Situation: I want to show the method and line number for the code that logs a message. The problem is that I have an intermediate class which calls into the log4net logger. Unfortunately, due to existing architectural issues, I can't do away with this intermediate class. The result is that I always see the method and line number as being in the intermediate class. Not what I want.
So I tried to create a custom PatternLayoutConverter, as per this question:
I am also programmatically configuring log4net since, again for architectural reasons, using an XML config file is not feasible (I also find it ridiculous that the preferred and only documented way of configuring log4net is through a stupid XML file, but that's a topic for another discussion). So I followed this thread.
Everything works fine except that my custom converter is never called. Here is the code for the custom converter:
public class TVPatternLayout : PatternLayout {
public TVPatternLayout() {
this.AddConverter("logsite", typeof(TVPatternLayoutConverter));
}
}
public class TVPatternLayoutConverter : PatternLayoutConverter {
protected override void Convert(TextWriter writer, LoggingEvent loggingEvent) {
StackTrace st = new StackTrace();
int idx = 1;
while(st.GetFrame(idx).GetMethod().DeclaringType.Assembly == typeof(LogManager).Assembly)
idx++;
writer.Write(String.Format("{0}.{1} (line {2})", st.GetFrame(idx).GetMethod().DeclaringType.Name, st.GetFrame(idx).GetMethod().Name,
st.GetFrame(idx).GetFileLineNumber()));
}
}
And here is the code where I configure the logger:
Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository();
hierarchy.Configured = false;
RollingFileAppender appender = new RollingFileAppender();
appender.Name = loggerName;
appender.File = realPath;
appender.AppendToFile = true;
appender.MaximumFileSize = "8000";
appender.MaxSizeRollBackups = 2;
TVPatternLayout patternLayout = new TVPatternLayout();
patternLayout.ConversionPattern = logFormat; // includes %logsite, my custom option
appender.Layout = patternLayout;
appender.ActivateOptions();
hierarchy.Root.AddAppender(appender);
hierarchy.Root.Level = Level.All;
hierarchy.Configured = true;