About Nicholas Blumhardt

Bio:
I'm a software engineer living in Brisbane, Australia. In my spare time I take photos, surf like mad, and run the Autofac and Stateless open source projects, which I founded.
Website:
http://nblumhardt.com
Jabber / Google Talk:
admin

Posts by Nicholas Blumhardt

Serilog.Sinks.Log4Net

Would you like to try Serilog, but have existing log4net infrastructure? On the journey to “1.0” Serilog needs your experiences and feedback. The Serilog.Sinks.Log4Net package may provide just what you need to kick the tyres of Serilog without turning your existing code and libraries upside-down.

This package lets you pipe structured log events off to suitable storage, while text representations are merged into log4net to be written to a consolidated flat log file.

Serilog.Sinks.Log4Net

To install the package:

PM> Install-Package Serilog.Sinks.Log4Net

Your existing log4net configuration remains unchanged, e.g. using the XmlConfigurator:

XmlConfigurator.Configure();

In your Serilog configuration, include both your choice of structured event storage (in this example the RavenDB sink), and the log4net sink:

Log.Logger = new LoggerConfiguration()
    .WriteTo.RavenDB(documentStore)
    .WriteTo.Log4Net()
    .CreateLogger();

Events written to a log4net logger will travel through the log4net pipeline only. Events written to Serilog will be emitted to RavenDB with full property structure intact, and to the log4net pipeline as regular text-based messages.

The sink is very simple, preserving log levels (Information, Warning, Error and so on) as well as the source class name if ForContext<TSource>() is used.

A running example can be found in the Serilog GitHub repo.

A discussion forum for Serilog

If you’re curious about Serilog (or have a rant that might take more than the humble comment boxes below can accommodate) please drop in and say “hello”!

A console sink with property colouring

The coloured console ‘appender’ is one of my favourites in log4net, so high on the list for inclusion in Serilog.

Smart property highlighting makes the result quite interesting:

ColoredConsoleSinkDemo

You can use it on the full .NET Framework using the out-of-the-box Serilog 0.2.8 package.

Log.Logger = new LoggerConfiguration()
    .WriteTo.ColoredConsole()
    .CreateLogger();

Simple at this stage, but fun! What do you think?

Changes in Serilog 0.2

Serilog

Thanks for all the feedback on Serilog, keep it coming! Version 0.2 is now on NuGet and introduces a couple of noticeable changes.

Phone and tablet support

The core of Serilog is now portable across .NET 4.5, Windows 8 and Windows Phone 8.

Serilog on WP8

The latter two platforms only include one ‘sink’ out of the box, that writes to a System.IO.TextWriter. I’d like to set up sinks for local storage on those platforms, if you’re knowledgeable (or brave!) and interested in helping out.

Revised configuration API

The first version of LoggerConfiguration used flat method chaining to drive the configuration process.

Log.Logger = new LoggerConfiguration()
    .MinimumLevel(LogEventLevel.Debug)
    .WithConsoleSink()
    .CreateLogger();

The number of methods on LoggerConfiguration became unwieldy quickly. On typing ‘.’, a user would be presented with everything including .WithKitchenSink().

0.2 aims at a cleaner IntelliSense experience by grouping options:

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Debug()
    .WriteTo.Console()
    .CreateLogger();

In addition to MinimumLevel and WriteTo, you can configure Serilog to Filter log events based on arbitrary rules, Enrich log events with properties calculated at runtime, and Destructure complex parameter types for serialization various ways.

There are advantages and disadvantages to any API, for the moment I’m happy with this direction but open to suggestions (give it a try!) Thanks @droyad, @uglybugger and @turtlator for the motivation and first round of feedback.

Control over ‘destructuring’

The new version survives the serialization of circular object graphs and offers more control over the serialization process. For example, only a selection of properties from HttpRequestMessage might be included in a log event:

Log.Logger = new LoggerConfiguration()
    .Destructure.ByTransforming<HttpRequestMessage>(
        m => new { Uri = m.RequestUri.AbsoluteUri,
                   m.Method,
                   m.Headers })
    ...

Log.Debug("Received {@Message}", httpRequestMessage);

Thanks @sandcastle_hq for putting the momentum behind this.

(Quick note on terminology, Serilog breaks down objects in two phases; destructuring controls the tree created out of regular .NET objects, while serialization is specific to the sink being used, for example converting that tree structure into JSON.)

What’s next?

Use, feedback, documentation, performance profiling and tuning, more sinks.

