Logging Threshold per Logger

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Logging Threshold per Logger

David Omer
I'm quite excited about NLog based on my preliminary research. It seems comprehensive enough to meed my needs with a simple interface and architecture. My question is about logging thresholds. I see that I can set the GlobalThreshold, but I need the ability to modify that threshold setting at the Logger level. Is it possible to set a logging threshold for a specific logger and if so, how?
Reply | Threaded
Open this post in threaded view
|

Re: Logging Threshold per Logger

Jarek Kowalski
Administrator
You need to create a separate rule for your logger. To make sure that no other rules are applied to this logger, make it "final" and put it at the beginning of the rule list. In the config file this would be something like this:

<rules>
    <logger name="Sooda.SQL" minlevel="Debug" writeTo="file" final="true" />
    <logger name="*" minlevel="Error" writeTo="file" />
</rules>

This sets the threshold for Sooda.SQL to Trace and "Error" for other loggers. To do it programmatically you need to create a LoggingConfiguration, add some targets to it using AddTarget() then add some LoggingRule objects to the LoggingRules collection. Once you have the logging configuration, just assign it to LogManager.Configuration property.

Sorry for such a short description, but I'm unable to write much more now.

Jarek
NLog Blog
Reply | Threaded
Open this post in threaded view
|

Re: Logging Threshold per Logger

David Omer
Thanks for the quick reply, but I'm still confused. If I implement the rules per your example, what impact does the GlobalThreshold have on the events that are written to the loggers. I understood that setting the level in the rule only specified where events will be logged with said LogLevel, IF the event's loglevel was >= the GlobalThreshold. Does the "minLevel" parameter override the GlobalThreshold parameter where as the "level" or "levels" parameters perform as I stated above?
Reply | Threaded
Open this post in threaded view
|

Re: Logging Threshold per Logger

Jarek Kowalski
Administrator
No events whose levels are below GlobalThreshold are logged regardless of any rules.

Jarek
NLog Blog
Reply | Threaded
Open this post in threaded view
|

Re: Logging Threshold per Logger

clab
In reply to this post by Jarek Kowalski

I need to create a separate rule for my loggers, one for normal log details, another only for Exception logs. There are my targets:
FileTarget target1 = new FileTarget();
..
target1.Name = "file";
NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target1, LogLevel.Debug);

FileTarget target2 = new FileTarget();
..
target2.Name = "exceptionfile";
NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target2, LogLevel.Debug);


I must create the same situation as this config file:
..
rules
logger name="*" minLevel="Info" writeTo="file"
logger name="ExceptionLogger" writeTo="exceptionfile"
/rules>
..


This is my code for apply these rules:
NLog.Config.LoggingConfiguration config = new NLog.Config.LoggingConfiguration();
config.AddTarget("file", target1);
config.AddTarget("exceptionfile", target2);

NLog.Config.LoggingRule ruleA = new NLog.Config.LoggingRule("*", LogLevel.Info, target1);
NLog.Config.LoggingRule ruleB = new NLog.Config.LoggingRule("ExceptionLogger", target2);

NLog.Config.LoggingRuleCollection collection = new NLog.Config.LoggingRuleCollection();
collection.Add(ruleA);
collection.Add(ruleB);


The final result is that all messages are write into Target2, also normal messages (and this is not that I want).

Where I wrong?

Thanks Jarek.

Claudio
Reply | Threaded
Open this post in threaded view
|

Re: Logging Threshold per Logger

Jarek Kowalski
Administrator
You need to make the first rule final, so that when it matches, no further rules are processed. In addition, you should swap the order of rules so that the first one added is ExceptionLogger. Also, you should add the rules to config.LoggingRules and not to your own collection.

The code should be more or less like this:

NLog.Config.LoggingConfiguration config = new NLog.Config.LoggingConfiguration();
config.AddTarget("file", target1);
config.AddTarget("exceptionfile", target2);

NLog.Config.LoggingRule ruleA = new NLog.Config.LoggingRule("*", LogLevel.Info, target1);
NLog.Config.LoggingRule ruleB = new NLog.Config.LoggingRule("ExceptionLogger", target2);

// ignore any further rules as soon as this one matches
ruleB.Final = true;

// the rules are processed in the order they are added to LoggingRules
config.LoggingRules.Add(ruleB);
config.LoggingRules.Add(ruleA);

LogManager.Configuration = config; // this makes the newly prepared configuration active
NLog Blog
Reply | Threaded
Open this post in threaded view
|

Re: Logging Threshold per Logger

clab
I'm sorry, but the problem always exist using NLog ver 0.9.5.0.
I tried to swap order to attach rules, and result is always log into TestNLog_..._Exception.log.
Another thing : activating newly prepared configuration, the log will not be created; if I comment this row, the log (one, not two) will be created.

This is my demo code, it is simple, copy and paste into VS.NET and run it, please.

Thank's you again.

Claudio

---------------------------------------------------
using System;

#region NLog using
  using NLog;
  using NLog.Targets;
  using NLog.Win32.Targets;
#endregion

class TestNLog
{

  #region NLog logger definitions
  /// <summary>
  /// Log class definition
  /// </summary>
  static Logger logger = LogManager.GetCurrentClassLogger();

  /// <summary>
  /// Exception Log class definition
  /// </summary>
  static Logger loggerException = LogManager.GetLogger("ExceptionLogger");
  #endregion

  /// <summary>
  /// Set programmatically NLog target for logging with Reporting Services.
  /// I can't use typically configuration file for NLog (unfortunately)
  /// because this class must be called by Reporting Services layer,
  /// therefore I had very difficults to setting exact location of NLog config file.
  /// </summary>
  static void Main()
  {
    FileTarget target1 = new FileTarget();
    target1.Layout = "${longdate} ${threadid} ${level:uppercase=true} ${message}";
    target1.FileName = "C:\\LOG\\TestNLog_${date:format=yyyy-MM-dd}.log";
    target1.KeepFileOpen = false;
    target1.Encoding = "iso-8859-2";
    target1.Name = "file";
    NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target1, LogLevel.Debug);

    FileTarget target2 = new FileTarget();
    target2.Layout = "${longdate} ${threadid} EXCEPTION ${message}  ${exception:format=tostring}";
    target2.FileName = "C:\\LOG\\TestNLog_${date:format=yyyy-MM-dd}_Exception.log";
    target2.KeepFileOpen = false;
    target2.Encoding = "iso-8859-2";
    target2.Name = "exceptionfile";
    NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target2, LogLevel.Debug);

    NLog.Config.LoggingConfiguration config = new NLog.Config.LoggingConfiguration();
    config.AddTarget("file", target1);
    config.AddTarget("exceptionfile", target2);

    NLog.Config.LoggingRule ruleA = new NLog.Config.LoggingRule("*", LogLevel.Info, target1);
    NLog.Config.LoggingRule ruleB = new NLog.Config.LoggingRule("ExceptionLogger", target2);

    // ignore any further rules as soon as this one matches
    ruleB.Final = true;

    // the rules are processed in the order they are added to LoggingRules
    config.LoggingRules.Add(ruleA);
    config.LoggingRules.Add(ruleB);

    //LogManager.Configuration = config; // this makes the newly prepared configuration active

    logger.Debug("This is DEBUG message.");
    logger.Info("This is INFO message.");
    logger.Warn("This is WARNING message.");
    logger.Error("This is ERROR message.");

    try
    {
      throw new System.ApplicationException("This is my exception!");
    }
    catch (Exception ex)
    {
      loggerException.ErrorException(ex.Message, ex);
    }
  }
}