I'm using log4net to log in XML format.
I'm using the following configuration:
<appender name="RollingLogFileAppenderError" type="log4net.Appender.RollingFileAppender, log4net">
<file type="log4net.Util.PatternString" value="App_Log\Service.Error.xml"/>
<staticLogFileName value="false"/>
<preserveLogFileNameExtension value="true"/>
<appendToFile value="true"/>
<rollingStyle value="Date"/>
<datePattern value=".yyyy-MM-dd"/>
<filter type="log4net.Filter.LevelMatchFilter">
<acceptOnMatch value="true"/>
<levelToMatch value="ERROR"/>
</filter>
<filter type="log4net.Filter.DenyAllFilter"/>
<layout name="StandardLayout" type="log4net.Layout.PatternLayout">
<header><?xml version="1.0" encoding="UTF-8"?><LogEntries></header>
<footer></LogEntries>
<conversionPattern value="<LogEntry date="%date" level="%level" logger="%logger" method="%aspnet-context{LogMethodName}">%message</LogEntry>%newline"/>
</layout>
</appender>
Now this works, except for the situations where I need to look at the latest log file. Then it's invalid an contains something like:
<?xml version="1.0" encoding="UTF-8"?>
<LogEntries>
<LogEntry>....</LogEntry>
With no footer, which naturally is invalid.
The files are collected to a central location, where we want to visualize information from the logs. But since some of the log files are invalid, it creates a bit of a problem.
Now I could pre-process the files before they are read into the visualization tool, but I would much rather have valid xml files.
Does anyone have a suggestion of how to handle this problem?
Edit:
Another solution could be to not log in XML, but for logging in for example JSON, which I understand also needs a root "element", the same problem seems to exist.
Your problem is that the footer is written when your application stops or starts with a new log file. Log4net (rollingfileappender) can't add the footer earlier because it will not remove it when adding a new entry. To overcome this you can make a xml appender which implements the SkelitonAppender or the RollingFileAppender which adds and removes footer when writing a new log entry.
Easier is to make your files smaller so you do need to look at the latest file.
Btw an easier way to do your conversion is by using the layout element in the configuration:
<layout type="XmlLayout" />
And make a XmlLayout class:
public class XmlLayout : XmlLayoutBase
{
protected override void FormatXml(XmlWriter writer, LoggingEvent loggingEvent)
{
writer.WriteStartElement("LogEntry");
writer.WriteStartElement("Message");
writer.WriteString(loggingEvent.RenderedMessage);
writer.WriteEndElement();
writer.WriteEndElement();
}
}