Serilog

Serilog

Serilog is a new logging library for .NET that combines the best of “traditional” and “structured” approaches.

Instrumentation vs. analysis: different goals, different requirements

Application logs are rich with analysable data, but forces at play during the early phases of application development encourage trade-offs that limit the practicality of consuming them later on.

In their primary role as instrumentation, log entries must be effortless to write and comfortable to read, thus text-message-based logging formats remain more popular than schematised approaches today.

Event analysis later in the application lifecyle then tends to rely on fitting a more structured event stream to the application, or parsing log messages using regular expressions to recover fields from the event.

Serilog avoids this compromise by rethinking how log messages are processed.

Simple, familiar instrumentation

On the surface, Serilog will be familiar to users of nearly any .NET logging library:

Log.Logger = new LoggerConfiguration()
    .WithFileSink("applog.txt")
    .CreateLogger();

Log.Information("Hello, world!");

This example writes a line like the following to applog.txt.

2013-03-29 20:46:12 [Information] Hello, world!

Most of the bread-and-butter features you’d expect from a logging library are supported or planned.

Message parameters as structured data

The significant difference is in how message parameters are captured. While traditional logging libraries render messages into strings before processing, Serilog defers rendering and captures the parameters separately from the message template:

SerilogLog

The log event, rather than being represented by a textual message, is captured as a MessageTemplate along with two properties, SensorInput and Time.

Later in processing the message can be rendered as text for an output mechanism like a log file. Or, the structured event describing the log message may be stored as-is in a NoSQL database like CouchDB or RavenDB. Writing to a document data store is where the strength of Serilog kicks in.

In this example, the @ in front of the SensorInput property name instructs Serilog to preserve the structure of the object, breaking it down into Lat and Long properties (for some examples showing why this is great see this discussion). The resulting document embeds the structure, rather than a string representation:

Couch

This is the core value proposition of the Serilog – build your application with all the advantages of simple text based logging, then seamlessly enable structured log analysis later on by adding a capable data store.

The project

Is Serilog ready for prime time? It depends on your willingness to tinker. The project is coming togrether, but there are numerous rough edges and nice-to-have features missing. Notably, there’s no XML configuration story out of the box. If you have a chance to kick the tyres I’d love to hear what you think.

Is yet-another-logging-library just a serious case of “not invented here”? I think that the log structure problem is yet to be completely solved, and that it needs to be. If you feel the same way, please get in touch – all help appreciated!

Autofac update 2.6.1 published

The eagle-eyed may have already spotted Autofac 2.6.1 lurking in the NuGet feed.

