-
-
Notifications
You must be signed in to change notification settings - Fork 7
Logging
Beginning in release 1.3.0, we use an abstract logging interface throught the Rx Comms library. This means that we have no hard dependency on any logging framework.
The abstract interfaces are defined in TA.Utils.Diagnostics
and are:
-
ILog
- defines a logging service for creating loggers. -
IFluentLogBuilder
- defines a fluent interface for building semantic log entries.
If you want RxComms to produce log output, you must inject a logging service. Otherwise, no logging will happen.
The log service is injected into the ChannelFactory
class and this only needs to be done once.
var factory = new ChannelFactory(logService);
A logging service suitable for injection can be found in TA.Utils.Logging.NLog
, which is a separate [NuGet][nuget] package.
The service uses NLog as its logging back end, and NLog should be configured
using the NLog.config
file.
The abstract logging interfaces support semantic (or structured) logging. One can add relevant information to log entries in the form of properties. These can be added individually to each new log entry via the fluent log even builder, or as Ambient Properties which are attached to all log entries created by that instance of the logging service.
Attaching ambient properties is done like so:
var logService = new LogService()
.WithAmbientProperty("sessionId", sessionId)
.WithAmbientProperty("user", currentUser);
Then, the log service can be used to generate log entries, which can themselves have properties added:
logService.Debug()
.Message("Starting program")
.Property("Version", productVersion)
.Property("GitCommitId", GitVersion.GitCommitSha)
.Write();
Another way to add properties is within the message template:
logService.Debug()
.Message("Start time {time}", DateTime.UtcNow)
.Write();
Dont't forget to .Write()
at the end!
You can also add things like exceptions, and RxComms provides an extension method for adding transactions:
catch (TransactionException ex)
{
logService.Error()
.Message("It's all gone a bit wrong)
.Exception(ex)
.Transaction(transaction)
.Write();
Good question. If you've only ever rendered log output to the console or a text file, then you might be missing the point of structured logging. Try rendering a JSON file, or to a structured logging engine such as Log4View or Seq. Here's an example from our Seq server:
Now that's what we call rich logging! Exceptions with full stack traces; ambient properties such as the process ID and thread ID; plus other contextual properties such as the transaction that was being processed when the error happened. That is semantic logging.