Kristian Kristensen’s Blog


Getting Colors in the log4net output from NServiceBus

Posted in Code,NServiceBus by Kristian Kristensen on the November 15th, 2010

I recently asked a question on the NServiceBus mailling list about how to get the ColoredConsoleAppender from log4net to work with the Generic Host in NServiceBus. By coincidence I stumbled upon a solution a few days ago, and thought I’d explain it here. The reason for getting it to work is of course to get some nicer output in the console when developing. Especially if you’re showing debug events it can be hard to sift through all of the information being presented; color helps with this.

Out of the box NServiceBus comes with three 3 profiles for the Generic Host: Lite, Integration and Production. These each set the logging level and the appender differently. I tried to customize this by utilizing the existing profile and just add log4net entries in my app.config file. This didn’t work well. I got a bunch of errors, which are also detailed in my question to the mailling list. However, if you instead implement your own profiles you can control the logging completely.

First we need to create our marker for our new profile:

using NServiceBus;

namespace Odin
{
    public class Lite : IProfile {}
}
This class works as a marker for the classes who actually implement the profile specific behavior. My demo profile is just a copy of the OOB Lite profile from NServiceBus, so it’s implementation looks like this:
 public class LiteProfileHandler : IHandleProfile<Lite>, IHandleProfile, IWantTheEndpointConfig
    {
        public void ProfileActivated()
        {
            Configure.Instance.Configurer.
            ConfigureComponent<InMemorySagaPersister>(ComponentCallModelEnum.Singleton);
            if (this.Config is AsA_Publisher)
            {
                Configure.Instance.Configurer.
                ConfigureComponent<InMemorySubscriptionStorage>(ComponentCallModelEnum.Singleton);
            }

        }

        public IConfigureThisEndpoint Config {get;set;}
    }
The interesting part in regards to logging is in the class that handles logging for my Lite profile:
    public class LiteLoggingHandler : IConfigureLoggingForProfile<Lite>
    {
        public void Configure(IConfigureThisEndpoint specifier)
        {
            NServiceBus.SetLoggingLibrary.Log4Net(() => log4net.Config.XmlConfigurator.ConfigureAndWatch(
                new FileInfo(@"C:\log4net.config")));

            //Switch to this line of code to use the log4net section in app.config
            //NServiceBus.SetLoggingLibrary.Log4Net(
            //   log4net.Config.XmlConfigurator.Configure
            //     );
        }
    }
This sets up log4net to read the configuration defined in the file “C:\log4net.config”. Obviously you’d want this to point to an app specific directory, a relative one or by embedding it in the app.config of the application. Doing the latter can be done by this call:
NServiceBus.SetLoggingLibrary.Log4Net(
log4net.Config.XmlConfigurator.Configure
);
The contents of log4net.config is seen below. It includes some default colors for the different log levels and sets the log level to show all Debug events and higher. You could use this configuration file as a starting point, and/or embed it in your log4net section in the app.config file.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <log4net debug="false">
    <appender name="console" type="log4net.Appender.ConsoleAppender">
      <layout type="log4net.Layout.PatternLayout">
        <param name="ConversionPattern" value="%d [%t] %-5p %c [%x] &lt;%X{auth}&gt; - %m%n"/>
      </layout>
    </appender>
    <appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
      <mapping>
        <level value="FATAL" />
        <foreColor value="Red" />
        <backColor value="White" />
      </mapping>
      <mapping>
        <level value="ERROR" />
        <foreColor value="Red, HighIntensity" />
      </mapping>
      <mapping>
        <level value="WARN" />
        <foreColor value="Yellow" />
      </mapping>
      <mapping>
        <level value="INFO" />
        <foreColor value="Cyan" />
      </mapping>
      <mapping>
        <level value="DEBUG" />
        <foreColor value="Green" />
      </mapping>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
      </layout>
    </appender>

    <root>
      <level value="DEBUG"/>
      <appender-ref ref="ColoredConsoleAppender"/>
    </root>
  </log4net>
</configuration>

To start the generic host with your new profile you parse the fully qualified type name to the NServiceBus.Host.Exe:

NServiceBus.Host.Exe Odin.Lite

And you should see an output console with color.

Colored Console with output from NServiceBus

Colored Console with output from NServiceBus

  • If you like my writing you should subscribe to my RSS feed.

    nServiceBus Manufacturing Sample and SendOnlyEndpoints

    Posted in Code,NServiceBus by Kristian Kristensen on the October 29th, 2010

    I’ve been tinkering with nServiceBus recently and wanted to check out and run the latest SVN version (upcoming version 3.0). When I ran the Manufacturing sample that comes out of the box it didn’t work and complained about “Send only endpoints can’t contain message handlers.”

    It turns out that there’s recently been a change to the Unicast Bus so it’ll check if the endpoints you’re using are send only or not and enforce a contract. That’s fine and well and serves as an explanation, but that didn’t make the sample run. Turns out what’s needed is the empty configuration element in the app.config file. That means you should change the App.config file in the HR.Host project to match the following:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <configSections>
        <section name="MsmqTransportConfig" type="NServiceBus.Config.MsmqTransportConfig, NServiceBus.Core" />
        <section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" />
      </configSections>
    
      <!-- in order to configure remote endpoints use the format:
           "queue@machine"
      -->
    
      <MsmqTransportConfig
      InputQueue="hr"
      ErrorQueue="error"
      NumberOfWorkerThreads="1"
      MaxRetries="5"
      />
    
    </configuration>
    

    So it seems that without the empty configuration element inside, it’ll fail thinking there’s no Unicast bus configuration.

    Also, you want to do what’s described here on the NServiceBus Mailling List to get the sample running under .NET 4.0: Manufacturing Sample Exception

  • If you like my writing you should subscribe to my RSS feed.