NLog Targets and Rules

3 minutes to read read

NLog Targets

The beauty of NLog is the Targets ‘system’ that is extentible and easy to use. Also the most amazing thing is the default target list as provided by NLog and the ease with which custom targets can be written. The Targets provided by the Nlog  by default are more then sufficient for most needs.

There can be multiple targets that can be linked to multiple Rules.

Well, the currently provided targets as provided by NLog can be accessed here. Some of the most useful targets with sample configuration is as below:

  1. ColoredConsole: This target adds a ‘beautiful’ Colored logs on the console. Well from the name it applies for Console Applications only.
    <targets  async="true">
       <target name="ConsoleTarget"  xsi:type="ColoredConsole"  layout="${longdate}, ${level}, ${message}"  useDefaultRowHighlightingRules="true"/>
    </targets>
  2. File Target: The file target as form the names writes the log to any file. Also, the location of the file could be on the network path as well.
        <targets  async="true">
          <target name="ConsoleTarget"  xsi:type="ColoredConsole"  layout="${longdate}, ${level}, ${message}"  useDefaultRowHighlightingRules="true"/>
          <target name="fileTarget"  xsi:type="File"  layout="${longdate}, ${level}, ${message}"               fileName="c:\temp\dummyLog_${longdate}.txt" />
          <target name="networkFilePath"  xsi:type="File"  layout="${longdate}, ${level}, ${message}"               fileName="\\127.0.0.1\Shared\temp\dummyLog_${machinename}.txt" />
        </targets>

    There are two targets as defined above, one is normal file in local system and the other one is on network path. The archival options availabel for Files can be seen here
    There is also an possiblity to add more advanced options to control file parameters. An example code is given below as:

        <targets  async="true">
          <target name="adavancedFileTarget"  
                  xsi:type="File"  
                  layout="${longdate}, ${level}, ${message}"               
                  fileName="c:\temp\log_${level}_${longdate}.txt"
                  header="${headerLayout}"
                  footer="${headerLayout}"
                  archiveAboveSize="1024000000"
                  createDirs="true" />
        </targets>
  3. Debug Target: As the name suggests it writes to the Log sink for the attached debugger  (if any :))
        <targets  async="true">
          <target name="debugTarget"  xsi:type="Debugger" layout="${longdate}, ${level}, ${message}" />
        </targets>
  4. Trace Target:  This also as prev, send the messages to system.Diagnoistics.Trace Listener. This can be useful, if there are any existing trace listeners, and nlog is to be configured to integrate with them.
        <targets  async="true">
          <target name="traceTarget"  xsi:type="Trace" layout="${longdate}, ${level}, ${message}" />
        </targets>

So the complete file looks like this

 <targets  async="true">
      <target name="ConsoleTarget"  xsi:type="ColoredConsole"  layout="${longdate}, ${level}, ${message}"  useDefaultRowHighlightingRules="true"/>
      <target name="fileTarget"  xsi:type="File"  layout="${longdate}, ${level}, ${message}"               fileName="c:\temp\dummyLog_${longdate}.txt" />
      <target name="networkFilePath"  xsi:type="File"  layout="${longdate}, ${level}, ${message}"               fileName="\\127.0.0.1\Shared\temp\dummyLog_${machinename}.txt" />
      <target name="adavancedFileTarget"
              xsi:type="File"
              layout="${longdate}, ${level}, ${message}"
              fileName="c:\temp\log_${level}_${longdate}.txt"
              header="${headerLayout}"
              footer="${headerLayout}"
              archiveAboveSize="1024000000"
              createDirs="true" />
      <target name="debugTarget"  xsi:type="Debugger" layout="${longdate}, ${level}, ${message}" />
      <target name="traceTarget"  xsi:type="Trace" layout="${longdate}, ${level}, ${message}" />
    </targets>

I shall try to explain a few where i found some trouble..

  1. Database: Here I faced a trouble because of the user authorization issues. In my dummy app, the call to db was done from service user. But nlog calls the user directly, which could not be allowed due to security issues. This was resolved by using User Mappings on a more fine grained level.
  2. EventLog: Very useful target, but you can definitely spend a few hours without any actual event log in Windows Event Viewer. There is no entry in Windows Event Log. The reason is that by design all the event sources willing to write to this, needs to be registered in registry. For this reason, you need to run your application once as admin. Then it should resoive.
  3. LogReceiverService: Here i faced some trouble with sending the additional data and deserializing it. The thing is that NLog sends the strings in two sets of lists. Dont remember actual name, plz ping if you face issue.

There are other plenty of targets at disposal from both NLog and 3rd party vendors that can be used from above Link.

If you want to further extend and write your own custom target, please follow blog for a article on that shortly.

Nlog Rules

NLog Rules are the heart of NLog, which defines the routing for the Log. The details are self explanatory. Please check the following code. Incase of any query please post in comments section.

<rules>
      <!--Write to debug only-->
      <logger name="*" writeTo="debugTarget" />
      <!--Write To all-->
      <logger name="*" writeTo="ConsoleTarget,fileTarget,adavancedFileTarget,debugTarget,traceTarget" />
      <!--Write all errors with warning-->
      <logger name="*" writeTo="adavancedFileTarget,ConsoleTarget" minlevel="Warning"  />
      <!--Write custom log levels-->
      <logger name="*" writeTo="fileTarget,ConsoleTarget,debugTarget" levels="Fatal,Error,Warn,Debug"  />
      <!--Wrtie from custom Logger-->
      <logger name="SocketLogger" writeTo="traceTarget" />
    </rules>

The complete logging file can be checked at: GitHub

2 comments

  1. Your NLog rules show a wildcard in every case – which means every log entry is going to go to *all* of the targets – right? What if you to have one named target that gets some messages and a wildcard for everything else? There doesn’t seem to be a way to specify ‘all but …”

    1. the “*” in the rules indicate the name of the logger which ‘can’ be used as an filter. By default it would be fully qualified name of the class something like namespace.sub-namespace.class. And this wildcard signifies if you want to log inputs from any specific filter to particular targets.

      Yes – it will log all entries to ‘defined’ targets in writeTo
      We face a similar situation where we needed to log entries from few specific classes to separate files (PII) the way we handled is that we didnt used * in rules, but something like below configuration

      logger name="XYZ.com.*" writeTo="debugTarget"

      logger name="secured.x.*" writeTo="ConsoleTarget,fileTarget,adavancedFileTarget,debugTarget,traceTarget"

      we changed the logger object to use secured.x as prefix when creating logger from those objects.

Leave a Reply

Your email address will not be published.