Log4net: Why is Pattern Layout ignored in RenderedMessage?

1k views Asked by At

I'm debugging a custom log4net Appender that I've written. My setup uses this standard PatternLayout in my config file:

  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
  </layout

In my Append() method implementation if I call RenderLoggingEvent() it returns a properly formatted message. The loggingEvent's Renderedmessage, however, only contains the %message bit.

RenderLoggingEvent() returns:

"2015-06-09 14:09:37,382 [Main Thread] INFO MyConsole.Program [(null)] - Thread test\r\n"

loggingEvent.RenderedMessage contains:

"Thread test"

Is this how RenderedMessage is supposed to work?

I need to render the message outside of the Appender so I'd rather not use its RenderLoggingEvent() method. Is there a more direct way to get the rendered message from the LoggingEvent instance?

2

There are 2 answers

3
stuartd On

You say you need to 'render the message outside of the Appender', but the Layout is associated with the appender.

Assuming you can work around this and access the layout somehow, then you can call the Format method on the layout:

PatternLayout layout = … ;
string result;
using (StringWriter writer = new StringWriter())
{
     layout.Format(writer, loggingEvent);
     result = writer.ToString();
}

Test output:

2015-06-09 14:06:43,357 [14] ERROR test [NDC] - Test Message

0
Marcel On

When you are extending the AppenderSkeleton to write your custom Appender, you already have the layout as a property at hand. You can then write a method in your Appender:

Here's my code (in TextBoxAppender.cs), inheriting AppenderSkeleton:

private string GetLayoutedMessage(LoggingEvent loggingEvent) {
    using (StringWriter writer = new StringWriter())
    {
        Layout.Format(writer, loggingEvent);
        return writer.ToString();
    }
}