The last release, the venerable 2.5.2, served us very well (maturity is a feature!) and this release adds a little more polish, without any known breaking changes.

  • The ASP.NET MVC integration package gets a bug fix for recursive views, UrlHelper and RequestContext registered by AutofacWebTypesModule, and an explicit method for registering model binders.
  • The WCF integration package gets much improved support for services with InstanceContextMode.Single.
  • A new helper InstancePerOwned<T>() makes it easier to control lifetime when using Owned<T>.
  • Autofac can now be used with .NET Portable Class Libraries (download only on the project site. (The Windows Phone 7 build now uses this configuration too.)
  • Autofac.dll is now clear of any issues found by SecAnnotate.exe.

Extra thanks to Alex and Travis for the majority of these improvements.

Convention-based part registration available in a new MEF preview!

There are many, many similarities between IoC-for-decoupling (as we know and love in Autofac) and IoC-for-extensibility as is implemented by MEF.

One thing that stuck out in the beginning for the MEF project members with IoC backgrounds, was the verbosity of using [Import] and [Export] attributes to describe parts, instead of the much more terse convention-driven approach used by IoC containers.

Over time, most of us grew to appreciate the role that the attributed programming model played in creating an unambiguous, decentralized configuration mechanism for plug-ins.

What the we also found was that applications using MEF for extensibility would also use it for internal composition, a-la IoC. In the much more controlled context of the host application, the lighter, more direct, convention-driven configuration model is compelling. DRY is one of the most important principles for building maintainable software, so techniques that eliminate repetition are very valuable.

It should be no surprise then, that the latest release of MEF (that I’ve only recently had any involvement in) comes with a nifty little model for defining parts by convention. The syntax should be familiar if you’re used to this kind of API:

var builder = new RegistrationBuilder();
builder.ForTypesDerivedFrom<Controller>()
    .Export()
    .SetCreationPolicy(CreationPolicy.NonShared);

When wired up to a MEF catalog, these simple conventions will read a part like:

public class HomeController :  Controller
{
    public HomeController(/* Dependencies here */) {}
    public ActionResult Index() {}
}

As:

[Export, PartCreationPolicy(CreationPolicy.NonShared)]
public class HomeController :  Controller
{
    [ImportingConstructor]
    public HomeController(/* Dependencies here */) {}
    public ActionResult Index() {}
}

RegistrationBuilder has more than a few tricks up its sleeve, and we expect to write a lot more about it on the BCL team blog in the coming weeks. For now, you can read about the new release, or even better, download the preview source and binaries from CodePlex.

Autofac 2.5 Released

Autofac 2.5 is now available on the project site and via NuGet. The new version includes a range of great contributions.

After incubation as an external project, Windows Phone 7 now joins ranks of officially-supported targets (just install the Autofac package via NuGet and you’re up and running!) For some tips on getting started see Brendan Kowitz’s notes.

The new release is highly-compatible with Autofac 2.4 (best used with the VS2010 compiler when targeting .NET 3.5.)

Included changes are:

  • Issue 329 – types are filtered by compatibilty before invoking key mapping functions when scanning assemblies
  • RegisterAssemblyTypes(...).WithMetadataFrom<T>() simplifies extraction of metadata from attribute properties
  • Module.ThisAssembly simplifies implementation of modules that scan their own assembly
  • Issue 333 – enable RegisterAssemblyTypes(...).PreserveExistingDefaults()
  • Windows Phone 7 and 7.1 support
  • Issue 312 – allow ContainerBuilder.Update() on the ComponentRegistry of any
    ILifetimeScope without affecting the parent scope
  • Issue 327 – allow autowiring of enum properties
  • Issue 319 – support list and dictionary literals in XML configuration
  • Issue 330 – corrections to generic type constraint checking where the constraint type is an interface
  • Issue 331 – fix build warnings and runtime issues using Moq integration
  • Introduced ContainerBuildOptions to control invocation of IStartable.Start() under unit tests
  • Container.Empty is now a property rather than a field (protection from inadvertent updates
  • Removed broken/obsolete examples from source tree (better examples are available elsewhere online)
  • Host configuration features for AutofacHostFactory in WCF integration
  • ComponentRegistry.Register() is now safe for use under multiple threads
  • Issue 227 – breaking change additional options (and enum rather than boolean parameter) for PropertiesAutowired()
  • Additional web abstractions are now registered by the MVC3 AutofacWebTypesModule
  • Issue 311 – fixed potential lifetime issues when injecting into MVC filter attributes
  • Tightened up behavior when correct constructor to use under reflection activator is ambiguous (now throws rather than choosing nondeterministically)
  • Issue 309 – fixed some issues in TypeExtensions.IsClosedTypeOf()
  • Improved exception messages

Many thanks to the Autofac project team and collaborators across the web for making this release happen!

Designing a Short Course on IoC: Day 5

The last of this curious series of journal entries today. As I mentioned previously, today is going to be about finalising the end-to-end flow of topics.

I think the first session – Fundamentals – is finished. I’m really excited and even a little nervous about putting together a new container on the fly! As a way of bedding down the terminology, mechanics and challenges, I think it is going to be great.

The layout for the remainder of the day still needs work, so I’d better get stuck into it! Those who’ve already signed up, I’ll see you soon – if you haven’t put your name down yet for either Brisbane, Sydney or Melbourne, this is probably the last reminder you’ll get from me.

Designing a Short Course on IoC: Day 4

A brief update today. Yesterday I think I covered everything I need to as far as demo app material goes, but tidying up, styling and (egads!) unit testing will have to wait for a rainy day.

I spent a fair bit of time yesterday looking at how I can use Whitebox to give an x-ray view of the composition process as the application is built. The information it provides is great – often revealing little issues that would otherwise go unnoticed – but the usability leaves me deeply unsatisfied. Still, it is a start, and by chipping away at it things are improving. Just having a simple view of component details is an improvement:

Whitebox component detail view

Today I’m concentrating on the flow of the day. I still have some questions to answer around the introductory session – how theoretical do we want to get? Does it make sense to examine the problems of composition in OO languages, or can we take that as a given for people interested in learning more about IoC? My tendency in the past would have been to go into depth about this, but by starting with “you’re going to use IoC – here’s how to do it” I think the practical side of the Dev Day will be emphasised.