views:

222

answers:

2

I want to be able to log the class file and line number in my log file so I am using the following config...

<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
  <!--etc-->
   <layout type="log4net.Layout.PatternLayout">
       <conversionPattern value="%date [%thread] %-5level (%file:%line) %logger => %message%newline" />
  </layout>
</appender>

However the %file attribute is making my log file entries waaaay too long to read comfortably....

2009-08-07 16:41:55,271 [7] INFO  (O:\mystream\aevpallsrv\DotNet\com.mycompany.au\myapp\Myappp\Controller.cs:75) MyApp.Controller => Controller.EnqueueWorkerThreads() - START

Is there a way to show just the class file ('Controller.cs') instead of the full path to the file also???

Michael

+2  A: 

Out of the box, PatternLayout supports only the %file token. What you can do is subclass PatternLayout and add your own pattern, say %filename, and for this token only output the name of the file.

Peter Lillevold
Thanks Peter, I really didn't want to mess around with subclassing in Log4Net but I suppose I will give it a go. While I'm there, I might try and customise the stoopid file naming options of the RollingLogFileAppender.
Michael Dausmann
Go for it. Adding your own patterns to Patternlayout is actually quite easy... let us all know how it goes.
Peter Lillevold
A: 

Although you're asking about the file name, I believe you can use %type to get the fully qualified type name (a.b.className). If you just want the class name, use %type{1}

Note that any method that generates caller information (%file and %type) have a performance cost associated with them.

As an aside, you can bypass the performance hit by naming the Logger using the Type name.

namespace MyNamespace
{     
    public class Foo
    {
        private static ILog log = LogManager.GetLogger(typeof(Foo));
    }
}

Your conversion pattern would look like:

"%date [%thread] %-5level %logger %message"

Where your logger would be "MyNameSpace.Foo". Likewise, if you only want the class name, use "%logger{1}, which will resolve as "Foo".

One of the best advantages to this approach is that you can leverage log4net's hierarchical repository system to adjust logging levels per type:

<!-- all classes in MyNamespace are warn -->
<logger name="MyNamespace">
     <level value="WARN" />
</logger>

<!-- only Foo is in debug -->
<logger name="MyNamespace.Foo">
    <level value="DEBUG" />
</logger>
bryanbcook
I haven't tried, but I wonder what %file{1} would work that same way that %type{1} would?
bryanbcook
Thanks for that Bryan. I am using the type name as the logger name and this works ok. I found that the class and line number information didn't work with my 'Release' configuration files anyway (I didn't release the pdb file) so I am skipping these entirely for my production release.
Michael Dausmann