Ads by Lake Quincy Media
Gibraltar - Learn about the best analysis tool for NLog

Archive for the ‘NLog v2’ Category

Using NLog with Mono

After releasing NLog 2.0 a number of people have reported problems with running on latest versions of Mono. Basically at the end of program execution (after the Main() has finished) the program locks up waiting for NLog logs to be flushed, so mono process never completes and needs to be killed.

This behavior is only specific to NLog 2.0 – NLog 1.0 did not exhibit this behavior. It seems to be related to threading and timers used by NLog 2.0 which are somehow not available in Mono when the program is about to be terminated. The same code works with .NET just fine. I haven’t fully investigated this issue – maybe Mono folks can see if this issue can be fixed in Mono itself?

Anyway – there is a simple way prevent the deadlock: just make sure you set LogManager.Configuration property to null before your application exits. This will cause Flush() to be executed before Main() finishes and will prevent appdomain unload handler from locking up.

In NLog 2.0.0.2005 (nightly build – available on CodePlex, source code on GitHub as usual) I have disabled automatic flushing of logs in Mono builds. That means that when running on Mono (same as with Silverlight and .NET Compact Framework), it is developer’s responsibility to flush logs before program exits. I’m hoping to restore automatic flushing behavior when the issue is fixed in Mono or if I can find a way to work around the problem.

Ads by Lake Quincy Media

NLog 2.0 Release Candidate is now available

It is our pleasure to announce that the Release Candidate (RC) of NLog 2.0 is now available for download. This is the last milestone before NLog 2.0 final release.

  • Binary downloads are available on CodePlex
  • Source code on GitHub
  • Full release notes can be found here.

Please download the release and report any problems you may find. Assuming no critical issues are found, NLog 2.0 will be released within a month from the RC release.

Exception logging enhancements

One of the frequent feature requests I’ve been getting was to improve the way exceptions are logged. Recent builds of NLog 2.0 include several usability enhancements that should make working with exceptions much easier.

Conditional formatting

Conditional logging allows you to make your layouts somewhat more dynamic – you can include/exclude fields based on conditions, provide default values and so on. In order to achieve this, you have 3 new layout renderers at your disposal.

${onexception:INNER} -  output

