Hello
In my company we are using an AsyncAppender for asynchronous logging
that we have implemented ourselves and we are quite happy with it. From
the start we had prepared a FixFields property on this appender so that
user can decide which fields has to be fixed by the appender before
passing it to nested appenders. The default value for this property is
Partial.
I recently try to use it so that most of the logging event formatting
is done in the logging thread rather than in the thread that generate
the log event. So I change the FixFields value to ThreadName and
discovered that it has an impact on the job performed by nested
appenders. For instance when I log an exception through a
ConsoleAppender nested in a AsyncAppender I have normally the following
result:
ERROR Exception raised
System.ApplicationException: FOO
à AsyncAppenderTest.Program.ThrowException() dans
C:\Dev\AsyncAppenderTest\AsyncAppenderTest\Program.cs:ligne 69
à AsyncAppenderTest.Program.Main(String[] args) dans
C:\Dev\AsyncAppenderTest\AsyncAppenderTest\Program.cs:ligne 40
Once I changed the FixFields to simply ThreadName I had:
ERROR Exception raised
As you can see the log of the exception has disappeared. This is so with
or without the %exception in the PatternLayout.
The problem is in the LoggingEvent class. It looks like you cannot
partially fix a LoggingEvent. Once you fix some fields using the Fix
property m_cacheUpdatable is set to false and when the LoggingEvent
reference is pass to the ConsoleAppender which call GetExceptionString
this method return an empty string because m_cacheUpdatable is false.
What is m_cacheUpdatable for exactly ? It looks like the intention is to
avoid the same field to be fixed several time but as all fields default
value in LoggingEventData is null and is not null anymore once fixed it
seems enough to avoid the multiple fixes situation. Couldn't be
LoggingEvent.m_cacheUpdatable simply removed ?
Thanks