2

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?

urig
  • 16,016
  • 26
  • 115
  • 184

2 Answers2

3

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

stuartd
  • 70,509
  • 14
  • 132
  • 163
  • Thanks @stuartd. I'm not sure this is a "more direct" way though. OTOH maybe I can do something similar by calling loggingEvent.WriteRenderedMessage(writer). This way I'm only dependant on the loggingEvent. – urig Jun 09 '15 at 13:07
  • @urig except the logging event has no knowledge of the layout set on the appender.. – stuartd Jun 09 '15 at 13:11
  • 1
    Worked for me. OP: Since you are writing an appender (hopefully inheriting `AppenderSkeleton`, you can just access the `Layout` property. – Marcel Jul 17 '18 at 07:10
1

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();
    }
}
Marcel
  • 15,039
  • 20
  • 92
  • 150