I have a single-threaded .NET Winforms application. I am using a static NLog logger to log errors using this syntax:

MyLogger.Log.Error("Error occurred...");

In accordance with my one NLog.config-defined target and one NLog.config-defined rule, that log-error output always is written to a file called "errors.txt". Sometimes I want an error to be written to "errors2.txt" instead. How would I do that without creating another static logger instance?

1 Answers

1
Julian On Best Solutions

You could use filters in the config or pass the filename to the logger call.

Note: These examples are using .WithProperty (on the NLog Logger), introduced in NLog 4.6.3

Filters

Use filters in the logger rules, we use the LogFinal so we need only the rules once (not needed for the 2nd logger rule)

See Filtering log messages on the NLog wiki

<rules>
  <logger name="*" writeTo="file-error1">
    <filters defaultAction='LogFinal'>
      <when condition="${event-properties:target} == 'error2'" action="Ignore" />
    </filters>
  </logger> 
  <logger name="*" writeTo="file-error2">
  </logger> 
</rules>

Logger call:

MyLogger.Log.Error("Error occurred..."); // writes to file-error1 target
MyLogger.Log.WithProperty("target", "error2").Error("Error occurred..."); // writes to file-error2 target

Pass file name

Pass the file name in as property. Maybe you could set a default property in the static Log method.

See also Event properties documentation

<targets>
    <target name="file" xsi:type="File"
        ....
        fileName="${basedir}/logs/{event-properties:filename}" 
        ...  />
</targets>

Logger call:

MyLogger.Log.WithProperty("filename", "error1.txt").Error("Error occurred...");
MyLogger.Log.WithProperty("filename", "error2.txt").Error("Error occurred...");