To render a layout when the exception is being logged, use ${onexception:INNER}, it will output INNER only when current log event includes an exception (in other words when it was emitted using any of the Logger.*Exception() methods. INNER can include other layouts, for example:

<targets>
  <target name="f" type="File" layout="${message}${onexception:EXCEPTION OCCURRED\:${exception:format=tostring}}" />
</targets>

It will output log message, but in case of exception, it will also log detailed exception information prefixed with "EXCEPTION OCCURRED:".

${when} – advanced conditional formatting

You can also conditionally include or exclude layout renderers based on conditions by using ${when} layout renderer wrapper. You can even use ambient property called "when" as if it were declared on any other layout renderer:

For example ${message:when=logger==’logger’} will only print the message when it was emitted by ‘logger’. The conditions can be much more complex – you have the full power of conditions language at your disposal.

${whenEmpty} – empty value coalescing

Sometimes you may want to print an indication that a layout renderer has produced an empty value, instead of completely skipping its output. That’s where ${whenEmpty} layout renderer wrapper comes in handy. You can also use the ambient property form, just by using ‘whenEmpty’ property in any other layout renderer. For example:

${message:whenEmpty=(no message)}

Inner exception logging

Recent builds also include improvements to ${exception} layout renderer which now lets you output inner exceptions. There are several new properties:

  • ${exception:maxInnerExceptionLevel=N} -  controls how many inner exceptions are logged. defaults to zero for backwards compatibility.
  • ${exception:innerExceptionSeparator=TEXT} – defines text that separates inner exceptions. Defaults to new line string (platform specific).
  • ${exception:innerFormat=FORMATSTRING} – defines the format of inner exceptions the same way that ${exception:format=FORMATSTRING} defines the format of the top-level exception. If this parameter is not specified, the same format is used for both top-level and inner exceptions.

A complete usage example is:

<targets>
  <target name="f" type="File" layout="${message}${onexception:EXCEPTION OCCURRED\:${exception:format=type,message,method:maxInnerExceptionLevel=5:innerFormat=shortType,message,method}}" />
</targets>

This will print top-level exception with full type name, message and method that raised the exception, but for inner exceptions only short type name is used instead.

As always, comments and suggestions are welcome.

NLog for Windows Phone 7

This week I have checked in a port of NLog 2.0 for Windows Phone 7. It’s still very experimental and the intention of this release is to get feedback from people. Please use at your own risk.

Current build supports 8 targets:

  • Console – can be used to write logs to the console (only works in Emulator – see this post for instruction on how to enable console output)
  • Memory – stores traces in memory
  • MethodCall – runs user-provided method for each log message
  • Network, NLogViewer and Chainsaw – write XML-formatted log event over the network. Only HTTP:// and HTTPS:// protocols are supported.
  • WebService – sends log events to a web service using SOAP or POST
  • LogReceiverService – sends log events to LogReceiver web service using WCF

Note that File target and several others are not included because of current constraints of the platform APIs.

Here is a simple step-by-step tutorial for adding NLog to your WP7 app:

  1. Download and install the bits

    • Go to http://nlog.codeplex.com/releases and download one of the recent nightly builds – choose build later than 2011/1/9
    • Pick a package named = NLog2-All-*.msi (includes builds for all platforms – recommended) or NLog2-WP-*.msi (which includes only WP7 bits).
    • Run the setup and wait – setup will add code snippets and templates for all development environments you have on the machine, which can take some time (couple minutes, so be patient)
  2. Add NLog  to your Windows Phone app project

    • Open your project
    • Add NLog.config to your project – the easiest way is to select ‘Add new item’ and choose ‘Empty NLog Configuration File’ from the ‘NLog’ section.
      NLogWP7AddNewItem
    • This will also add a reference to NLog:
      NLogWP7WithReference
    • If you prefer, you manually add reference to "C:\Program Files (x86)\NLog\Silverlight for Windows Phone 7\NLog.dll" instead and create NLog.config manually
    • One last thing is changing Build Action for NLog.config to ‘Content’ (this ensures that the file will be included in the XAP package).
  3. Set logging configuration

    In this tutorial we will use LogReceiverService target, but you can use any other target supported by NLog. To do this open NLog.config and paste the following configuration:

    <?xml version="1.0" encoding="utf-8" ?>
    <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    
        <targets>
          <target xsi:type="LogReceiverService" name="webService" endpointAddress="http://localhost:5000/LogReceiver.svc"/>
        </targets>
    
        <rules>
          <logger name="*" minlevel="Debug" writeTo="webService" />
        </rules>
    </nlog>
  4. Emit log messages

    To emit log messages you need to get a Logger instance from LogManager and call one of the log methods. See .NET_Logging_API for more information. Let’s add some logging code to MainPage.xaml.cs:

    namespace WindowsPhoneApplication2
    {
        using System.Windows;
        using Microsoft.Phone.Controls;
    
        public partial class MainPage : PhoneApplicationPage
        {
            private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
    
            // Constructor
            public MainPage()
            {
                InitializeComponent();
                logger.Info("Main page loaded.");
            }
    
            private void button1_Click(object sender, RoutedEventArgs e)
            {
                logger.Debug("Button 1 clicked.");
            }
    
            private void button2_Click(object sender, RoutedEventArgs e)
            {
                logger.Debug("Button 2 clicked.");
            }
        }
    }

    When you run the code, log messages will be sent to http://localhost:5000/LogReceiver.svc

  5. Receive log messages

    In order to receive log messages you need to have an endpoint that implements ILogReceiverServer contract. NLog comes with an example that does just that and listens on (incidentally) http://localhost/LogReceiver.svc , or if you prefer you can implement your own server. You can find it the example in the source code under examples\NLogReceiverForwarderService. The sample will basically forward NLog messages received from the network through NLog running on the server machine.

    • Download NLog source code
    • Open the project file examples\NLogReceiverForwarderService\NLogReceiverForwarderService.csproj (Visual Studio needs to be running as an Administrator)
    • Edit NLog.config and adjust log outputs as necessary.
    • Run the project. Notice how when you click on buttons in your Windows Phone 7 application, the logs are displayed on your console:

      LogForwarderOutput
  6. Let’s do more…

    Having rich NLog do log routing on both client and server opens a lot of possibilities. You can for example send much richer information from the client to the server. In order to do this we’ll be using parameters. Let’s modify client side configuration to send thread id along with each log message:

    <?xml version="1.0" encoding="utf-8" ?>
    <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    
        <targets>
          <target xsi:type="LogReceiverService" name="webService" endpointAddress="http://localhost:5000/LogReceiver.svc">
            <parameter name="t" layout="${threadid}" />
          </target>
        </targets>
    
        <rules>
          <logger name="*" minlevel="Debug" writeTo="webService" />
        </rules>
    </nlog>

    On the server side, we can now extract ‘t’ parameter using ${event-context} layout renderer. Let’s also add timestamp to each message:

    <?xml version="1.0" encoding="utf-8" ?>
    <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    
        <targets>
            <target name="console" xsi:type="Console" layout="${longdate} ${message} ${event-context:t}" />
        </targets>
    
        <rules>
            <logger name="*" minlevel="Debug" writeTo="console" />
        </rules>
    </nlog>

    Now when you restart both client and server you should see this picture – we can now see that all log events were sent from thread #2 – the UI thread of the Silverlight application.

    LogForwarderOutput2

I would love to hear your feedback about this build and using NLog in Windows Phone 7 applications in general. Please use Forum for any questions or suggestions or Issue Tracker if something does not work correctly.

NLog 2.0 Beta 1 has been released

It is my pleasure to announce that NLog 2.0 Beta 1 has been released.

NLog 2.0 release is focused on adding support for new platforms (Silverlight, .NET Framework 4), improving logging architecture and manageability and addressing most frequently reported user issues.

The following platforms are supported in this release:

  • .NET Framework 2.0 SP1 and above, 3.5 (Client and Extended profiles), 4.0 (Client and Extended profiles)
  • Silverlight 2.0, 3.0, 4.0
  • .NET Compact Framework 2.0, 3.5
  • Mono 2.x profile

Read full release notes:
http://nlog-project.org/nlog2-beta1-release-notes

Download Beta 1 bits on CodePlex:
http://nlog.codeplex.com/releases/view/52957

Source code is available on GitHub:
http://github.com/jkowalski/NLog/

Bugs can be reported on CodePlex:
http://nlog.codeplex.com/workitem/list/basic

Discuss on forum:
http://nlog-project.org/forum

Subscribe to NLog RSS feed:
http://nlog-project.org/feed

Follow @JarekKowalski on Twitter:
http://twitter.com/JarekKowalski

New exception handling rules in NLog 2.0

NLog will introduce a change to logging exception handling and suppression. In NLog 1.0 all exceptions were disabled by default, but could be enabled by setting

<nlog throwExceptions=”true>

</nlog>

or in code:

LogManager.ThrowExceptions = true;

This flag applied to configuration errors as well as runtime errors, which was problematic, because a simple configuration file typo could cause entire logging to be disabled silently.

To address this, NLog 2.0 will treat configuration errors separately from runtime errors. There will be two kinds of exceptions:

  1. Configuration exceptions – raised during parsing of configuration file and wrapped in NLogConfigurationException. Such errors are fatal and will prevent your application from starting (this is the same as having malformed App.config or Web.config). The errors that cause this exception are:
    • syntax errors in NLog.config
    • invalid target names
    • invalid property names
    • invalid property values
  2. Runtime exceptions (such as permission issues, connection failures, etc.) – raised during logging and initialization and wrapped in NLogRuntimeException. They can be controlled by throwExceptions flag.

I would love to hear your comments.

Intellisense for NLog configuration files

I have recently updated tools to build NLog.xsd which are needed to Intellisense in Visual Studio. Instead of one, in NLog 2.0 there will be multiple schema files – one for each framework plus a unified schema for all frameworks.

File Name XML Namespace Frameworks
NLog.xsd http://www.nlog-project.org/schemas/NLog.xsd (all frameworks)
NLog.Mono2.xsd http://www.nlog-project.org/schemas/NLog.mono2.xsd Mono 2.x
NLog.NetCf20.xsd http://www.nlog-project.org/schemas/NLog.netcf20.xsd .NET Compact Framework 2.0
NLog.NetCf35.xsd http://www.nlog-project.org/schemas/NLog.netcf35.xsd .NET Compact Framework 3.5
NLog.NetFx20.xsd http://www.nlog-project.org/schemas/NLog.netfx20.xsd .NET Framework 2.0
NLog.NetFx35.xsd http://www.nlog-project.org/schemas/NLog.netfx35.xsd .NET Framework 3.5
NLog.NetFx40.xsd http://www.nlog-project.org/schemas/NLog.netfx40.xsd .NET Framework 4.0
NLog.SL2.xsd http://www.nlog-project.org/schemas/NLog.sl2.xsd Silverlight 2.0
NLog.SL3.xsd http://www.nlog-project.org/schemas/NLog.sl3.xsd Silverlight 3.0
NLog.SL4.xsd http://www.nlog-project.org/schemas/NLog.sl4.xsd Silverlight 4.0

The idea is that each XSD file only contains items (targets, layouts, filters, etc.) supported by a particular framework and unified schema supports all the targets supported by at least one framework. Because of that Intellisense will provide smart editing help and validation that’s specific to the target framework.

Intellisense In Action

When you add NLog.config to your project using Add Item, it will be using a unified schema (so you will see both Silverlight-specific and .NET Framework specific targets there)

image

When you change the XML to a particular framework – for example Silverlight 2.0, you will immediately see that File target is not supported on that platform and XML editor will highlight the place where the error occurs.

image

This also works for individual properties. For example, LogReceiverService target does not support certain properties on .NET Compact Framework 3.5 (because of lack of WCF). Sure enough, when you use .NET CF-specific schema those errors will be highlighted.

image

XSD schemas also provide help when editing NLog.config files:

image

Customizing XSD Schemas

Starting with NLog 2.0 it is also easy to customize NLog.xsd, which can be useful if your organization uses private extensions to NLog. Let’s say you have created your NLog extensions and put them in SampleExtensions.dll. In order to generate customized NLog.xsd, you need to follow this simple process:

The first step is to download and unpack NLog sources (from GitHub or zip package) and build everything by running:

build.cmd build xsd

from command line. This will build NLog and the tools necessary to customize XSD files. First tool we’ll be using is called DumpApiXml, which analyzes a DLL and generates API file from it as described here. We must run it on our extensions assembly and pass it directory (or directories) where all reference assemblies are located.

<nlog-dir>\tools\DumpApiXml\bin\Debug\DumpApiXml.exe –assembly  <path>\SampleExtensions.dll  -ref "D:\Work\NLog\build\bin\Debug\.NET Framework 4.0" –output <path>\SampleExtensions.api

Once we have the SampleExtensions.api project, we need to convert it to XSD using MakeNLogXSD. It accepts multiple *.api files and can produce XSD files with custom namespaces:

<nlog-dir>\tools\MakeNLogXSD\bin\Debug\MakeNLogXSD.exe -api "<nlog-dir>\build\bin\Debug\.NET Framework 4.0\API\NLog.api" –api <path>\SampleExtensions.api -xmlns http://mycompany.com/NLog.xsd –out <path>\MyNLog.xsd

The command will produce MyNLog.xsd which will use http://mycompany.com/NLog.xsd schema. You can now install the schema in Visual Studio (by dropping it in "%ProgramFiles%\Microsoft Visual Studio 9.0\Xml\Schemas" directory) and you should be able to enjoy Intellisense and validation against your custom schema:

image

NLog 2.0: Small API reorganizations and breaking changes

I just checked a set of API changes, which may break code which uses recent nightly builds from NLog 2.0 branch. If you are upgrading to the latest build (2010.06.11.01 or newer) you may need to update your code:

  • NLog.Targets.Compound namespace was removed and classes were merged into NLog.Targets.Wrappers namespace. In NLog 2.0 there is no distinction between wrappers and compound targets – they will be collectively referred to as wrappers.
  • NLog.Contexts namespace was removed and classes were merged into NLog namespace (this is actually the situation we had in NLog 1.0, so this change is really undoing previous breaking change which was unnecessary)

The changes are consistent with general breaking change policy and should not impact people only using file-based configuration and simple logging APIs.

New, smaller NLog installer is available

I’ve just checked in code changes to produce much smaller installer packages for NLog 2.0. Until now, the combined installer package for all framework was 20.8MB, after the change it is less than 6 MB. What made the installer huge was not the size of NLog.dll (it is are between 200KB and 300KB depending on the platform), but the documentation: 9 chm files, each about 2MB. it was clearly a big waste, given that the documentation for most platforms is almost the same.

The new installer includes single documentation file generated from a special build of NLog with DOCUMENTATION flag turned on. The combined assembly includes superset of all APIs available for all platforms – the produced assembly won’t necessarily run, but is good enough to generate documentation. The same technique was used in NLog 1.0 timeframe – I originally thought it would not work for 2.0 given large differences between .NET and Silverlight build, but now I think it is a reasonable compromise between the size and accuracy of the doc file.

The new suite of installers should show up on CodePlex in the next couple hours.

NLog 2.0 documentation is available on the wiki

Documentation for NLog 2.0 is now available on the Wiki. It includes reference documents generated automatically from code as well as hand-written documents and tutorials, some of which have been migrated from WordPress pages to the Wiki format.

Documentation for targets, layouts, layout renderers and filters has been enhanced to include usage examples which you can paste into your configuration code. Because of the new format, it is possible to enhance reference documents with user-created content, such as code or configuration samples. See documentation for the File target for an example.

Note that it is not possible to edit certain parts of automatically generated pages. Things like parameter list, supported platforms and usage example do not show up in Wiki source. Instead you will see a special tag which looks like: <generatedDoc id=’File_target’ hash=’db5419b5ab45ec8defc51cb5dabeaaf4′ />, and causes generated doc to be inserted. The tags and contents are automatically updated whenever I re-upload documentation.

Now that every piece of documentation is in Wiki format, I’m looking for volunteers to help maintain and enhance it, so if you like technical writing and want to own part of the documentation, please let me know.

Please report any issues you find with the Wiki as comments here, or (even better), register for an account and fix those issues yourself.