Solracnapod
Solracnapod

Reputation: 863

Automatically log System.diagnostics.trace messages to an Nlog target

Say you have C# trace messages all over an application. Something like:

Trace.TraceInformation("Service Started"); 

How do you automatically log this to an nLog target without having to add code like the following to all the classes that have trace messages?

using NLog;
private static Logger logger = LogManager.GetCurrentClassLogger();

Is there a way to do this without including traces produced by the .NET Framework itself, which this article demonstrates how to do?

Upvotes: 14

Views: 10926

Answers (3)

Vinod Srivastav
Vinod Srivastav

Reputation: 4255

You can use nlog as <sharedListeners> in the App.config

<system.diagnostics>

    <sources>
      <source name="System" switchValue="All">
        <listeners>
          <add name="nlog" />
        </listeners>
      </source>
      <source name="MySystem" switchValue="All">
        <listeners>
          <add name="nlog" />
        </listeners>
      </source>
    </sources>
    
    <sharedListeners>
      <add name="nlog" type="NLog.NLogTraceListener, NLog" />
    </sharedListeners>

    <trace autoflush="true" indentsize="4">
      <listeners>
        <add name="nlog" />
        <remove name="Default" />
      </listeners>
    </trace>
    
</system.diagnostics>

Edit: using TraceSource

As Nlog comes with a TraceListener which can be used as shared listener, you can also add a custom soure MySystem as above you can get rid of LogManager.GetCurrentClassLogger(); and can use the build-in TraceSource itself as.

public class Person
{
//...
    var ts = new TraceSource("MySystem"); 
    //or ts = TraceSource(this.GetType().Name);
    ts.TraceInformation("This will go through nLog listener");

This will avoid you to reference nlog.dll in each/every project in solution and will minimize the dependency to a single main project where App.Config resides.

Here with TraceSource(this.GetType().Name) you will achieve what LogManager.GetCurrentClassLogger() will do for you. And for class Person you need to add the following in the App.Config :

<source name="Person" switchValue="All">
    <listeners>
      <add name="nlog" />
    </listeners>
</source>

In turn now you can switch on/off logging from a module without rebuilding the whole solution.

Upvotes: 1

wageoghe
wageoghe

Reputation: 27608

You can use NLog's NLogTraceListener.

For completeness, here is the System.Diagnostics configuration (from the link above) to specify the NLogTraceListener:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.diagnostics>
    <sources>
      <source name="System.Net" switchValue="All">
        <listeners>
          <add name="nlog" />
        </listeners>
      </source>
      <source name="System.Net.Sockets" switchValue="All">
        <listeners>
          <add name="nlog" />
        </listeners>
      </source>
    </sources>
    <sharedListeners>
      <add name="nlog" type="NLog.NLogTraceListener, NLog" />
    </sharedListeners>
  </system.diagnostics>
</configuration>

You also need to configure NLog to tell it how to write the information once it moves from the System.Diagnostics.Trace to NLog:

<nlog>
  <targets>
    <target name="console" type="ColoredConsole" layout="${longdate} ${windows-identity} ${message}" />
  </targets>

  <rules>
    <logger name="*" minlevel="Trace" writeTo="console" />
  </rules>
</nlog>

Upvotes: 7

fiat
fiat

Reputation: 15971

This works for cases where there isn't an explicit source.

  <system.diagnostics>
      <trace autoflush="true" indentsize="4">
        <listeners>
          <add name="MyNLogTraceListener" type="NLog.NLogTraceListener, NLog" />
          <remove name="Default" />
        </listeners>
      </trace>
  </system.diagnostics>

Upvotes: 10

Related Questions