Here is a simple application that will log to console and syslog demon. On Windows platform we can use free edition of Kiwi Syslog Server. On Linux application will use both local and remote syslog. As a logger library I use NLog.
Sample solution can be downloaded from here https://github.com/mchudinov/LoggingNLog. It is compatible with Visual Studio 2012, Mono Develop 5, and Xamarin Studio 5.
1. Add NLog to the solution
NLog package
For logging to syslog demon on Linux we need NLog.Targets.Syslog
2. Configure NLog
NLog can be configured either in App.config or in an external file. I always configure NLog right in App.config, then I have less files to take care about. Simple App.config configuration look like this:
<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/> </configSections> <nlog> <variable name="Layout" value="${longdate} ${level:upperCase=true} ${message} (${callsite:includSourcePath=true})"/> <targets> <target name="debugger" type="Debugger" layout="${Layout}" /> <target name="console" type="ColoredConsole" layout="${Layout}"/> </targets> <rules> <logger name="*" minlevel="Trace" writeTo="console,debugger" /> </rules> </nlog> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="NLog" publicKeyToken="5120e14c03d0593c" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration>
nlog section contains a Layout variable that defines format for log output, two targets: console and Visual Studio output and one rule with logging level. nlog section must be defined in configSection section.
3. Test NLog
Instance Logger and use it:
private static Logger logger = LogManager.GetCurrentClassLogger();
class Program { private static Logger logger = LogManager.GetCurrentClassLogger(); static void Main(string[] args) { logger.Trace("Sample trace message"); logger.Debug("Sample debug message"); logger.Info("Sample informational message"); logger.Warn("Sample warning message"); logger.Error("Sample error message"); logger.Fatal("Sample fatal error message"); } }
4. Use async targets
Set async=”true” for targets.
<targets async="true"> <target name="debugger" type="Debugger" layout="${Layout}" /> <target name="console" type="ColoredConsole" layout="${Layout}"/> .... </targets>
5. Log to syslog
Remote Syslog is disabled by default on Ubuntu-flavor Linux by default.
To enable it edit Rsyslog config fil /etc/rsyslog.conf
The following lines must be uncomment it this configuration file:
################# #### MODULES #### ################# $ModLoad imuxsock # provides support for local system logging $ModLoad imklog # provides kernel logging support #$ModLoad immark # provides --MARK-- message capability # provides UDP syslog reception $ModLoad imudp #THIS LINE! $UDPServerRun 514 #THIS LINE!
Restart syslog demon sudo service rsyslog restart
root@mikael ~# service rsyslog restart rsyslog stop/waiting rsyslog start/running, process 2995
As a syslog on Windows a free version of syslog Kiwi can be used. Kiwi works only as a remote syslog server, it is available on standard 514 UDP syslog port.
Add NLog.Targets.Syslog package
https://www.nuget.org/packages/NLog.Targets.Syslog/
Add assembly reference to NLog.Targets.Syslog in App.config inside nlog section and add new target type Syslog. The new App.config looks like this:
<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/> </configSections> <nlog> <variable name="Layout" value="${longdate} ${level:upperCase=true} ${message} (${callsite:includSourcePath=true})"/> <variable name="LayoutSyslog" value="${message} (${callsite:includSourcePath=true})"/> <extensions> <add assembly="NLog.Targets.Syslog" /> </extensions> <targets async="true"> <target name="debugger" type="Debugger" layout="${Layout}" /> <target name="console" type="ColoredConsole" layout="${Layout}"/> <target name="syslog" type="Syslog" syslogserver="127.0.0.1" port="514" facility="Local0" sender="MyProgram" layout="${LayoutSyslog}"/> </targets> <rules> <logger name="*" minlevel="Trace" writeTo="console,debugger,syslog" /> </rules> </nlog> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="NLog" publicKeyToken="5120e14c03d0593c" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration>
This is a new section that should be placed in App.config for NLog version 4
<runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="NLog" publicKeyToken="5120e14c03d0593c" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" /> </dependentAssembly> </assemblyBinding> </runtime>
6. Logging from Quartz.NET
Quartz.NET uses Common.Logging. We must add a sectionGroup named common to configsection of App.config file:
<configSections> <sectionGroup name="common"> <section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" /> </sectionGroup> <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" /> </configSections>
And add a common/logging section that describes Common.Logging configuration that will be used by Quartz.NET:
<common> <logging> <factoryAdapter type="Common.Logging.NLog.NLogLoggerFactoryAdapter, Common.Logging.NLog31"> <arg key="configType" value="INLINE" /> </factoryAdapter> </logging> </common>
With an external NLog.config configuration file it will look like this:
<common> <logging> <factoryAdapter type="Common.Logging.NLog.NLogLoggerFactoryAdapter, Common.Logging.NLog31"> <arg key="configType" value="FILE" /> <arg key="configFile" value="~/NLog.config" /> </factoryAdapter> </logging> </common>
Final App.config:
<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <sectionGroup name="common"> <section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" /> </sectionGroup> <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" /> </configSections> <common> <logging> <factoryAdapter type="Common.Logging.NLog.NLogLoggerFactoryAdapter, Common.Logging.NLog31"> <arg key="configType" value="INLINE" /> </factoryAdapter> </logging> </common> <nlog> <variable name="Layout" value="${longdate} ${level:upperCase=true} ${message} (${callsite:includSourcePath=true})" /> <variable name="LayoutSyslog" value="${message} (${callsite:includSourcePath=true})" /> <extensions> <add assembly="NLog.Targets.Syslog" /> </extensions> <targets async="true"> <target name="debugger" type="Debugger" layout="${Layout}" /> <target name="console" type="ColoredConsole" layout="${Layout}" /> <target name="syslog" type="Syslog" syslogserver="127.0.0.1" port="514" facility="Local0" sender="EvryHemitParser" layout="${LayoutSyslog}" /> </targets> <rules> <logger name="*" minlevel="Info" writeTo="console,debugger,syslog" /> </rules> </nlog> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="NLog" publicKeyToken="5120e14c03d0593c" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration>
Colored console output:
Kiwi Syslog server on Windows output:
On Linux
Mono Develop output
Syslog on Linux
Sample solution can be downloaded from here https://github.com/mchudinov/LoggingNLog. It is compatible with Visual Studio 2012, Mono Develop 5, and Xamarin Studio 5.