I agree with implementing a custom PatternLayoutConverter. Here a couple of examples:
This one adds the System.Diagnostics.Trace.CorrelationManager.ActivityId to the output:
public class ActivityIdLayoutConverter : PatternLayoutConverter
{
protected override void Convert(System.IO.TextWriter writer, LoggingEvent loggingEvent)
{
writer.Write(Trace.CorrelationManager.ActivityId.ToString());
}
}
This one is parameterized (it can be configured with a key which can be used to retrieve a value from a dictionary - similar to the GDC or MDC):
class KeyLookupPatternConverter : PatternLayoutConverter
{
protected override void Convert(System.IO.TextWriter writer, LoggingEvent loggingEvent)
{
string setting;
//Option is the key name specified in the config file
if (SomeDictionaryWithYourValues.TryGetValue(Option, out setting))
{
writer.Write(setting);
}
}
}
Here is a link to a question that I asked about creating a PatternLayoutConverter that can take a key value. It shows how to do it in log4net and NLog as well as how to configure.
Alternatively, you could wrap a log4net logger and in your wrapper's "Log" method, you could modify the input message or your could put your custom values in the GlobalDiagnosticContext.Properties or ThreadDiagnosticContext.Properties and then reference the values in the output via the normal properties token method.