Configure logging for Windows Service using log4net — Part 2
This blog post is part of the series How to: Create Windows Service that schedules jobs, logs and is configurable by means of dependency injection.
In previous blog post, we created a simple Windows Service with Topshelf which can be installed using simple command line. When we ran our Windows Service as a console application we saw the following output:
We can see there is some default logging going on here. In this blog post we will see how to configure our own logging using log4net, Apache library that is publicly available as a NuGet package. Before we show how to do just that, let’s first try to understand how logging is implemented in Topshelf.
If we decompile Topshelf’s HostFactory.New()
and HostFactory.Run()
methods, we can see calls to HostLogger.Get()
method which returns LogWriter
that does the actual logging. In HostLogger.Get()
method, HostLogger
uses LogWriterFactory
to create LogWriter
instance which is then returned. HostLogger
provides default value for LogWriterFactory
property, which is why we see logging taking place when we run our console application. We can supply custom LogWriterFactory
by calling HostLogger.UseLogger(HostLoggerConfigurator configurator)
. HostLoggerConfigurator
is a factory for LogWriterFactory
and contains a single method called CreateLogWriterFactory()
.
Types HostLoggerConfigurator
, LogWriterFactory
and LogWriter
are interfaces. That means we can provide our custom implementations and supply them via HostLogger.UseLogger()
method. By default, HostLogger
uses TraceHostLoggerConfigurator
, TraceLogWriterFactory
and TraceLogWriter
implementations from Topshelf.Logging namespace. Together, they set up TraceSource
with TraceListener
that outputs to console — that is why we see logs in the console. TraceSource
and TraceListener
are types from System.Diagnostics and you can read more about them on Microsoft’s docs page.
Now that we know how logging in Topshelf works, it’s just a matter of providing our own log4net implementations for HostLoggerConfigurator
, LogWriterFactory
and LogWriter
, or we can use NuGet package that does that for us — Topshelf.Log4Net.
After installing Topshelf.Log4Net, we can do the following:
XmlConfigurator.Configure()
configures log4net from our app.config
file.
hostConfigurator.UseLog4Net()
provides log4net implementations for HostLoggerConfigurator
, LogWriterFactory
, LogWriter
and supplies them to HostLogger
via HostLogger.UseLogger()
.
Once this is done, we get the following output:
We see the logging pattern that is now configured in the provided app.config
below.
If you are not familiar with log4net configuration API, you can learn more on https://logging.apache.org/log4net/release/manual/configuration.html.
In next post, we will configure dependency injection using Autofac.