Logging - rebus-org/Rebus GitHub Wiki

Logging in Rebus can be key to understand what is going on and to diagnose problems. Therefore, it is probably a good idea to have some kind of strategy around this, ensuring that logs are properly monitored.

You will most likely already have a way you prefer to log your things, probably using Serilog, NLog, or another .NET logging library. Only thing left then is to configure Rebus to pipe its internal logs the same way, so that you can have Rebus' work and your work interleaved in the output, allowing you to understand everything that is happening in your applications.

Configuring it

As mentioned in the description of the Configuration API, logging must be configured as the first thing. This is to ensure that logging is properly set up for the other configurers in case they feel like logging.

A couple of logging options are included in the box, including logging to the console and via System.Diagnostics.Trace. They can be configured like so:

Configure.With(...)
         .Logging(l => l.Console())
         // etc

in order to set up plain and unsexy console output logging, or

Configure.With(...)
         .Logging(l => l.ColoredConsole())
         // etc

to add some colors to the console logging. System.Diagnostics.Trace logging can be set up with

Configure.With(...)
         .Logging(l => l.Trace())
         // etc

whereas logging can be disabled alltogether with

Configure.With(...)
         .Logging(l => l.None())
         // etc

As default, logging will be colored console logging.

Rebus can use e.g. Serilog as well if you include the Rebus.Serilog package. Then, you can go ahead and do your usual Serilog configuration, and then you can Rebus-enable it by doing it like this:

// the usual logger stuff here
var logger = new LoggerConfiguration()
    .(...)
    .CreateLogger();

// might even make it global default
Log.Logger = logger;

// make Rebus use it too
Configure.With(...)
         .Logging(l => l.Serilog(logger))
         // etc

Logging in your code

Logging with Rebus is built around that principle that

  • you log your things the way you're used to - Rebus does not want to interfere with that
  • Rebus most likely has a package that can pipe all of Rebus' logs the same way

This means that you will not end up depending on anything Rebus anywhere that does not need to do messaging.

Logging from Rebus extensions

If you are building an extension to Rebus, you are most likely hooking it in as a decorator of something. In that case, you have access to the same IRebusLoggerFactory as the other Rebus components, which you can retrieve from the IResolutionContext handed to you during instantiation.

For example, consider this configuration extension that provides a UseMsmq extension method on the transport configurer:

public static class MsmqTransportConfigurationExtensions
{
    public static void UseMsmq(this StandardConfigurer<ITransport> configurer, string inputQueueName)
    {
        configurer.Register(c =>
        {
            var rebusLoggerFactory = c.Get<IRebusLoggerFactory>();

            return new MsmqTransport(inputQueueName, rebusLoggerFactory);
        });
    }
}

As you can see, the MsmqTransport can be constructed with access to a IRebusLoggerFactory, which is retrieved from the resolution context, and then MsmqTransport can use the GetCurrentClassLogger method to get a logger for it to use:

readonly ILog _log;

public MsmqTransport(string inputQueueAddress, IRebusLoggerFactory rebusLoggerFactory)
{
    _log = rebusLoggerFactory.GetCurrentClassLogger();

    // other stuff down here (...)
}

...and that is how you get to log stuff good when you are extending Rebus.

Rebus' logging strategy

Debug

Rebus logs a lot of things, mostly Debug information that is most likely uninteresting in the general case. It can be nice to be able to turn on Debug logging when running on a developer machine though.

Info

Rebus Info logging is more interesting, because it will tell you information on when the bus starts up and shuts down etc. Therefore, e.g. to know that the system shuts down properly, it can be nice to leave Info logging on in your environments.

Warn and above

Warn and Error level logging should always be turned on, because these log levels are reserved for the interesting messages!

One thing should be noted: When your code throws during the handling of messages, it is NOT treated as an error until the message is moved to the service's error queue. I.e., during retries, multiple warnings may be logged, intil the final retry that results in an Error log, whereafter the message is moved out of the way.

Therefore, if you haven't set up monitoring of your error queues, it is probably a good idea to configure your favorite logging library to send a mail to an administrator when there's Error level logs.

⚠️ **GitHub.com Fallback** ⚠️