bavaza
bavaza

Reputation: 11037

Log only to a specific target at runtime

I am using NLog with two targets:

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  <targets async="true">
    <target name="logfile" xsi:type="File" fileName="my.log"/>
    <target name="console" xsi:type="Console"/>
  </targets>

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

Is it possible to log a message only to the "logfile" target, without having the message written to the "console" target as well?

EDIT

To clarify: I want to direct messages from the same class to different loggers at run time (w/o having to change the XML). Something like:

class Program
{
    static Logger _logger = LogManager.GetCurrentClassLogger();

    static void Main(string[] args)
    {
        // Note - _logger.InfoToTarget() does not really exist
        _logger.InfoToTarget("logfile", "This is my very detailed message, possibly with object dumps");
        _logger.InfoToTarget("console", "Short message");
    }
}

I'm aware that this couples my code with the NLlog.config file.

Upvotes: 3

Views: 3984

Answers (3)

MegaMark
MegaMark

Reputation: 610

One way to accomplish the functionality you are looking for is to name your logger

_logger = LogManager.GetLogger("MyConsoleLogger")
_logger.Info("This will log to the console...");
_logger = LogManager.GetLogger("MyFileLogger")
_logger.Trace("This will log to a file...");

rather than using

LogManager.GetCurrentClassLogger().              

In your config file you could then list in the rules

<rules>
<logger name="MyFileLogger" minlevel="Trace" writeTo="logfile"/>
<logger name="MyConsoleLogger" minlevel="Info" writeTo="console"/>
</rules>

This is by far not the most pretty solution to look at, but it does give you the functionality that you are looking for.

Upvotes: 3

JNYRanger
JNYRanger

Reputation: 7097

Absolutely, however I am assuming you mean at release you no longer wish to log to the console. You can do this very easily by removing or commenting out the listener that writes to the console target. Now it will only write to the logfile target.

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <targets async="true">
       <target name="logfile" xsi:type="File" fileName="my.log"/>
       <target name="console" xsi:type="Console"/>
    </targets>

    <rules>
       <logger name="*" minlevel="Trace" writeTo="logfile"/>
       <!--<logger name="*" minlevel="Info" writeTo="console"/>-->
    </rules>
</nlog>

The rule that writes to the console is now deactivated, but the log file is active. If this is during release you probably want to change your rule to not process your trace logging as the min level for the log file since it will slow down your app with excessive IO. I have asked this question in the past and it appears that best practice is to do this via the XML configuration files. (Logging in Release Build of Application (C#))

Upvotes: -1

p07r0457
p07r0457

Reputation: 236

There are a few ways to do this, and the correct method depends on your situation.

Keep in mind that you typically want to avoid having your app know too much about the inner-workings of logging. If possible, it's best to configure nlog to decide where things should get logged.

Is there a specific namespace that should not be logged to console? That's easy to configure. Also, you can use the "When" filter (https://github.com/nlog/nlog/wiki/When-filter) or conditions (https://github.com/nlog/nlog/wiki/Conditions)

It may also be best to have multiple logger instances, so you can call the one that is appropriate for each situation (logger per class) (Why do loggers recommend using a logger per class?).

Upvotes: 1

Related Questions