../_images/sitetitle2.png

Advanced Usage

Shutting Down NuLog

Standard method

Please note that NuLog has implemented finalizers, so that shutting down NuLog is not necessary. Your log messages will be flushed, and NuLog will exit cleanly automatically, on application exit. However, if for any reason you want to shut NuLog down before application exit, the most standard way to do this is using the Shutdown method of the LogManager. You would do this if you are using the LogManager to manage your logging construction needs:

1
2
3
4
5
6
7
8
      public void DoStuff() {
          // ...

          LogManager.Shutdown();

          // ...
      }
  }

StandardLoggerFactory Finalizer

The standard logger factory implementation has a finalizer, which disposes the assets managed by the factory, namely, the IDispatcher assigned to it, when garbage collection deconstructs it.

Disposing the Dispatcher

It is important to dispose the dispatcher, so that the queued log events can be sent to their targets before application exit. Again, this isn’t necessary, as the finalizers will automatically do this for you on application exit.

Like the StandardLoggerFactory the StandardDispatcher also has a finalizer, which will dispose the dispatcher when disposed of by the garbage collector.

Meta Data Providers

Much like static meta data, dynamic meta data can be included in log events to be delivered to the targets. To do this, a IMetaDataProvider instance must be passed to the log manager when requesting a logger.

Custom Meta Data Provider

The IMetaDataProvider interface has a single method for providing meta data:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
    /// <summary>
    /// Defines the expected behavior of a meta data provider - namely, providing meta data.
    /// </summary>
    public interface IMetaDataProvider {

        /// <summary>
        /// Provide meta data for a log event.
        /// </summary>
        IDictionary<string, object> ProvideMetaData();
    }

There’s not any more to it than that. As an illustration, however, let’s take a look at an implementation that includes some request data for a MVC controller:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
    public class MyControllerMetaDataProvider : IMetaDataProvider {
        private readonly Controller myController;

        public MyControllerMetaDataProvider(Controller controller) {
            myController = controller;
        }

        public IDictionary<string, object> ProvideMetaData() {
            var request = myController.Request;
            return new Dictionary<string, object>
            {
                { "UserHostAddress", request.UserHostAddress },
                { "URL", request.Url }
            };
        }
    }
}

This meta data provider will include information specific to the request, for the given controller. Next, let’s take a look at how to use our new meta data provider.

Using Meta Data Providers

To use our custom meta data provider, we pass an instance of it to our log manager when requesting a logger:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
    public class MyMetaDataProviderController : Controller {
        private readonly ILogger myLogger;

        public MyMetaDataProviderController() {
            var myMetaDataProvider = new MyControllerMetaDataProvider(this);
            myLogger = LogManager.GetLogger(myMetaDataProvider);
        }

        public ActionResult Index() {
            myLogger.Log("Will include my custom, request specific meta data.", "index");
            return View();
        }
    }
}

Advanced Rule Routing

The ‘final’ and ‘strictInclude’ Flags

Complex routing can be achieved using the final and strictInclude flags:

  • final - When set to true, and if a log message matches the rule, no further rules will be processed. Rules are processed in consecutive order, as listed in the rule list.
  • strictInclude - By default, if any tag is matched in the include list, the rule is matched. By seting the StrictInclude flag, all tags (or tag patterns) listed in include must match for the rule to be considered a match.

Examples

final

Let’s say that you want to send messages with the “consoleonly” tag, only to console, but have a general, catch-all rule in place. In the following example, events with the consoleonly tag will be routed only to the console target, all others will only go to the file target:

1
2
3
4
5
6
7
8
9
      <rules>
          <rule
            include="consoleonly"
            targets="console"
            final="true" />
          <rule
            include="*"
            targets="file" />
      </rules>

strictInclude

We use the strictInclude flag to state that all tags/patterns in the “include” of the rule must be matched for the rule to match. This enables us to zero in on specific log events:

1
2
3
4
5
6
      <rules>
          <rule
            include="NuLogSnippets.*,index"
            strictInclude="true"
            targets="file" />
      </rules>

The above rule states that all log events with the index tag, and a tag starting with NuLogSnippets. are routed to the target named file. Note that the class that log events are logged from are automatically added as tags, for example: NuLogSnippets.Docs.MyMetaDataProviderController is added to the log events generated by the Index action, and any other calls to the logger, in that class.