CommonLoggingTraceListener to Log4Net FormatException

03 February 2015

Recently, I redirected Thinktecture IdentityServer diagnostics tracing using Common.Logging to Log4Net and go this error.

ERROR Diagnostics.w3wp.exe (null) - <log4net.Error>Exception rendering object type [Common.Logging.Factory.AbstractLogger+StringFormatFormattedMessage]<stackTrace>System.FormatException: Input string was not in a correct format.
   at System.Text.StringBuilder.AppendFormat(IFormatProvider provider, String format, Object[] args)
   at System.String.Format(IFormatProvider provider, String format, Object[] args)
   at Common.Logging.Factory.AbstractLogger.StringFormatFormattedMessage.ToString()
   at log4net.ObjectRenderer.DefaultRenderer.RenderObject(RendererMap rendererMap, Object obj, TextWriter writer)
   at log4net.ObjectRenderer.RendererMap.FindAndRender(Object obj, TextWriter writer)</stackTrace></log4net.Error>

I found it was due to the fact that some Json was being logged. When you perform a string.format with curly braces you need to escape them when not placeholders. e.g. string.format("{{foo:{0}}}","Test").

My fix

I extended CommonLoggingTraceListener and implemented an override for log.

protected override void Log(TraceEventType eventType, string source, int id, string format, params object[] args)
{
    if (args != null && args.Length==0)  
    {
        format = format
            .Replace("{", "{{")
            .Replace("}", "}}");
    }
    base.Log(eventType, source, id, format, args);
}
Common.Logging Logging