Simplified logging
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


This contains a simple logging facade in dapplo.log, as well as some simple loggers, a file logger and also some (currently example) adapters for other log frameworks. The facade allows a framework/library to have log statements without forcing the project that uses this to use the same huge logger. Without a logger and if used correctly the performance penalty is extremely small, as soon as you have issues you can set a logger and get some information.

The project is build modular, currently the facade which is the least you will need, is about 17KB. Adding a file logger adds another 21KB, which totals to <40KB. Just as a comparison, log4net is about 300KB. (although unfair, it can do a lot more)

  • Documentation can be found here
  • Current build status Azure DevOps: Build Status
  • Coverage Status Azure DevOps: Coverage Status
  • Current build status AppVeyor: Build status
  • Coverage Status coveralls: Coverage Status
  • NuGet package Dapplo.Log: NuGet package
  • NuGet package Dapplo.Log.Loggers: NuGet package
  • NuGet package Dapplo.Log.LogFile: NuGet package
  • NuGet package Dapplo.Log.XUnit: NuGet package

This package supports most platforms / profiles, if something is missing let me know.

Ever written a framework? Well... I did, and one of the biggest problems I had was deciding on a logger framework. Most of the time, I didn't decide on a logger as this would force the user to use or at least include the one I used. This project will help you out, and make it possible for your user to decide where the entries go.

To you this, you add the nuget package. Add the using statement to your class:

using Dapplo.Log;

Include a static one-liner in your class:

private static readonly LogSource Log = new LogSource();

And wherever you want to write a log statement, you call:

Log.Info().WriteLine(message, params);
Log.Error().WriteLine(exception, message, params);

Where the Log is the static LogSource variable in your class, the method after this defines the log level and the WriteLine only specifies the information to log. There is a reason why this is defined like this:

  • The LogSource captures the calling class (by using StackTrace or CallerFilePath for PCL) once, so you know where the log came from.
  • The log level method is an extension method which defines the level, captures the calling method and line of the code. Available levels are:
    • None
    • Verbose
    • Debug
    • Info
    • Warn
    • Error
    • Fatal
  • The Write / WriteLine extension takes care of the arguments.
  • If no logger is available, or the level is higher, nothing happens. If there is a logger with the right leven, all information is passed to the logger.

To see the output from the code in your project, you will need to instanciate a logger before using it. There are a couple of loggers available, here some examples:

  • TraceLogger, which uses the System.Diagnostics.Trace to write the formatted information to.
  • ConsoleLogger, which uses the Console to write the formatted information to.
  • XUnitLogger, this is specific for XUnit and makes it possible to see the output to every Fact

If you need a specific log level, use either this before creating your TraceLogger:

LogSettings.DefaultLevel = LogLevel.Warn;

Or you can set the level on the Logger itself.

You enable the logging like this:


A file logger is also available, it supports:

  • Async writing to the file, it will only delay your application with a small overhead of accessing an internal queue.
  • Rolling filenames
  • If rolling, the file can be moved to a directory and have a different filename.
  • If rolling, the file can be gzipped Available in the package Dapplo.Log.LogFile

I have included examples of "wrappers" in the test project, these are not available in a NuGet Package.

That is all for now...