28
votes

I am using log4net DebugAppender (or TraceAppender). I have configured the appender like this:

<appender name="DebugAppender" type="log4net.Appender.DebugAppender">
    <immediateFlush value="true" />
        <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%level %message%newline" />
    </layout>
</appender>

Loggers in the code are declared in the usual per-class manner:

private static readonly ILog Log = 
    LogManager.GetLogger(typeof(TradingApiRouteCollectionExtensions));

Output in the Output windows looks like this:

Acme.Common.Configuration.TradingApiRouteCollectionExtensions: DEBUG Registering route prefix 'session' for service Acme.Session.SessionService Acme.Common.Configuration.TradingApiRouteCollectionExtensions: DEBUG Web methods found for type Acme.Session.SessionService: Acme.Common.Configuration.TradingApiRouteCollectionExtensions: DEBUG session/

Notice how every line starts with the logger type name. I want to suppress this as I didn't ask for it in the configuration and I don't want it. I can't see any obvious way to do this. Is it possible?

6

6 Answers

14
votes

You need to create your own appender. The one you are using does the following:

System.Diagnostics.Debug.Write(RenderLoggingEvent(loggingEvent), loggingEvent.LoggerName);
if (!this.m_immediateFlush)
    return;
System.Diagnostics.Debug.Flush();

Therefore you always end up with the class (logger) name in the output window. You can derive from the log4net Debug appender and override the Append method.

10
votes

Alternatively, you can start your layout conversion pattern with %newline. From my config:

    <appender name="DebuggerAppender" type="log4net.Appender.DebugAppender">
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%newline%file (%line): %level: %message%newline"/>
        </layout>
    </appender>

Pros: it's quicker than creating your own appender

Cons: it shows you log on 2 lines.

Note how the %file (%line) at the beginning of the line is a format interpreted by Visual Studio. It allows you to click on the log message in the output window and be taken straight to the the code that generated it.

4
votes

If you read the TraceAppender source code, you'll find actually the logger name is wrote as the default "category" name of the trace. So if you set this value already, the logger name will not be displayed in the output.

So with the config below:

<appender name="TraceAppender" type="log4net.Appender.TraceAppender">
  <category value="" />
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%date [%thread] %level - %message%newline%exception" />
  </layout>
</appender>

The output will be:

: 2017-02-27 22:53:26,335 [6] INFO - Task Ended

But you may find that every line starts with ":", which is ugly. So my config for category is:

...
<category value="LOG" />
...

And the output is:

LOG: 2017-02-27 22:53:26,335 [6] INFO - Task Ended

NOTE: DebugAppender does not provide the way to overwrite category. Only TraceAppender works.

2
votes

note that as of v2.0.8, you can turn off the output of the category name:

https://logging.apache.org/log4net/release/release-notes.html

var debugger = new DebugAppender();
debugger.Category = null;
2
votes

With the modern log4net it's possible to do this:

<appender name="DebugAppender" type="log4net.Appender.DebugAppender" >

    <!-- Add the <category> tag as below, this will remove %logger prefix in the output -->
    <category type="log4net.Layout.PatternLayout">
        <conversionPattern value="" />
    </category>

    <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="...whatever normal pattern you need there..." />
    </layout>
</appender>

The "category" property of DebugAppender have a default value of new PatternLayout("%logger"), and log4net uses the formatted result of it as the category parameter of Debug.Write(string, string). Not sure why they did it, but anyway the config above lets log4net know that category is not needed, and it starts using Debug.Write(string) overload, i.e. the one without the category stuff.

1
votes

My edit to the answer got rejected so providing additional useful info separately. Here is what a complete implementation would look like:

public class MyDebugAppender : log4net.Appender.DebugAppender
{
    protected override void Append(LoggingEvent loggingEvent)
    {
        System.Diagnostics.Debug.Write(RenderLoggingEvent(loggingEvent));
        if (ImmediateFlush)
        {
            System.Diagnostics.Debug.Flush();
        }
    }
}

m_immediateFlush is inaccessible in the derived class so you need to use the ImmediateFlush property.

Also, note that if using a log.config file you will need to specify that your Appender is provided in a new assembly. (Courtesy of this SO answer.)

<appender name="AppenderRef" type="MyNamespace.MyDebugAppender, MyAppenderAssembly">