March 9, 2017

Log4net - Add the stacktrace in the logs

The log4net version included in Sitecore doesn't contains the stacktrace. That mean that you cannot use %stacktrace or %stacktracedetail in the conversionsPattern.

As a workaround, you can override the appender.
First create the following class:
public class SitecoreLogFileWithStackAppender : SitecoreLogFileAppender
{
    protected override void Append(LoggingEvent loggingEvent)
    {
        var msg = loggingEvent.MessageObject as string;
        if (msg != null)
        {
            var prop = loggingEvent.GetType().GetField("m_data", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
            var mData = (LoggingEventData)prop.GetValue(loggingEvent);
            mData.Message = $"{msg}{Environment.NewLine}{Environment.StackTrace}";
            prop.SetValue(loggingEvent, mData);
        }

        base.Append(loggingEvent);
    }
}
Now you are able to configure the log4net appender like this:
<appender name="StackFileAppender" type="MyNamespace.SitecoreLogFileWithStackAppender, MyDll">
  <file value="$(dataFolder)/logs/log.Stacktraces.{date}.txt" />
  <appendToFile value="true" />
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%5t %d{yyyy-MM-dd HH:mm:ss.fff} %-5p %c - %m%n%n" />
  </layout>
</appender>
For my project I have choose to log all the errors, and all the messages who begin by [SD] in a separated fil with the stacktrace. The config is the following:
<appender name="StackFileAppender" type="MyNamespace.SitecoreLogFileWithStackAppender, MyDll">
  <file value="$(dataFolder)/logs/log.Stacktraces.{date}.txt" />
  <filter type="log4net.Filter.StringMatchFilter">
    <stringToMatch value="[SD]"></stringToMatch>
  </filter>
  <filter type="log4net.Filter.DenyAllFilter" />
  <appendToFile value="true" />
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%5t %d{yyyy-MM-dd HH:mm:ss.fff} %-5p %c - %m%n%n" />
  </layout>
</appender>

No comments:

Post a Comment