<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

 <title>NLog</title>
 <link href="http://nlog-project.org/feed/index.xml" rel="self"/>
 <link href="http://nlog-project.org/"/>
 <updated>2013-06-14T06:53:35-07:00</updated>
 <id>http://nlog-project.org/</id>
 <author>
   <name>Kim Christensen</name>
 </author>

 
 <entry>
   <title>Moving NLog Forward</title>
   <link href="http://nlog-project.org/2012/07/23/moving-forward.html"/>
   <updated>2012-07-23T00:00:00-07:00</updated>
   <id>http://nlog-project.org/2012/07/23/moving-forward</id>
   <content type="html">&lt;p&gt;Dear NLog Community,&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s been almost exactly a year since NLog 2.0 was released. Since v1.0 release in 2006 NLog has been very popular among .NET developers, but as you may have noticed, the development has stagnated a bit after 2.0 release.&lt;/p&gt;

&lt;p&gt;In the last 6 months or so I found myself having less and less free time to spend on coding in general, and developing NLog in particular. The fact that my day job now involves programming in Java and not .NET does not really help.&lt;/p&gt;

&lt;p&gt;NLog clearly needs your help to remain the coolest logging library for .NET: I&amp;#8217;m looking for a passionate person, a group of people or a company, who could gradually take over the responsibility of running NLog project and moving it forward.&lt;/p&gt;

&lt;p&gt;It involves planning, managing automated builds, releases, bugs, forums, wiki, running website, NuGet, tools, integrating community contributions, etc. The reward is huge: thousands of satisfied developers, who have downloaded NLog 2.0 about 100.000 times in the last year alone!&lt;/p&gt;

&lt;p&gt;Please contact me if you&amp;#8217;re interested in owning part of NLog&amp;#8217;s future at &lt;a href='mailto:jaak@jkowalski.net'&gt;jaak@jkowalski.net&lt;/a&gt; or post on the &lt;a href='http://nlog-project.org/forum'&gt;Forum&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Using NLog with Mono</title>
   <link href="http://nlog-project.org/2011/10/30/using-nlog-with-mono.html"/>
   <updated>2011-10-30T00:00:00-07:00</updated>
   <id>http://nlog-project.org/2011/10/30/using-nlog-with-mono</id>
   <content type="html">&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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&amp;#8217;t fully investigated this issue - maybe Mono folks can see if this issue can be fixed in Mono itself?&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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&amp;#8217;s responsibility to flush logs before program exits. I&amp;#8217;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.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>NLog 2.0 has been released!</title>
   <link href="http://nlog-project.org/2011/07/17/nlog-2-0-has-been-released.html"/>
   <updated>2011-07-17T00:00:00-07:00</updated>
   <id>http://nlog-project.org/2011/07/17/nlog-2-0-has-been-released</id>
   <content type="html">&lt;p&gt;It is my great pleasure to announce that NLog 2.0 has been released.&lt;/p&gt;

&lt;p&gt;NLog 2.0 release is focused on adding support for new platforms (Silverlight, .NET Framework 4, Windows Phone 7.x), improving logging architecture and manageability and addressing most frequently reported user issues.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Binaries can be downloaded from &lt;a href='http://nlog.codeplex.com/releases/view/32639'&gt;CodePlex&lt;/a&gt;.&lt;/li&gt;

&lt;li&gt;Sources are available at &lt;a href='http://github.com/NLog/NLog'&gt;GitHub&lt;/a&gt;.&lt;/li&gt;

&lt;li&gt;&lt;a href='http://nuget.org/'&gt;NuGet&lt;/a&gt; packages are also &lt;a href='http://nuget.org/List/Packages/NLog'&gt;available&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can read the release notes at &lt;a href='http://nlog-project.org/nlog-2-0-release-notes.html'&gt;http://nlog-project.org/nlog-2-0-release-notes.html&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>NLog 2.0 Release Candidate is now available</title>
   <link href="http://nlog-project.org/2011/06/17/nlog-20-release-candidate.html"/>
   <updated>2011-06-17T00:00:00-07:00</updated>
   <id>http://nlog-project.org/2011/06/17/nlog-20-release-candidate</id>
   <content type="html">&lt;p&gt;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.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Binary downloads are available on &lt;a href='http://nlog.codeplex.com/releases/view/68535'&gt;CodePlex&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;Source code on &lt;a href='http://github.com/NLog/NLog'&gt;GitHub&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;Full release notes can be found &lt;a href='http://nlog-project.org/nlog-2-rc-release-notes.html'&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Exception logging enhancements</title>
   <link href="http://nlog-project.org/2011/04/20/exception-logging-enhancements.html"/>
   <updated>2011-04-20T00:00:00-07:00</updated>
   <id>http://nlog-project.org/2011/04/20/exception-logging-enhancements</id>
   <content type="html">&lt;p&gt;One of the frequent feature requests I&amp;#8217;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.&lt;/p&gt;

&lt;h2 id='conditional_formatting'&gt;Conditional formatting&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;${onexception:INNER} - output&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To render a layout when the exception is being logged, use &lt;strong&gt;${onexception:INNER}&lt;/strong&gt;, it will output INNER only when current log event includes an exception (in other words when it was emitted using any of the Logger.&lt;em&gt;Exception() methods. INNER can include other layouts, for example:&lt;/em&gt;&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='xml'&gt;&lt;span class='nt'&gt;&amp;lt;targets&amp;gt;&lt;/span&gt;
  &lt;span class='nt'&gt;&amp;lt;target&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;f&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;type=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;File&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;layout=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;${message}${onexception:EXCEPTION OCCURRED\:${exception:format=tostring}}&amp;quot;&lt;/span&gt; &lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;/targets&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It will output log message, but in case of exception, it will also log detailed exception information prefixed with &amp;#8220;EXCEPTION OCCURRED:&amp;#8221;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;${when} - advanced conditional formatting&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can also conditionally include or exclude layout renderers based on conditions by using &lt;strong&gt;${when}&lt;/strong&gt; layout renderer wrapper. You can even use ambient property called &amp;#8220;when&amp;#8221; as if it were declared on any other layout renderer:&lt;/p&gt;

&lt;p&gt;For example &lt;strong&gt;${message:when=logger==&amp;#8217;logger&amp;#8217;}&lt;/strong&gt; will only print the message when it was emitted by &amp;#8216;logger&amp;#8217;. The conditions can be much more complex - you have the full power of conditions language at your disposal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;${whenEmpty} - empty value coalescing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sometimes you may want to print an indication that a layout renderer has produced an empty value, instead of completely skipping its output. That&amp;#8217;s where &lt;strong&gt;${whenEmpty}&lt;/strong&gt; layout renderer wrapper comes in handy. You can also use the ambient property form, just by using &amp;#8216;whenEmpty&amp;#8217; property in any other layout renderer. For example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;${message:whenEmpty=(no message)}&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id='inner_exception_logging'&gt;Inner exception logging&lt;/h2&gt;

&lt;p&gt;Recent builds also include improvements to &lt;strong&gt;${exception}&lt;/strong&gt; layout renderer which now lets you output inner exceptions. There are several new properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;${exception:maxInnerExceptionLevel=N}&lt;/strong&gt; - controls how many inner exceptions are logged. defaults to zero for backwards compatibility.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;${exception:innerExceptionSeparator=TEXT}&lt;/strong&gt; - defines text that separates inner exceptions. Defaults to new line string (platform specific).&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;${exception:innerFormat=FORMATSTRING}&lt;/strong&gt; - defines the format of inner exceptions the same way that &lt;strong&gt;${exception:format=FORMATSTRING}&lt;/strong&gt; 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.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A complete usage example is:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='xml'&gt;&lt;span class='nt'&gt;&amp;lt;targets&amp;gt;&lt;/span&gt;
  &lt;span class='nt'&gt;&amp;lt;target&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;f&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;type=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;File&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;layout=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;${message}${onexception:EXCEPTION OCCURRED\:${exception:format=type,message,method:maxInnerExceptionLevel=5:innerFormat=shortType,message,method}}&amp;quot;&lt;/span&gt; &lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;/targets&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;As always, comments and suggestions are welcome.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Simplifying NLog.Extended.dll usage</title>
   <link href="http://nlog-project.org/2011/04/14/simplifying-nlog-extended-dll-usage.html"/>
   <updated>2011-04-14T00:00:00-07:00</updated>
   <id>http://nlog-project.org/2011/04/14/simplifying-nlog-extended-dll-usage</id>
   <content type="html">&lt;p&gt;I&amp;#8217;d like to let you know about small simplification to using targets and layout renderers from NLog.Extended.dll. Previously you had to register them using configuration section:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='xml'&gt;&lt;span class='nt'&gt;&amp;lt;extensions&amp;gt;&lt;/span&gt;
  &lt;span class='nt'&gt;&amp;lt;add&lt;/span&gt; &lt;span class='na'&gt;assembly=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;NLog.Extended&amp;quot;&lt;/span&gt; &lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;/extensions&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Starting with today&amp;#8217;s Nightly build, this is no longer required - you can simply use extended items without extra registration (exactly like it worked in NLog 1.0). The only change is that you must have NLog.Extended.dll in the same directory as NLog.dll - you will get exception if it&amp;#8217;s not present.&lt;/p&gt;

&lt;p&gt;If you need NLog.Extended, please &lt;a href='http://nlog-project.org/download'&gt;give this feature a try&lt;/a&gt; and report any issues you find.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>NLog for Windows Phone 7</title>
   <link href="http://nlog-project.org/2011/01/09/nlog-for-windows-phone-7.html"/>
   <updated>2011-01-09T00:00:00-08:00</updated>
   <id>http://nlog-project.org/2011/01/09/nlog-for-windows-phone-7</id>
   <content type="html">&lt;p&gt;This week I have checked in a port of NLog 2.0 for Windows Phone 7. It&amp;#8217;s still very experimental and the intention of this release is to get feedback from people. Please use at your own risk.&lt;/p&gt;

&lt;p&gt;Current build supports 8 targets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='https://github.com/NLog/NLog/wiki/Console-target'&gt;Console&lt;/a&gt; - can be used to write logs to the console (only works in Emulator - see this post for instruction on how to enable console output)&lt;/li&gt;

&lt;li&gt;&lt;a href='https://github.com/NLog/NLog/wiki/Memory-target'&gt;Memory&lt;/a&gt; - stores traces in memory&lt;/li&gt;

&lt;li&gt;&lt;a href='https://github.com/NLog/NLog/wiki/MethodCall-target'&gt;MethodCall&lt;/a&gt; - runs user-provided method for each log message&lt;/li&gt;

&lt;li&gt;&lt;a href='https://github.com/NLog/NLog/wiki/Network-target'&gt;Network&lt;/a&gt;, &lt;a href='https://github.com/NLog/NLog/wiki/NLogViewer-target'&gt;NLogViewer&lt;/a&gt; and &lt;a href='https://github.com/NLog/NLog/wiki/Chainsaw-target'&gt;Chainsaw&lt;/a&gt; - write XML-formatted log event over the network. Only HTTP:// and HTTPS:// protocols are supported.&lt;/li&gt;

&lt;li&gt;&lt;a href='https://github.com/NLog/NLog/wiki/WebService-target'&gt;WebService&lt;/a&gt; - sends log events to a web service using SOAP or POST&lt;/li&gt;

&lt;li&gt;&lt;a href='https://github.com/NLog/NLog/wiki/LogReceiverService-target'&gt;LogReceiverService&lt;/a&gt; - sends log events to LogReceiver web service using WCF&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that &lt;a href='https://github.com/NLog/NLog/wiki/File-target'&gt;File target&lt;/a&gt; and several others are not included because of current constraints of the platform APIs.&lt;/p&gt;

&lt;p&gt;Here is a simple step-by-step tutorial for adding NLog to your WP7 app:&lt;/p&gt;

&lt;h2 id='download_and_install_the_bits'&gt;Download and install the bits&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Go to &lt;a href='http://nlog.codeplex.com/releases'&gt;http://nlog.codeplex.com/releases&lt;/a&gt; and download one of the recent nightly builds - choose build later than 2011/1/9&lt;/li&gt;

&lt;li&gt;Pick a package named = NLog2-All-&lt;em&gt;.msi (includes builds for all platforms - recommended) or NLog2-WP-&lt;/em&gt;.msi (which includes only WP7 bits).&lt;/li&gt;

&lt;li&gt;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)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='add_nlog_to_your_windows_phone_app_project'&gt;Add NLog to your Windows Phone app project&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Open your project&lt;/li&gt;

&lt;li&gt;Add &lt;strong&gt;NLog.config&lt;/strong&gt; to your project - the easiest way is to select &amp;#8217;&lt;strong&gt;Add new item&lt;/strong&gt;&amp;#8217; and choose &amp;#8217;&lt;strong&gt;Empty NLog Configuration File&lt;/strong&gt;&amp;#8217; from the &amp;#8217;&lt;strong&gt;NLog&lt;/strong&gt;&amp;#8217; section.&lt;/li&gt;
&lt;/ul&gt;
&lt;img src='/images/posts/2011/01/NLogWP7AddNewItem.png' /&gt;
&lt;ul&gt;
&lt;li&gt;This will also add a reference to NLog:&lt;/li&gt;
&lt;/ul&gt;
&lt;img src='/images/posts/2011/01/NLogWP7WithReference_thumb.png' /&gt;
&lt;ul&gt;
&lt;li&gt;If you prefer, you manually add reference to &amp;#8221;&lt;strong&gt;C:\Program Files (x86)\NLog\Silverlight for Windows Phone 7\NLog.dll&lt;/strong&gt;&amp;#8221; instead and create &lt;strong&gt;NLog.config&lt;/strong&gt; manually&lt;/li&gt;

&lt;li&gt;One last thing is changing &lt;strong&gt;Build Action&lt;/strong&gt; for NLog.config to &amp;#8217;&lt;strong&gt;Content&lt;/strong&gt;&amp;#8217; (this ensures that the file will be included in the XAP package).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='set_logging_configuration'&gt;Set logging configuration&lt;/h2&gt;

&lt;p&gt;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:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='xml'&gt;&lt;span class='cp'&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;nlog&lt;/span&gt; &lt;span class='na'&gt;xmlns=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;http://www.nlog-project.org/schemas/NLog.xsd&amp;quot;&lt;/span&gt;
      &lt;span class='na'&gt;xmlns:xsi=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;

    &lt;span class='nt'&gt;&amp;lt;targets&amp;gt;&lt;/span&gt;
      &lt;span class='nt'&gt;&amp;lt;target&lt;/span&gt; &lt;span class='na'&gt;xsi:type=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;LogReceiverService&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;webService&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;endpointAddress=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;http://localhost:5000/LogReceiver.svc&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;/targets&amp;gt;&lt;/span&gt;

    &lt;span class='nt'&gt;&amp;lt;rules&amp;gt;&lt;/span&gt;
      &lt;span class='nt'&gt;&amp;lt;logger&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;*&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;minlevel=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;Debug&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;writeTo=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;webService&amp;quot;&lt;/span&gt; &lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;/rules&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;/nlog&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id='emit_log_messages'&gt;Emit log messages&lt;/h2&gt;

&lt;p&gt;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&amp;#8217;s add some logging code to MainPage.xaml.cs:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='csharp'&gt;&lt;span class='k'&gt;namespace&lt;/span&gt; &lt;span class='nn'&gt;WindowsPhoneApplication2&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;using&lt;/span&gt; &lt;span class='nn'&gt;System.Windows&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;using&lt;/span&gt; &lt;span class='nn'&gt;Microsoft.Phone.Controls&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

    &lt;span class='k'&gt;public&lt;/span&gt; &lt;span class='k'&gt;partial&lt;/span&gt; &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;MainPage&lt;/span&gt; &lt;span class='p'&gt;:&lt;/span&gt; &lt;span class='n'&gt;PhoneApplicationPage&lt;/span&gt;
    &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='k'&gt;private&lt;/span&gt; &lt;span class='k'&gt;static&lt;/span&gt; &lt;span class='n'&gt;NLog&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;Logger&lt;/span&gt; &lt;span class='n'&gt;logger&lt;/span&gt; &lt;span class='p'&gt;=&lt;/span&gt; &lt;span class='n'&gt;NLog&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;LogManager&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;GetCurrentClassLogger&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;

        &lt;span class='c1'&gt;// Constructor&lt;/span&gt;
        &lt;span class='k'&gt;public&lt;/span&gt; &lt;span class='nf'&gt;MainPage&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt;
        &lt;span class='p'&gt;{&lt;/span&gt;
            &lt;span class='n'&gt;InitializeComponent&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
            &lt;span class='n'&gt;logger&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;Info&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;Main page loaded.&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
        &lt;span class='p'&gt;}&lt;/span&gt;

        &lt;span class='k'&gt;private&lt;/span&gt; &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;button1_Click&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;object&lt;/span&gt; &lt;span class='n'&gt;sender&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;RoutedEventArgs&lt;/span&gt; &lt;span class='n'&gt;e&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='p'&gt;{&lt;/span&gt;
            &lt;span class='n'&gt;logger&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;Debug&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;Button 1 clicked.&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
        &lt;span class='p'&gt;}&lt;/span&gt;

        &lt;span class='k'&gt;private&lt;/span&gt; &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;button2_Click&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;object&lt;/span&gt; &lt;span class='n'&gt;sender&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;RoutedEventArgs&lt;/span&gt; &lt;span class='n'&gt;e&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='p'&gt;{&lt;/span&gt;
            &lt;span class='n'&gt;logger&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;Debug&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;Button 2 clicked.&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
        &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When you run the code, log messages will be sent to http://localhost:5000/LogReceiver.svc&lt;/p&gt;

&lt;h2 id='receive_log_messages'&gt;Receive log messages&lt;/h2&gt;

&lt;p&gt;In order to receive log messages you need to have an endpoint that implements &lt;strong&gt;ILogReceiverServer&lt;/strong&gt; 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 &lt;strong&gt;examples\NLogReceiverForwarderService&lt;/strong&gt;. The sample will basically forward NLog messages received from the network through NLog running on the server machine.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download NLog source code&lt;/li&gt;

&lt;li&gt;Open the project file &lt;strong&gt;examples\NLogReceiverForwarderService\NLogReceiverForwarderService.csproj&lt;/strong&gt; (Visual Studio needs to be running as an Administrator)&lt;/li&gt;

&lt;li&gt;Edit NLog.config and adjust log outputs as necessary.&lt;/li&gt;

&lt;li&gt;Run the project. Notice how when you click on buttons in your Windows Phone 7 application, the logs are displayed on your console:&lt;/li&gt;
&lt;/ul&gt;
&lt;img src='/images/posts/2011/01/LogForwarderOutput_thumb.png' /&gt;
&lt;h2 id='lets_do_more'&gt;Let&amp;#8217;s do more&amp;#8230;&lt;/h2&gt;

&lt;p&gt;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&amp;#8217;ll be using parameters. Let&amp;#8217;s modify client side configuration to send thread id along with each log message:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='xml'&gt;&lt;span class='cp'&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;nlog&lt;/span&gt; &lt;span class='na'&gt;xmlns=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;http://www.nlog-project.org/schemas/NLog.xsd&amp;quot;&lt;/span&gt;
      &lt;span class='na'&gt;xmlns:xsi=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;

    &lt;span class='nt'&gt;&amp;lt;targets&amp;gt;&lt;/span&gt;
      &lt;span class='nt'&gt;&amp;lt;target&lt;/span&gt; &lt;span class='na'&gt;xsi:type=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;LogReceiverService&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;webService&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;endpointAddress=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;http://localhost:5000/LogReceiver.svc&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;
        &lt;span class='nt'&gt;&amp;lt;parameter&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;t&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;layout=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;${threadid}&amp;quot;&lt;/span&gt; &lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class='nt'&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;/targets&amp;gt;&lt;/span&gt;

    &lt;span class='nt'&gt;&amp;lt;rules&amp;gt;&lt;/span&gt;
      &lt;span class='nt'&gt;&amp;lt;logger&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;*&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;minlevel=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;Debug&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;writeTo=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;webService&amp;quot;&lt;/span&gt; &lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;/rules&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;/nlog&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;On the server side, we can now extract &amp;#8216;t&amp;#8217; parameter using &lt;a href='https://github.com/NLog/NLog/wiki/EventContext-Layout-Renderer'&gt;${event-context} layout renderer&lt;/a&gt;. Let&amp;#8217;s also add timestamp to each message:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='xml'&gt;&lt;span class='cp'&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;nlog&lt;/span&gt; &lt;span class='na'&gt;xmlns=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;http://www.nlog-project.org/schemas/NLog.xsd&amp;quot;&lt;/span&gt;
      &lt;span class='na'&gt;xmlns:xsi=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;

    &lt;span class='nt'&gt;&amp;lt;targets&amp;gt;&lt;/span&gt;
        &lt;span class='nt'&gt;&amp;lt;target&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;console&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;xsi:type=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;Console&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;layout=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;${longdate} ${message} ${event-context:t}&amp;quot;&lt;/span&gt; &lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;/targets&amp;gt;&lt;/span&gt;

    &lt;span class='nt'&gt;&amp;lt;rules&amp;gt;&lt;/span&gt;
        &lt;span class='nt'&gt;&amp;lt;logger&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;*&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;minlevel=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;Debug&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;writeTo=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;console&amp;quot;&lt;/span&gt; &lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;/rules&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;/nlog&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;img src='/images/posts/2011/01/LogForwarderOutput2_thumb.png' /&gt;
&lt;p&gt;I would love to hear your feedback about this build and using NLog in Windows Phone 7 applications in general. Please use &lt;a href='http://nlog-project.org/forum'&gt;Forum&lt;/a&gt; for any questions or suggestions or &lt;a href='http://nlog-project.org/issuetracker'&gt;Issue Tracker&lt;/a&gt; if something does not work correctly.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>NLog 2.0 Beta 1 has been released</title>
   <link href="http://nlog-project.org/2010/09/26/nlog-2-0-beta-1-has-been-released.html"/>
   <updated>2010-09-26T00:00:00-07:00</updated>
   <id>http://nlog-project.org/2010/09/26/nlog-2-0-beta-1-has-been-released</id>
   <content type="html">&lt;p&gt;It is my pleasure to announce that NLog 2.0 Beta 1 has been released.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;The following platforms are supported in this release:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;.NET Framework 2.0 SP1 and above, 3.5 (Client and Extended profiles), 4.0 (Client and Extended profiles)&lt;/li&gt;

&lt;li&gt;Silverlight 2.0, 3.0, 4.0&lt;/li&gt;

&lt;li&gt;.NET Compact Framework 2.0, 3.5&lt;/li&gt;

&lt;li&gt;Mono 2.x profile&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Read full release notes: &lt;a href='http://nlog-project.org/nlog2-beta1-release-notes.html'&gt;http://nlog-project.org/nlog2-beta1-release-notes.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Download Beta 1 bits on CodePlex: &lt;a href='http://nlog.codeplex.com/releases/view/52957'&gt;http://nlog.codeplex.com/releases/view/52957&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Source code is available on GitHub: &lt;a href='http://github.com/jkowalski/NLog/'&gt;http://github.com/jkowalski/NLog/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bugs can be reported on CodePlex: &lt;a href='http://nlog.codeplex.com/workitem/list/basic'&gt;http://nlog.codeplex.com/workitem/list/basic&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Discuss on forum: &lt;a href='http://nlog-project.org/forum'&gt;http://nlog-project.org/forum&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Subscribe to NLog RSS feed: &lt;a href='http://nlog-project.org/feed'&gt;http://nlog-project.org/feed&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Follow @JarekKowalski on Twitter: &lt;a href='http://twitter.com/JarekKowalski'&gt;http://twitter.com/JarekKowalski&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Deploying NLog configuration files</title>
   <link href="http://nlog-project.org/2010/09/25/deploying-nlog-configuration.html"/>
   <updated>2010-09-25T00:00:00-07:00</updated>
   <id>http://nlog-project.org/2010/09/25/deploying-nlog-configuration</id>
   <content type="html">&lt;p&gt;Some of the &lt;a href='https://github.com/NLog/NLog/wiki/Targets'&gt;targets&lt;/a&gt; supported by NLog require installation to be performed on the machine before the target can be used. For example, when logging to a &lt;a href='https://github.com/NLog/NLog/wiki/Database-target'&gt;database&lt;/a&gt;, a DBA needs to create the necessary tables, when logging to &lt;a href='https://github.com/NLog/NLog/wiki/EventLog-target'&gt;event log&lt;/a&gt; or &lt;a href='https://github.com/NLog/NLog/wiki/PerfCounter-target'&gt;performance counter&lt;/a&gt;, administrator of the machine must create them before the application can write to them.&lt;/p&gt;

&lt;p&gt;NLog 2.0 comes with a new tool and APIs that lets you manage installation and uninstallation of objects which support logging.&lt;/p&gt;

&lt;p&gt;Say you want to write logs to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;local SQLEXPRESS database&lt;/li&gt;

&lt;li&gt;Event Log on the local machine&lt;/li&gt;

&lt;li&gt;increase performance counter each time log message occurs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With NLog 2.0, you can embed installation/uninstallations steps directly in the log configuration file, like in the following example:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='xml'&gt;&lt;span class='cp'&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;nlog&lt;/span&gt; &lt;span class='na'&gt;xmlns=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;http://www.nlog-project.org/schemas/NLog.xsd&amp;quot;&lt;/span&gt;
      &lt;span class='na'&gt;xmlns:xsi=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;
  &lt;span class='nt'&gt;&amp;lt;targets&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;target&lt;/span&gt; &lt;span class='na'&gt;xsi:type=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;Database&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;db&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;
      &lt;span class='c'&gt;&amp;lt;!-- SQL command to be executed for each entry --&amp;gt;&lt;/span&gt;
      &lt;span class='nt'&gt;&amp;lt;commandText&amp;gt;&lt;/span&gt;INSERT INTO [LogEntries](TimeStamp, Message, Level, Logger) VALUES(getutcdate(), @msg, @level, @logger)&lt;span class='nt'&gt;&amp;lt;/commandText&amp;gt;&lt;/span&gt;

      &lt;span class='c'&gt;&amp;lt;!-- parameters for the command --&amp;gt;&lt;/span&gt;
      &lt;span class='nt'&gt;&amp;lt;parameter&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;@msg&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;layout=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;${message}&amp;quot;&lt;/span&gt; &lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class='nt'&gt;&amp;lt;parameter&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;@level&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;layout=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;${level}&amp;quot;&lt;/span&gt; &lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class='nt'&gt;&amp;lt;parameter&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;@logger&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;layout=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;${logger}&amp;quot;&lt;/span&gt; &lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;

      &lt;span class='c'&gt;&amp;lt;!-- connection string --&amp;gt;&lt;/span&gt;
      &lt;span class='nt'&gt;&amp;lt;dbProvider&amp;gt;&lt;/span&gt;System.Data.SqlClient&lt;span class='nt'&gt;&amp;lt;/dbProvider&amp;gt;&lt;/span&gt;
      &lt;span class='nt'&gt;&amp;lt;connectionString&amp;gt;&lt;/span&gt;server=.\SQLEXPRESS;database=MyLogs;integrated security=sspi&lt;span class='nt'&gt;&amp;lt;/connectionString&amp;gt;&lt;/span&gt;

      &lt;span class='c'&gt;&amp;lt;!-- commands to install database --&amp;gt;&lt;/span&gt;
      &lt;span class='nt'&gt;&amp;lt;install-command&amp;gt;&lt;/span&gt;
        &lt;span class='nt'&gt;&amp;lt;text&amp;gt;&lt;/span&gt;CREATE DATABASE MyLogs&lt;span class='nt'&gt;&amp;lt;/text&amp;gt;&lt;/span&gt;
        &lt;span class='nt'&gt;&amp;lt;connectionString&amp;gt;&lt;/span&gt;server=.\SQLEXPRESS;database=master;integrated security=sspi&lt;span class='nt'&gt;&amp;lt;/connectionString&amp;gt;&lt;/span&gt;
        &lt;span class='nt'&gt;&amp;lt;ignoreFailures&amp;gt;&lt;/span&gt;true&lt;span class='nt'&gt;&amp;lt;/ignoreFailures&amp;gt;&lt;/span&gt;
      &lt;span class='nt'&gt;&amp;lt;/install-command&amp;gt;&lt;/span&gt;

      &lt;span class='nt'&gt;&amp;lt;install-command&amp;gt;&lt;/span&gt;
        &lt;span class='nt'&gt;&amp;lt;text&amp;gt;&lt;/span&gt;
          CREATE TABLE LogEntries(
          id int primary key not null identity(1,1),
          TimeStamp datetime2,
          Message nvarchar(max),
          level nvarchar(10),
          logger nvarchar(128))
        &lt;span class='nt'&gt;&amp;lt;/text&amp;gt;&lt;/span&gt;
      &lt;span class='nt'&gt;&amp;lt;/install-command&amp;gt;&lt;/span&gt;

      &lt;span class='c'&gt;&amp;lt;!-- commands to uninstall database --&amp;gt;&lt;/span&gt;
      &lt;span class='nt'&gt;&amp;lt;uninstall-command&amp;gt;&lt;/span&gt;
        &lt;span class='nt'&gt;&amp;lt;text&amp;gt;&lt;/span&gt;DROP DATABASE MyLogs&lt;span class='nt'&gt;&amp;lt;/text&amp;gt;&lt;/span&gt;
        &lt;span class='nt'&gt;&amp;lt;connectionString&amp;gt;&lt;/span&gt;server=.\SQLEXPRESS;database=master;integrated security=sspi&lt;span class='nt'&gt;&amp;lt;/connectionString&amp;gt;&lt;/span&gt;
        &lt;span class='nt'&gt;&amp;lt;ignoreFailures&amp;gt;&lt;/span&gt;true&lt;span class='nt'&gt;&amp;lt;/ignoreFailures&amp;gt;&lt;/span&gt;
      &lt;span class='nt'&gt;&amp;lt;/uninstall-command&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;

    &lt;span class='nt'&gt;&amp;lt;target&lt;/span&gt; &lt;span class='na'&gt;xsi:type=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;EventLog&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;eventLog&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;source=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;NLog Demo&amp;quot;&lt;/span&gt;
            &lt;span class='na'&gt;layout=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;${message}${newline}Call site: ${callsite:className=true:methodName=true}${newline}Logger: ${logger}&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;

    &lt;span class='nt'&gt;&amp;lt;target&lt;/span&gt; &lt;span class='na'&gt;xsi:type=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;PerfCounter&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;pc1&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;categoryName=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;My Log&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;counterName=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;My Counter&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;

  &lt;span class='nt'&gt;&amp;lt;rules&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;logger&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;*&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;minlevel=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;Trace&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;writeTo=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;db,eventLog,pc1&amp;quot;&lt;/span&gt; &lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class='nt'&gt;&amp;lt;/rules&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;/nlog&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In order to deploy the database, event log and performance counter, you can use simply use InstallNLogConfig.exe tool that comes with NLog. Open elevated command prompt and run the following command:&lt;/p&gt;
&lt;pre&gt;
&gt; InstallNLogConfig.exe c:\path\to\NLog.config
Installing 'Database Target[db]'
Finished installing 'Database Target[db]'.
Installing 'EventLog Target[eventLog]'
Finished installing 'EventLog Target[eventLog]'.
Installing 'PerfCounter Target[pc1]'
Finished installing 'PerfCounter Target[pc1]'.
&lt;/pre&gt;
&lt;p&gt;Uninstalling is equally easy:&lt;/p&gt;
&lt;pre&gt;
&gt; InstallNLogConfig.exe&quot; -u c:\path\to\NLog.config 
Uninstalling 'Database Target[db]' 
Finished uninstalling 'Database Target[db]'. 
Uninstalling 'EventLog Target[eventLog]' 
Finished uninstalling 'EventLog Target[eventLog]'. 
Uninstalling 'PerfCounter Target[pc1]' 
Finished uninstalling 'PerfCounter Target[pc1]'.
&lt;/pre&gt;
&lt;h2 id='passing_parameters_to_installation'&gt;Passing parameters to installation&lt;/h2&gt;

&lt;p&gt;Sometimes there is a need to pass parameters to the installation routing, which should not be normally visible in the NLog.config file. One example might be DBA username and password for connecting to the database. You can pass parameters on the command line by using –p NAME=VALUE option:&lt;/p&gt;
&lt;pre&gt;
&gt; InstallNLogConfig.exe&quot; –p ADMIN_USER=sa –p ADMIN_PASSWORD=megaSecret1234 c:\path\to\NLog.config 
&lt;/pre&gt;
&lt;p&gt;The parameters are accessible using &lt;a href='https://github.com/NLog/NLog/wiki/InstallContext-Layout-Renderer'&gt;${install-context} layout renderer&lt;/a&gt;. For example, we can easily modify the above example to use SQL authentication where user name and password are passed from command line:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='xml'&gt;&lt;span class='nt'&gt;&amp;lt;install-command&amp;gt;&lt;/span&gt;
  &lt;span class='nt'&gt;&amp;lt;text&amp;gt;&lt;/span&gt;CREATE DATABASE MyLogs&lt;span class='nt'&gt;&amp;lt;/text&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;connectionString&amp;gt;&lt;/span&gt;server=.\SQLEXPRESS;database=master;
                      user id=${install-context:ADMIN_USER};password=${install-context:PASSWORD}&lt;span class='nt'&gt;&amp;lt;/connectionString&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;ignoreFailures&amp;gt;&lt;/span&gt;true&lt;span class='nt'&gt;&amp;lt;/ignoreFailures&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;/install-command&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id='installation_api'&gt;Installation API&lt;/h2&gt;

&lt;p&gt;In order to install logging configuration, you can simply use Install() and Uninstall() methods on LoggingConfiguration object. They both take InstallationContext arguments, which can be used pass parameters and specify logging and other options:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='csharp'&gt;&lt;span class='k'&gt;namespace&lt;/span&gt; &lt;span class='nn'&gt;NLog.Config&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;public&lt;/span&gt; &lt;span class='k'&gt;sealed&lt;/span&gt; &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;InstallationContext&lt;/span&gt; &lt;span class='p'&gt;:&lt;/span&gt; &lt;span class='n'&gt;IDisposable&lt;/span&gt;
    &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='c1'&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span class='c1'&gt;/// Gets or sets the installation log level.&lt;/span&gt;
        &lt;span class='c1'&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span class='k'&gt;public&lt;/span&gt; &lt;span class='n'&gt;LogLevel&lt;/span&gt; &lt;span class='n'&gt;LogLevel&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='k'&gt;get&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='k'&gt;set&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;

        &lt;span class='c1'&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span class='c1'&gt;/// Gets or sets a value indicating whether to ignore failures during installation.&lt;/span&gt;
        &lt;span class='c1'&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span class='k'&gt;public&lt;/span&gt; &lt;span class='kt'&gt;bool&lt;/span&gt; &lt;span class='n'&gt;IgnoreFailures&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='k'&gt;get&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='k'&gt;set&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;

        &lt;span class='c1'&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span class='c1'&gt;/// Gets the installation parameters.&lt;/span&gt;
        &lt;span class='c1'&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span class='k'&gt;public&lt;/span&gt; &lt;span class='n'&gt;IDictionary&lt;/span&gt;&lt;span class='p'&gt;&amp;lt;&lt;/span&gt;&lt;span class='kt'&gt;string&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kt'&gt;string&lt;/span&gt;&lt;span class='p'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;Parameters&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='k'&gt;get&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='k'&gt;private&lt;/span&gt; &lt;span class='k'&gt;set&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;

        &lt;span class='c1'&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span class='c1'&gt;/// Gets or sets the log output.&lt;/span&gt;
        &lt;span class='c1'&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span class='k'&gt;public&lt;/span&gt; &lt;span class='n'&gt;TextWriter&lt;/span&gt; &lt;span class='n'&gt;LogOutput&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='k'&gt;get&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='k'&gt;set&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Typical installation code will look like this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='csharp'&gt;&lt;span class='k'&gt;using&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;var&lt;/span&gt; &lt;span class='n'&gt;context&lt;/span&gt; &lt;span class='p'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='n'&gt;InstallationContext&lt;/span&gt;&lt;span class='p'&gt;())&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='kt'&gt;var&lt;/span&gt; &lt;span class='n'&gt;config&lt;/span&gt; &lt;span class='p'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='n'&gt;XmlLoggingConfiguration&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;NLog.config&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;

  &lt;span class='c1'&gt;// output detailed installation logs&lt;/span&gt;
  &lt;span class='n'&gt;context&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;LogLevel&lt;/span&gt; &lt;span class='p'&gt;=&lt;/span&gt; &lt;span class='n'&gt;LogLevel&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;Trace&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

  &lt;span class='n'&gt;context&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;Parameters&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;ADMIN_USER&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='p'&gt;=&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;sa&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='n'&gt;context&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;Parameters&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;ADMIN_PASSWORD&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='p'&gt;=&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;megaSecret1234&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

  &lt;span class='c1'&gt;// write logs to a log file&lt;/span&gt;
  &lt;span class='k'&gt;using&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;var&lt;/span&gt; &lt;span class='n'&gt;logFile&lt;/span&gt; &lt;span class='p'&gt;=&lt;/span&gt; &lt;span class='n'&gt;File&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;CreateText&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;InstallLog.txt&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
  &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='n'&gt;context&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;LogOutput&lt;/span&gt; &lt;span class='p'&gt;=&lt;/span&gt; &lt;span class='n'&gt;logFile&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

    &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;Install&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;context&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;  
  &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In order to support custom installation in your target or any other configuration item (such as layout, filter, etc.), you simply need to implement IIinstallable interface:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='csharp'&gt;&lt;span class='k'&gt;public&lt;/span&gt; &lt;span class='k'&gt;interface&lt;/span&gt; &lt;span class='n'&gt;IInstallable&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;Install&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;InstallationContext&lt;/span&gt; &lt;span class='n'&gt;installationContext&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;Uninstall&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;InstallationContext&lt;/span&gt; &lt;span class='n'&gt;installationContext&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='kt'&gt;bool?&lt;/span&gt; &lt;span class='n'&gt;IsInstalled&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;InstallationContext&lt;/span&gt; &lt;span class='n'&gt;installationContext&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;See &lt;a href='http://github.com/NLog/NLog/blob/master/src/NLog/Targets/DatabaseTarget.cs'&gt;DatabaseTarget&lt;/a&gt; sources for example implementation.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>New exception handling rules in NLog 2.0</title>
   <link href="http://nlog-project.org/2010/09/05/new-exception-handling-rules-in-nlog-2-0.html"/>
   <updated>2010-09-05T00:00:00-07:00</updated>
   <id>http://nlog-project.org/2010/09/05/new-exception-handling-rules-in-nlog-2-0</id>
   <content type="html">&lt;p&gt;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&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='xml'&gt;&lt;span class='nt'&gt;&amp;lt;nlog&lt;/span&gt; &lt;span class='na'&gt;throwExceptions=&lt;/span&gt;&lt;span class='s'&gt;”true”&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;

&lt;span class='nt'&gt;&amp;lt;/nlog&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;or in code:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='csharp'&gt;&lt;span class='n'&gt;LogManager&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;ThrowExceptions&lt;/span&gt; &lt;span class='p'&gt;=&lt;/span&gt; &lt;span class='k'&gt;true&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;To address this, NLog 2.0 will treat configuration errors separately from runtime errors. There will be two kinds of exceptions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Configuration exceptions - raised during parsing of &lt;a href='https://github.com/NLog/NLog/wiki/Configuration-file'&gt;configuration file&lt;/a&gt; and wrapped in &lt;strong&gt;NLogConfigurationException&lt;/strong&gt;. 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:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;syntax errors in NLog.config&lt;/li&gt;

&lt;li&gt;invalid target names&lt;/li&gt;

&lt;li&gt;invalid property names&lt;/li&gt;

&lt;li&gt;invalid property values&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Runtime exceptions (such as permission issues, connection failures, etc.) - raised during logging and initialization and wrapped in &lt;strong&gt;NLogRuntimeException&lt;/strong&gt;. They can be controlled by &lt;strong&gt;throwExceptions&lt;/strong&gt; flag.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I would love to hear your comments.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Routing System.Diagnostics.Trace and System.Diagnostics.TraceSource logs through NLog</title>
   <link href="http://nlog-project.org/2010/09/02/routing-system-diagnostics-trace-and-system-diagnostics-tracesource-logs-through-nlog.html"/>
   <updated>2010-09-02T00:00:00-07:00</updated>
   <id>http://nlog-project.org/2010/09/02/routing-system-diagnostics-trace-and-system-diagnostics-tracesource-logs-through-nlog</id>
   <content type="html">&lt;p&gt;I have recently added a trace listener class for NLog, which enables routing of System.Diagnostics.Trace and System.Diagnostics.TraceSource logs through your favorite log routing engine. This can be very useful for integrating components that don’t necessarily support logging through NLog as well as analyzing traces produced .NET Framework itself.&lt;/p&gt;

&lt;p&gt;By using NLog trace listener you can send those logs via &lt;a href='https://github.com/NLog/NLog/wiki/Mail-target'&gt;email&lt;/a&gt;, save them to a &lt;a href='https://github.com/NLog/NLog/wiki/Database-target'&gt;database&lt;/a&gt;, &lt;a href='https://github.com/NLog/NLog/wiki/File-target'&gt;file&lt;/a&gt; or to any other supported log &lt;a href='https://github.com/NLog/NLog/wiki/Targets'&gt;targets&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let’s create a simple example – application that makes network call. We will then enable network call tracing without touching a single line of code.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='csharp'&gt;&lt;span class='k'&gt;namespace&lt;/span&gt; &lt;span class='nn'&gt;TraceDemo&lt;/span&gt; 
&lt;span class='p'&gt;{&lt;/span&gt; 
  &lt;span class='k'&gt;using&lt;/span&gt; &lt;span class='nn'&gt;System.Net&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; 

  &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;Program&lt;/span&gt; 
  &lt;span class='p'&gt;{&lt;/span&gt; 
    &lt;span class='k'&gt;static&lt;/span&gt; &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;Main&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;string&lt;/span&gt;&lt;span class='p'&gt;[]&lt;/span&gt; &lt;span class='n'&gt;args&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; 
    &lt;span class='p'&gt;{&lt;/span&gt; 
      &lt;span class='kt'&gt;var&lt;/span&gt; &lt;span class='n'&gt;webClient&lt;/span&gt; &lt;span class='p'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='n'&gt;WebClient&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt; 
      &lt;span class='n'&gt;webClient&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;DownloadString&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;http://somehost/nosuchfile.txt&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; 
    &lt;span class='p'&gt;}&lt;/span&gt; 
  &lt;span class='p'&gt;}&lt;/span&gt; 
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see the example is just using WebClient from System.Net namespace, and has no tracing-specific code. Internally WebClient is capable of outputting traces through &lt;strong&gt;System.Net&lt;/strong&gt; trace source. To route those traces through NLog you need to assign a listener to each source in the application configuration file. It is convenient to define NLogTraceListener as a shared listener and reference by name in all sources that you need as in the following example:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='xml'&gt;&lt;span class='cp'&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
  &lt;span class='nt'&gt;&amp;lt;system.diagnostics&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;sources&amp;gt;&lt;/span&gt;
      &lt;span class='nt'&gt;&amp;lt;source&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;System.Net&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;switchValue=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;All&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;
        &lt;span class='nt'&gt;&amp;lt;listeners&amp;gt;&lt;/span&gt;
          &lt;span class='nt'&gt;&amp;lt;add&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;nlog&amp;quot;&lt;/span&gt; &lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class='nt'&gt;&amp;lt;/listeners&amp;gt;&lt;/span&gt;
      &lt;span class='nt'&gt;&amp;lt;/source&amp;gt;&lt;/span&gt;
      &lt;span class='nt'&gt;&amp;lt;source&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;System.Net.Sockets&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;switchValue=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;All&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;
        &lt;span class='nt'&gt;&amp;lt;listeners&amp;gt;&lt;/span&gt;
          &lt;span class='nt'&gt;&amp;lt;add&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;nlog&amp;quot;&lt;/span&gt; &lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class='nt'&gt;&amp;lt;/listeners&amp;gt;&lt;/span&gt;
      &lt;span class='nt'&gt;&amp;lt;/source&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;/sources&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;sharedListeners&amp;gt;&lt;/span&gt;
      &lt;span class='nt'&gt;&amp;lt;add&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;nlog&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;type=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;NLog.NLogTraceListener, NLog&amp;quot;&lt;/span&gt; &lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;/sharedListeners&amp;gt;&lt;/span&gt;
  &lt;span class='nt'&gt;&amp;lt;/system.diagnostics&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Obviously you also need NLog.dll and &lt;a href='https://github.com/NLog/NLog/wiki/Configuration-file'&gt;NLog.config&lt;/a&gt; to be located in the application directory. For our purposes we’ll use simple configuration with single target:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='xml'&gt;&lt;span class='nt'&gt;&amp;lt;nlog&amp;gt;&lt;/span&gt;
  &lt;span class='nt'&gt;&amp;lt;targets&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;target&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;console&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;type=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;ColoredConsole&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;layout=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;${longdate} ${windows-identity} ${message}&amp;quot;&lt;/span&gt; &lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class='nt'&gt;&amp;lt;/targets&amp;gt;&lt;/span&gt;

  &lt;span class='nt'&gt;&amp;lt;rules&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;logger&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;*&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;minlevel=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;Trace&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;writeTo=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;console&amp;quot;&lt;/span&gt; &lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class='nt'&gt;&amp;lt;/rules&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;/nlog&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When you run this application, you will get nice color-coded trace that includes lots of diagnostics information straight from the guts of .NET Framework. Having access to detailed trace like this can be very helpful in diagnosing hard-to-reproduce problems that are often impossible to figure out with a debugger.&lt;/p&gt;
&lt;img src='/images/posts/2010/09/image_thumb1.png' /&gt;</content>
 </entry>
 
 <entry>
   <title>Intellisense for NLog configuration files</title>
   <link href="http://nlog-project.org/2010/06/30/intellisense-for-nlog-configuration-files.html"/>
   <updated>2010-06-30T00:00:00-07:00</updated>
   <id>http://nlog-project.org/2010/06/30/intellisense-for-nlog-configuration-files</id>
   <content type="html">&lt;p&gt;I have recently updated tools to build &lt;strong&gt;NLog.xsd&lt;/strong&gt; 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.&lt;/p&gt;
&lt;table cellspacing='0' border='1' cellpadding='2' width='724'&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td valign='top' width='138'&gt;&lt;strong&gt;File Name&lt;/strong&gt;&lt;/td&gt;
&lt;td valign='top' width='394'&gt;&lt;strong&gt;XML Namespace&lt;/strong&gt;&lt;/td&gt;
&lt;td valign='top' width='190'&gt;&lt;strong&gt;Frameworks&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign='top' width='142'&gt;NLog.xsd&lt;/td&gt;
&lt;td valign='top' width='392'&gt;&lt;a href='http://www.nlog-project.org/schemas/NLog.xsd'&gt;http://www.nlog-project.org/schemas/NLog.xsd&lt;/a&gt;&lt;/td&gt;
&lt;td valign='top' width='189'&gt;(all frameworks)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign='top' width='145'&gt;NLog.Mono2.xsd&lt;/td&gt;
&lt;td valign='top' width='390'&gt;&lt;a href='http://www.nlog-project.org/schemas/NLog.mono2.xsd'&gt;http://www.nlog-project.org/schemas/NLog.mono2.xsd&lt;/a&gt;&lt;/td&gt;
&lt;td valign='top' width='188'&gt;Mono 2.x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign='top' width='148'&gt;NLog.NetCf20.xsd&lt;/td&gt;
&lt;td valign='top' width='389'&gt;&lt;a href='http://www.nlog-project.org/schemas/NLog.netcf20.xsd'&gt;http://www.nlog-project.org/schemas/NLog.netcf20.xsd&lt;/a&gt;&lt;/td&gt;
&lt;td valign='top' width='187'&gt;.NET Compact Framework 2.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign='top' width='150'&gt;NLog.NetCf35.xsd&lt;/td&gt;
&lt;td valign='top' width='388'&gt;&lt;a href='http://www.nlog-project.org/schemas/NLog.netcf35.xsd'&gt;http://www.nlog-project.org/schemas/NLog.netcf35.xsd&lt;/a&gt;&lt;/td&gt;
&lt;td valign='top' width='186'&gt;.NET Compact Framework 3.5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign='top' width='152'&gt;NLog.NetFx20.xsd&lt;/td&gt;
&lt;td valign='top' width='387'&gt;&lt;a href='http://www.nlog-project.org/schemas/NLog.netfx20.xsd'&gt;http://www.nlog-project.org/schemas/NLog.netfx20.xsd&lt;/a&gt;&lt;/td&gt;
&lt;td valign='top' width='186'&gt;.NET Framework 2.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign='top' width='153'&gt;NLog.NetFx35.xsd&lt;/td&gt;
&lt;td valign='top' width='387'&gt;&lt;a href='http://www.nlog-project.org/schemas/NLog.netfx35.xsd'&gt;http://www.nlog-project.org/schemas/NLog.netfx35.xsd&lt;/a&gt;&lt;/td&gt;
&lt;td valign='top' width='185'&gt;.NET Framework 3.5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign='top' width='154'&gt;NLog.NetFx40.xsd&lt;/td&gt;
&lt;td valign='top' width='386'&gt;&lt;a href='http://www.nlog-project.org/schemas/NLog.netfx40.xsd'&gt;http://www.nlog-project.org/schemas/NLog.netfx40.xsd&lt;/a&gt;&lt;/td&gt;
&lt;td valign='top' width='185'&gt;.NET Framework 4.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign='top' width='155'&gt;NLog.SL2.xsd&lt;/td&gt;
&lt;td valign='top' width='386'&gt;&lt;a href='http://www.nlog-project.org/schemas/NLog.sl2.xsd'&gt;http://www.nlog-project.org/schemas/NLog.sl2.xsd&lt;/a&gt;&lt;/td&gt;
&lt;td valign='top' width='185'&gt;Silverlight 2.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign='top' width='156'&gt;NLog.SL3.xsd&lt;/td&gt;
&lt;td valign='top' width='385'&gt;&lt;a href='http://www.nlog-project.org/schemas/NLog.sl3.xsd'&gt;http://www.nlog-project.org/schemas/NLog.sl3.xsd&lt;/a&gt;&lt;/td&gt;
&lt;td valign='top' width='184'&gt;Silverlight 3.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign='top' width='156'&gt;NLog.SL4.xsd&lt;/td&gt;
&lt;td valign='top' width='385'&gt;&lt;a href='http://www.nlog-project.org/schemas/NLog.sl4.xsd'&gt;http://www.nlog-project.org/schemas/NLog.sl4.xsd&lt;/a&gt;&lt;/td&gt;
&lt;td valign='top' width='186'&gt;Silverlight 4.0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;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.&lt;/p&gt;

&lt;h2 id='intellisense_in_action'&gt;Intellisense In Action&lt;/h2&gt;

&lt;p&gt;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)&lt;/p&gt;
&lt;img src='/images/posts/2010/06/image.png' /&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;img src='/images/posts/2010/06/image1.png' /&gt;
&lt;p&gt;This also works for individual properties. For example, &lt;a href='https://github.com/NLog/NLog/wiki/LogReceiverService-target'&gt;LogReceiverService&lt;/a&gt; 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.&lt;/p&gt;
&lt;img src='/images/posts/2010/06/image2.png' /&gt;
&lt;p&gt;XSD schemas also provide help when editing NLog.config files:&lt;/p&gt;
&lt;img src='/images/posts/2010/06/image_thumb.png' /&gt;
&lt;h2 id='customizing_xsd_schemas'&gt;Customizing XSD Schemas&lt;/h2&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;p&gt;The first step is to download and unpack NLog sources (from &lt;a href='http://github.com/NLog/NLog/'&gt;GitHub&lt;/a&gt; or zip package) and build everything by running:&lt;/p&gt;
&lt;pre&gt;
build.cmd build xsd
&lt;/pre&gt;
&lt;p&gt;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 &lt;a href='http://nlog-project.org/2010/03/22/nlog-2-0-build-and-release-process-explained.html'&gt;here&lt;/a&gt;. We must run it on our extensions assembly and pass it directory (or directories) where all reference assemblies are located.&lt;/p&gt;
&lt;pre&gt;
&amp;lt;nlog-dir&amp;gt;\tools\DumpApiXml\bin\Debug\DumpApiXml.exe -assembly  &amp;lt;path&amp;gt;\SampleExtensions.dll
  -ref &quot;D:\Work\NLog\build\bin\Debug\.NET Framework 4.0&quot; -output &amp;lt;path&amp;gt;\SampleExtensions.api
&lt;/pre&gt;
&lt;p&gt;Once we have the SampleExtensions.api project, we need to convert it to XSD using MakeNLogXSD. It accepts multiple &lt;em&gt;.api files and can produce XSD files with custom namespaces:&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;
&amp;lt;nlog-dir&amp;gt;\tools\MakeNLogXSD\bin\Debug\MakeNLogXSD.exe -api &quot;&amp;lt;nlog-dir&amp;gt;\build\bin\Debug\.NET Framework 4.0\API\NLog.api&quot;
  -api &amp;lt;path&amp;gt;\SampleExtensions.api -xmlns http://mycompany.com/NLog.xsd -out &amp;lt;path&amp;gt;\MyNLog.xsd
&lt;/pre&gt;
&lt;p&gt;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 &amp;#8221;&lt;strong&gt;%ProgramFiles%\Microsoft Visual Studio 9.0\Xml\Schemas&lt;/strong&gt;&amp;#8221; directory) and you should be able to enjoy Intellisense and validation against your custom schema:&lt;/p&gt;
&lt;img src='http://nlog-project.org/wp-content/uploads/2010/06/image3.png' /&gt;</content>
 </entry>
 
 <entry>
   <title>Nlog 2 0 Small Api Reorganizations And Breaking Changes</title>
   <link href="http://nlog-project.org/2010/06/10/nlog-2-0-small-api-reorganizations-and-breaking-changes.html"/>
   <updated>2010-06-10T00:00:00-07:00</updated>
   <id>http://nlog-project.org/2010/06/10/nlog-2-0-small-api-reorganizations-and-breaking-changes</id>
   <content type="html">&lt;p&gt;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:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;NLog.Targets.Compound&lt;/strong&gt; namespace was removed and classes were merged into &lt;strong&gt;NLog.Targets.Wrappers&lt;/strong&gt; namespace. In NLog 2.0 there is no distinction between wrappers and compound targets – they will be collectively referred to as wrappers.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;NLog.Contexts&lt;/strong&gt; namespace was removed and classes were merged into &lt;strong&gt;NLog&lt;/strong&gt; namespace (this is actually the situation we had in NLog 1.0, so this change is really undoing previous breaking change which was unnecessary)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The changes are consistent with general &lt;a href='http://nlog-project.org/2009/10/19/nlog-2-backwards-compatibility-and-breaking-change-policy.html'&gt;breaking change policy&lt;/a&gt; and should not impact people only using file-based configuration and simple logging APIs.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>New, smaller NLog installer is available</title>
   <link href="http://nlog-project.org/2010/06/10/new-smaller-nlog-installer-is-available.html"/>
   <updated>2010-06-10T00:00:00-07:00</updated>
   <id>http://nlog-project.org/2010/06/10/new-smaller-nlog-installer-is-available</id>
   <content type="html">&lt;p&gt;I&amp;#8217;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.&lt;/p&gt;

&lt;p&gt;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&amp;#8217;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.&lt;/p&gt;

&lt;p&gt;The new suite of installers should show up on CodePlex in the next couple hours.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>NLog 2.0 documentation is available on the wiki</title>
   <link href="http://nlog-project.org/2010/06/05/nlog-2-0-documentation-is-available-on-the-wiki.html"/>
   <updated>2010-06-05T00:00:00-07:00</updated>
   <id>http://nlog-project.org/2010/06/05/nlog-2-0-documentation-is-available-on-the-wiki</id>
   <content type="html">&lt;p&gt;Documentation for NLog 2.0 is now available on the &lt;a href='http://nlog-project.org/wiki/'&gt;Wiki&lt;/a&gt;. 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.&lt;/p&gt;

&lt;p&gt;Documentation for &lt;a href='https://github.com/NLog/NLog/wiki/Targets'&gt;targets&lt;/a&gt;, &lt;a href='https://github.com/NLog/NLog/wiki/Layouts'&gt;layouts&lt;/a&gt;, &lt;a href='https://github.com/NLog/NLog/wiki/Layout-Renderers'&gt;layout renderers&lt;/a&gt; and &lt;a href='https://github.com/NLog/NLog/wiki/Filters'&gt;filters&lt;/a&gt; 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 &lt;a href='https://github.com/NLog/NLog/wiki/File-target'&gt;File target&lt;/a&gt; for an example.&lt;/p&gt;
&lt;blockquote&gt;
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: &amp;gt;generatedDoc id='File_target' hash='db5419b5ab45ec8defc51cb5dabeaaf4′ /&amp;lt;, and causes generated doc to be inserted. The tags and contents are automatically updated whenever I re-upload documentation.
&lt;/blockquote&gt;
&lt;p&gt;Now that every piece of documentation is in Wiki format, I&amp;#8217;m &lt;strong&gt;looking for volunteers to help maintain and enhance it&lt;/strong&gt;, so if you like technical writing and want to own part of the documentation, please let me know.&lt;/p&gt;

&lt;p&gt;Please report any issues you find with the Wiki as comments here, or (even better), register for an account and fix those issues yourself.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>NLog nightly builds are now available</title>
   <link href="http://nlog-project.org/2010/05/22/nlog-nightly-builds-available.html"/>
   <updated>2010-05-22T00:00:00-07:00</updated>
   <id>http://nlog-project.org/2010/05/22/nlog-nightly-builds-available</id>
   <content type="html">&lt;p&gt;Nightly builds of NLog are now available on CodePlex. They are generated every night around 1AM PST which is 10AM in most of Europe. Builds are generated using &lt;a href='http://ccnetlive.thoughtworks.com/ccnet/doc/CCNET/'&gt;CruiseControl.NET&lt;/a&gt; which is pretty awesome piece of software - except the fact that they don&amp;#8217;t use NLog yet :).&lt;/p&gt;

&lt;p&gt;After each build, binaries are automatically pushed to CodePlex servers using &lt;a href='http://codeplex.codeplex.com/wikipage?title=CodePlexWebServices&amp;amp;referringTitle=CodePlexAPI'&gt;CodePlex Web Services API&lt;/a&gt;. Once the release is uploaded, a direct link to it is also placed on the &lt;a href='http://nlog-project.org/download.html'&gt;Download&lt;/a&gt; page. I still haven&amp;#8217;t figured out how to delete older releases automatically because CodePlex API does not support this, so I&amp;#8217;ll be doing that manually for now.&lt;/p&gt;

&lt;p&gt;You can subscribe to the RSS feed at &lt;a href='http://feeds.feedburner.com/nlogreleases'&gt;http://feeds.feedburner.com/nlogreleases&lt;/a&gt; to be notified about new builds.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Asynchronous Makeover - NLog Edition</title>
   <link href="http://nlog-project.org/2010/05/18/asynchronous-makeover-nlog-edition.html"/>
   <updated>2010-05-18T00:00:00-07:00</updated>
   <id>http://nlog-project.org/2010/05/18/asynchronous-makeover-nlog-edition</id>
   <content type="html">&lt;p&gt;I just checked in code to enable asynchronous execution of wrappers in NLog. This is the last big architectural change before bug-fixing and stabilization for 2.0 release.&lt;/p&gt;

&lt;h2 id='new_features'&gt;New features&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Exceptions thrown from wrappers such as AsyncTargetWrapper, BufferingTargetWrapper, AspNetBufferingTargetWrapper are now handled as opposed to being swallowed.&lt;/li&gt;

&lt;li&gt;LogReceiverWebServiceTarget now handles asynchronous exceptions.&lt;/li&gt;

&lt;li&gt;Exceptions from batch-aware targets are now handled for each item separately. It means that if you write 100 messages to a BufferedWrapper which wraps File target and one of those file writes fails, you will get 99 successes and 1 failure as opposed to one massive failure which no wrapper can reasonably handle. The same thing applies to email, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There has been a small change to the design described in &lt;a href='http://nlog-project.org/2010/05/09/asynchronous-logging-in-nlog-2-0.html'&gt;the last post&lt;/a&gt;. Asynchronous continuations are represented as delegates instead of interface. It makes makes it much easier to use ad-hoc continuations in code without sacrificing composability.&lt;/p&gt;

&lt;h2 id='downloads'&gt;Downloads&lt;/h2&gt;

&lt;p&gt;The source code is available in &lt;a href='http://github.com/NLog/NLog'&gt;GitHub repository&lt;/a&gt;. I&amp;#8217;ve published a private build from the master branch: &lt;a href='http://nlog-project.org/public/asyncpreview1/'&gt;http://nlog-project.org/public/asyncpreview1/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I would appreciate people giving this build a spin and reporting any anomalies. Given the scope of changes and lack of unit tests in some areas I expect many things to be broken, so any usage in production is highly discouraged.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>NLog project metrics on Ohloh.net</title>
   <link href="http://nlog-project.org/2010/05/14/nlog-project-metrics-on-ohloh-net.html"/>
   <updated>2010-05-14T00:00:00-07:00</updated>
   <id>http://nlog-project.org/2010/05/14/nlog-project-metrics-on-ohloh-net</id>
   <content type="html">&lt;p&gt;Today I came by &lt;a href='http://ohloh.net/'&gt;Ohloh.net&lt;/a&gt; which I found to be very interesting. It provides detailed statistics about open source projects. NLog was already registered by some good soul, but was pointing at the old source repository on sourceforge.net, so I updated it to use Github repo and &lt;a href='http://www.ohloh.net/p/nlog'&gt;recomputed the stats&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The statistics are generally pretty interesting, and seem pretty accurate - but there are also some entertaining ones, like the estimation of the cost it would take to recreate such a project from scratch (obviously in corporate environment):&lt;/p&gt;
&lt;img src='/images/posts/ohloh.png' /&gt;
&lt;p&gt;There are many more interesting statistics, so go and &lt;a href='http://www.ohloh.net/p/nlog'&gt;check them out&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve also put &lt;strong&gt;I USE IT&lt;/strong&gt; button on top of this page. You can add NLog to your tool stack on Ohloh by clicking on it, which will count in project statistics.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Asynchronous logging in NLog 2.0</title>
   <link href="http://nlog-project.org/2010/05/09/asynchronous-logging-in-nlog-2-0.html"/>
   <updated>2010-05-09T00:00:00-07:00</updated>
   <id>http://nlog-project.org/2010/05/09/asynchronous-logging-in-nlog-2-0</id>
   <content type="html">&lt;p&gt;NLog 1.0 supports &lt;a href='https://github.com/NLog/NLog/wiki/AsyncWrapper-target'&gt;asynchronous logging&lt;/a&gt;, but there is no good support for asynchronous exception handling. This is because wrappers targets are not capable of receiving exceptions which are raised on other threads.&lt;/p&gt;

&lt;p&gt;Since NLog 2.0 is going to support Silverlight where entire networking stack is completely asynchronous, it is critical to enable wrappers for those scenarios. Without it some important wrapper-based features, such as load balancing or failover would not work properly.&lt;/p&gt;

&lt;p&gt;This post will present new APIs to support asynchronous logging features that are coming in the next release of NLog.&lt;/p&gt;

&lt;h2 id='exception_handling_in_nlog_10'&gt;Exception Handling in NLog 1.0&lt;/h2&gt;

&lt;p&gt;NLog 1.0 uses very simple, synchronous exception handling pattern:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='csharp'&gt;&lt;span class='k'&gt;try&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='c1'&gt;// do something&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='k'&gt;catch&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;Exception&lt;/span&gt; &lt;span class='n'&gt;ex&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='c1'&gt;// handle exception&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The problem arises if the code block inside try { } clause performs an asynchronous operation such as network call which may result in an exception, as in the following example:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='csharp'&gt;&lt;span class='k'&gt;try&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='n'&gt;WebClient&lt;/span&gt; &lt;span class='n'&gt;client&lt;/span&gt; &lt;span class='p'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='n'&gt;WebClient&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
    &lt;span class='n'&gt;client&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;DownloadStringCompleted&lt;/span&gt; &lt;span class='p'&gt;+=&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;sender&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;e&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='c1'&gt;// this event will be raised asynchronously&lt;/span&gt;
        &lt;span class='c1'&gt;// on another thread, long after try/catch block completes&lt;/span&gt;
 
        &lt;span class='c1'&gt;// any exceptions raised here will not be handled by the catch {} block below&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;

    &lt;span class='n'&gt;client&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;DownloadStringAsync&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='n'&gt;Uri&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;http://example.com&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;));&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='k'&gt;catch&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;Exception&lt;/span&gt; &lt;span class='n'&gt;ex&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='c1'&gt;// handle exception&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;NLog cannot handle exceptions in such cases, since the original stack frame is gone, so it just swallows exceptions raised asynchronously and logs them to the internal log. Not catching exceptions on background threads would be fatal and might result in application termination.&lt;/p&gt;

&lt;p&gt;You can probably see why swallowing exceptions prevents wrappers, such as &lt;a href='https://github.com/NLog/NLog/wiki/RetryingWrapper-target'&gt;RetryingWrapper&lt;/a&gt; from working. If you write declare the following wrappers in your configuration file, the outermost wrapper will never implement any retry logic, since AsyncWrapper will never pass any asynchronous exceptions to RetryingWrapper.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='xml'&gt;&lt;span class='nt'&gt;&amp;lt;target&lt;/span&gt; &lt;span class='na'&gt;type=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;RetryingWrapper&amp;quot;&lt;/span&gt; &lt;span class='err'&gt;...&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;
   &lt;span class='nt'&gt;&amp;lt;target&lt;/span&gt; &lt;span class='na'&gt;type=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;AsyncWrapper&amp;quot;&lt;/span&gt; &lt;span class='err'&gt;...&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;
      &lt;span class='nt'&gt;&amp;lt;target&lt;/span&gt; &lt;span class='na'&gt;type=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;File&amp;quot;&lt;/span&gt; &lt;span class='err'&gt;...&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;
   &lt;span class='nt'&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id='asynchronous_exception_handling_in_nlog_20'&gt;Asynchronous Exception Handling in NLog 2.0&lt;/h2&gt;

&lt;p&gt;In order to implement proper asynchronous exception handling we need to let asynchronous methods know what to do in case of success and failure. This is typically done through &lt;a href='http://en.wikipedia.org/wiki/Continuation'&gt;continuation&lt;/a&gt; functions. There are many ways to represent continuation information, I&amp;#8217;ve decided to represent it as an interface with two methods:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='csharp'&gt;&lt;span class='k'&gt;public&lt;/span&gt; &lt;span class='k'&gt;interface&lt;/span&gt; &lt;span class='n'&gt;IAsyncContinuation&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;OnSuccess&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
    &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;OnException&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;Exception&lt;/span&gt; &lt;span class='n'&gt;exception&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The Target.Write() API will be refactored to look like this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='csharp'&gt;&lt;span class='k'&gt;public&lt;/span&gt; &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;WriteLogEvent&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;LogEventInfo&lt;/span&gt; &lt;span class='n'&gt;logEvent&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;IAsyncContinuation&lt;/span&gt; &lt;span class='n'&gt;asyncContinuation&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;try&lt;/span&gt;
    &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;Write&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;logEvent&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;asyncContinuation&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;catch&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;Exception&lt;/span&gt; &lt;span class='n'&gt;ex&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='n'&gt;asyncContinuation&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;OnException&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;ex&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='k'&gt;protected&lt;/span&gt; &lt;span class='k'&gt;virtual&lt;/span&gt; &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;Write&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;LogEventInfo&lt;/span&gt; &lt;span class='n'&gt;logEvent&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;IAsyncContinuation&lt;/span&gt; &lt;span class='n'&gt;asyncContinuation&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;try&lt;/span&gt;
    &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;Write&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;logEvent&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;catch&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;Exception&lt;/span&gt; &lt;span class='n'&gt;ex&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='n'&gt;asyncContinuation&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;OnException&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;ex&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
        &lt;span class='k'&gt;return&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;

    &lt;span class='n'&gt;asyncContinuation&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;OnSuccess&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='k'&gt;protected&lt;/span&gt; &lt;span class='k'&gt;abstract&lt;/span&gt; &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;Write&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;LogEventInfo&lt;/span&gt; &lt;span class='n'&gt;logEvent&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see, by default the asynchronous code gets forwarded to the synchronous Write method. This lets us keep the existing extensibility interface for targets. If you want to implement asynchronous target, you need to override both synchronous and asynchronous write methods:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='csharp'&gt;&lt;span class='k'&gt;public&lt;/span&gt; &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;MyAsyncTarget&lt;/span&gt; &lt;span class='p'&gt;:&lt;/span&gt; &lt;span class='n'&gt;TargetWithLayout&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='na'&gt;    [RequiredParameter]&lt;/span&gt;
    &lt;span class='k'&gt;public&lt;/span&gt; &lt;span class='n'&gt;Uri&lt;/span&gt; &lt;span class='n'&gt;TargetUri&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='k'&gt;get&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='k'&gt;set&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;

    &lt;span class='k'&gt;protected&lt;/span&gt; &lt;span class='k'&gt;override&lt;/span&gt; &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;Write&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;LogEventInfo&lt;/span&gt; &lt;span class='n'&gt;logEvent&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='k'&gt;throw&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nf'&gt;NotSupportedException&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;Synchronous write operation is not supported.&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;

    &lt;span class='k'&gt;protected&lt;/span&gt; &lt;span class='k'&gt;override&lt;/span&gt; &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;Write&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;LogEventInfo&lt;/span&gt; &lt;span class='n'&gt;logEvent&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;IAsyncContinuation&lt;/span&gt; &lt;span class='n'&gt;asyncContinuation&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='kt'&gt;var&lt;/span&gt; &lt;span class='n'&gt;wc&lt;/span&gt; &lt;span class='p'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='n'&gt;WebClient&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
        &lt;span class='n'&gt;wc&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;UploadDataCompleted&lt;/span&gt; &lt;span class='p'&gt;+=&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;sender&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;e&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;=&amp;gt;&lt;/span&gt;
            &lt;span class='p'&gt;{&lt;/span&gt;
                &lt;span class='n'&gt;wc&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;Dispose&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
                &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;e&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;Error&lt;/span&gt; &lt;span class='p'&gt;!=&lt;/span&gt; &lt;span class='k'&gt;null&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
                &lt;span class='p'&gt;{&lt;/span&gt;
                    &lt;span class='n'&gt;asyncContinuation&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;OnException&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;e&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;Error&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
                    &lt;span class='k'&gt;return&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
                &lt;span class='p'&gt;}&lt;/span&gt;

                &lt;span class='n'&gt;asyncContinuation&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;OnSuccess&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
            &lt;span class='p'&gt;};&lt;/span&gt;

        &lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='p'&gt;[]&lt;/span&gt; &lt;span class='n'&gt;data&lt;/span&gt; &lt;span class='p'&gt;=&lt;/span&gt; &lt;span class='n'&gt;Encoding&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;UTF8&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;GetBytes&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;Layout&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;GetFormattedMessage&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;logEvent&lt;/span&gt;&lt;span class='p'&gt;));&lt;/span&gt;
        &lt;span class='n'&gt;wc&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;UploadDataAsync&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;TargetUri&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;data&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Target.Flush() method will be changed in a similar way, except it will be asynchronous only:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='csharp'&gt;&lt;span class='k'&gt;public&lt;/span&gt; &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;Flush&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;IAsyncContinuation&lt;/span&gt; &lt;span class='n'&gt;asyncContinuation&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;try&lt;/span&gt;
    &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;FlushAsync&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;asyncContinuation&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;catch&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;Exception&lt;/span&gt; &lt;span class='n'&gt;ex&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='n'&gt;asyncContinuation&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;OnException&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;ex&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='k'&gt;protected&lt;/span&gt; &lt;span class='k'&gt;virtual&lt;/span&gt; &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;FlushAsync&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;IAsyncContinuation&lt;/span&gt; &lt;span class='n'&gt;asyncContinuation&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='n'&gt;asyncContinuation&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;OnSuccess&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;LogManager and LogFactory will also be enhanced with asynchronous Flush() methods. Their synchronous overloads will not be available in Silverlight, since there is no way to wait on a potential network call without causing a deadlock:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='csharp'&gt;&lt;span class='k'&gt;public&lt;/span&gt; &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;LogFactory&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;
&lt;span class='cp'&gt;#if !SILVERLIGHT&lt;/span&gt;
  &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;Flush&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;Flush&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;TimeSpan&lt;/span&gt; &lt;span class='n'&gt;timeout&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;Flush&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='n'&gt;timeoutMilliseconds&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='cp'&gt;#endif&lt;/span&gt;

  &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;Flush&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;IAsyncContinuation&lt;/span&gt; &lt;span class='n'&gt;asyncContinuation&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;Flush&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;IAsyncContinuation&lt;/span&gt; &lt;span class='n'&gt;asyncContinuation&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;TimeSpan&lt;/span&gt; &lt;span class='n'&gt;timeout&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;Flush&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;IAsyncContinuation&lt;/span&gt; &lt;span class='n'&gt;asyncContinuation&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='n'&gt;timeoutMilliseconds&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id='working_with_continuations'&gt;Working with continuations&lt;/h2&gt;

&lt;p&gt;NLog 2.0 will provide default implementation of continuations creatable through AsyncHelpers.MakeContinuation() factory method:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='csharp'&gt;&lt;span class='n'&gt;IAsyncContinuation&lt;/span&gt; &lt;span class='n'&gt;continuation&lt;/span&gt; &lt;span class='p'&gt;=&lt;/span&gt; &lt;span class='n'&gt;AsyncHelpers&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;MakeContinuation&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;
    &lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='cm'&gt;/* code to execute on success */&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='n'&gt;ex&lt;/span&gt; &lt;span class='p'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='cm'&gt;/* code to execute on failure */&lt;/span&gt; &lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In addition to this I am planning to expose helpers which will make working with and composing continuations easier:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='csharp'&gt;&lt;span class='k'&gt;public&lt;/span&gt; &lt;span class='k'&gt;delegate&lt;/span&gt; &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;AsynchronousAction&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;IAsyncContinuation&lt;/span&gt; &lt;span class='n'&gt;asyncContinuation&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='k'&gt;public&lt;/span&gt; &lt;span class='k'&gt;delegate&lt;/span&gt; &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='n'&gt;AsynchronousAction&lt;/span&gt;&lt;span class='p'&gt;&amp;lt;&lt;/span&gt;&lt;span class='n'&gt;T&lt;/span&gt;&lt;span class='p'&gt;&amp;gt;(&lt;/span&gt;&lt;span class='n'&gt;IAsyncContinuation&lt;/span&gt; &lt;span class='n'&gt;asyncContinuation&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;T&lt;/span&gt; &lt;span class='n'&gt;argument&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;

&lt;span class='k'&gt;public&lt;/span&gt; &lt;span class='k'&gt;static&lt;/span&gt; &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;AsyncHelpers&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;public&lt;/span&gt; &lt;span class='k'&gt;static&lt;/span&gt; &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='n'&gt;RunSequentially&lt;/span&gt;&lt;span class='p'&gt;&amp;lt;&lt;/span&gt;&lt;span class='n'&gt;T&lt;/span&gt;&lt;span class='p'&gt;&amp;gt;(&lt;/span&gt;&lt;span class='n'&gt;IEnumerable&lt;/span&gt;&lt;span class='p'&gt;&amp;lt;&lt;/span&gt;&lt;span class='n'&gt;T&lt;/span&gt;&lt;span class='p'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;values&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;IAsyncContinuation&lt;/span&gt; &lt;span class='n'&gt;asyncContinuation&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;AsynchronousAction&lt;/span&gt;&lt;span class='p'&gt;&amp;lt;&lt;/span&gt;&lt;span class='n'&gt;T&lt;/span&gt;&lt;span class='p'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;callback&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='k'&gt;public&lt;/span&gt; &lt;span class='k'&gt;static&lt;/span&gt; &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='n'&gt;RunInParallel&lt;/span&gt;&lt;span class='p'&gt;&amp;lt;&lt;/span&gt;&lt;span class='n'&gt;T&lt;/span&gt;&lt;span class='p'&gt;&amp;gt;(&lt;/span&gt;&lt;span class='n'&gt;IEnumerable&lt;/span&gt;&lt;span class='p'&gt;&amp;lt;&lt;/span&gt;&lt;span class='n'&gt;T&lt;/span&gt;&lt;span class='p'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;values&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;IAsyncContinuation&lt;/span&gt; &lt;span class='n'&gt;asyncContinuation&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;AsynchronousAction&lt;/span&gt;&lt;span class='p'&gt;&amp;lt;&lt;/span&gt;&lt;span class='n'&gt;T&lt;/span&gt;&lt;span class='p'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;action&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='k'&gt;public&lt;/span&gt; &lt;span class='k'&gt;static&lt;/span&gt; &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;Repeat&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='n'&gt;repeatCount&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;IAsyncContinuation&lt;/span&gt; &lt;span class='n'&gt;asyncContinuation&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;AsynchronousAction&lt;/span&gt; &lt;span class='n'&gt;action&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='k'&gt;public&lt;/span&gt; &lt;span class='k'&gt;static&lt;/span&gt; &lt;span class='n'&gt;IAsyncContinuation&lt;/span&gt; &lt;span class='nf'&gt;FollowedBy&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt; &lt;span class='n'&gt;IAsyncContinuation&lt;/span&gt; &lt;span class='n'&gt;asyncContinuation&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;AsynchronousAction&lt;/span&gt; &lt;span class='n'&gt;action&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='k'&gt;public&lt;/span&gt; &lt;span class='k'&gt;static&lt;/span&gt; &lt;span class='n'&gt;IAsyncContinuation&lt;/span&gt; &lt;span class='nf'&gt;WithTimeout&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt; &lt;span class='n'&gt;IAsyncContinuation&lt;/span&gt; &lt;span class='n'&gt;asyncContinuation&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;TimeSpan&lt;/span&gt; &lt;span class='n'&gt;timeout&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='k'&gt;public&lt;/span&gt; &lt;span class='k'&gt;static&lt;/span&gt; &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;RunSynchronously&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;AsynchronousAction&lt;/span&gt; &lt;span class='n'&gt;action&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id='impact_on_wrappers'&gt;Impact on wrappers&lt;/h2&gt;

&lt;p&gt;Because of the way the API is designed, the impact on existing targets should be very limited. Unfortunately this does not apply to wrappers, which have to be completely rewritten to be fully asynchronous. Asynchronous code tends to be larger and more difficult to read and follow, as demonstrated in the following example:&lt;/p&gt;

&lt;p&gt;For example, the code for &lt;a href='https://github.com/NLog/NLog/wiki/RetryingWrapper-target'&gt;retrying wrapper&lt;/a&gt; in NLog 1.0 looked like this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='csharp'&gt;&lt;span class='k'&gt;protected&lt;/span&gt; &lt;span class='k'&gt;internal&lt;/span&gt; &lt;span class='k'&gt;override&lt;/span&gt; &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;Write&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;LogEventInfo&lt;/span&gt; &lt;span class='n'&gt;logEvent&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='p'&gt;=&lt;/span&gt; &lt;span class='m'&gt;0&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='p'&gt;&amp;lt;&lt;/span&gt; &lt;span class='n'&gt;RetryCount&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='p'&gt;++&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='k'&gt;try&lt;/span&gt;
        &lt;span class='p'&gt;{&lt;/span&gt;
            &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='p'&gt;&amp;gt;&lt;/span&gt; &lt;span class='m'&gt;0&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
                &lt;span class='n'&gt;InternalLogger&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;Warn&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;Retry #{0}&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
            &lt;span class='n'&gt;WrappedTarget&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;Write&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;logEvent&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
            &lt;span class='c1'&gt;// success, return&lt;/span&gt;
            &lt;span class='k'&gt;return&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
        &lt;span class='p'&gt;}&lt;/span&gt;
        &lt;span class='k'&gt;catch&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;Exception&lt;/span&gt; &lt;span class='n'&gt;ex&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='p'&gt;{&lt;/span&gt;
            &lt;span class='n'&gt;InternalLogger&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;Warn&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;Error while writing to &amp;#39;{0}&amp;#39;: {1}&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;WrappedTarget&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;ex&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
            &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='p'&gt;==&lt;/span&gt; &lt;span class='n'&gt;RetryCount&lt;/span&gt; &lt;span class='p'&gt;-&lt;/span&gt; &lt;span class='m'&gt;1&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
                &lt;span class='k'&gt;throw&lt;/span&gt; &lt;span class='n'&gt;ex&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
            &lt;span class='n'&gt;System&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;Threading&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;Thread&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;Sleep&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;RetryDelayMilliseconds&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
        &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The code for the same operation in NLog 2.0 is much more complex:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='csharp'&gt;&lt;span class='k'&gt;protected&lt;/span&gt; &lt;span class='k'&gt;override&lt;/span&gt; &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;Write&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;LogEventInfo&lt;/span&gt; &lt;span class='n'&gt;logEvent&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;IAsyncContinuation&lt;/span&gt; &lt;span class='n'&gt;asyncContinuation&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='n'&gt;FailureAction&lt;/span&gt; &lt;span class='n'&gt;failure&lt;/span&gt; &lt;span class='p'&gt;=&lt;/span&gt; &lt;span class='k'&gt;null&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='n'&gt;counter&lt;/span&gt; &lt;span class='p'&gt;=&lt;/span&gt; &lt;span class='m'&gt;0&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

    &lt;span class='n'&gt;failure&lt;/span&gt; &lt;span class='p'&gt;=&lt;/span&gt; &lt;span class='n'&gt;ex&lt;/span&gt; &lt;span class='p'&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class='p'&gt;{&lt;/span&gt;
            &lt;span class='n'&gt;InternalLogger&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;Warn&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;Error while writing to &amp;#39;{0}&amp;#39;: {1}&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;WrappedTarget&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;ex&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
            &lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='n'&gt;retryNumber&lt;/span&gt; &lt;span class='p'&gt;=&lt;/span&gt; &lt;span class='n'&gt;Interlocked&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;Increment&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;ref&lt;/span&gt; &lt;span class='n'&gt;counter&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;

            &lt;span class='c1'&gt;// exceeded retry count&lt;/span&gt;
            &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;retryNumber&lt;/span&gt; &lt;span class='p'&gt;==&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;RetryCount&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
            &lt;span class='p'&gt;{&lt;/span&gt;
                &lt;span class='n'&gt;asyncContinuation&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;OnException&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;ex&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
                &lt;span class='k'&gt;return&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
            &lt;span class='p'&gt;}&lt;/span&gt;

            &lt;span class='c1'&gt;// sleep and try again&lt;/span&gt;
            &lt;span class='n'&gt;Thread&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;Sleep&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;RetryDelayMilliseconds&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
            &lt;span class='n'&gt;InternalLogger&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;Warn&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;Retry #{0}&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;retryNumber&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;

            &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;WrappedTarget&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;WriteLogEvent&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;logEvent&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;AsyncHelpers&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;MakeContinuation&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;asyncContinuation&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;OnSuccess&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;failure&lt;/span&gt;&lt;span class='p'&gt;));&lt;/span&gt;
        &lt;span class='p'&gt;};&lt;/span&gt;

    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;WrappedTarget&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;WriteLogEvent&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;logEvent&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;AsyncHelpers&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;MakeContinuation&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;asyncContinuation&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;OnSuccess&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;failure&lt;/span&gt;&lt;span class='p'&gt;));&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id='summary'&gt;Summary&lt;/h2&gt;

&lt;p&gt;Asynchronous processing is a very difficult matter, and it is very difficult to write correct and robust asynchronous code. I am hoping that proposed APIs and abstraction level are the right ones and will not make the source code too difficult to read and maintain.&lt;/p&gt;

&lt;p&gt;Any comments or suggestions are welcome.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>NLog 2.0 installer is available for testing</title>
   <link href="http://nlog-project.org/2010/05/01/nlog-2-0-installer-is-available-for-testing.html"/>
   <updated>2010-05-01T00:00:00-07:00</updated>
   <id>http://nlog-project.org/2010/05/01/nlog-2-0-installer-is-available-for-testing</id>
   <content type="html">&lt;p&gt;I&amp;#8217;ve spent last couple nights working on MSI installer for NLog 2.0 and I have first version of MSI packages ready for testing. They should be reasonably usable - the code passes all unit tests but did not get much integration testing yet.&lt;/p&gt;

&lt;p&gt;There are 5 installer packages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;.NET Framework package (NLog2-NetFX-PrivateBuild.msi - 8.4 MB) which includes NLog for .NET Framework 2.0, 3.5 and 4.0&lt;/li&gt;

&lt;li&gt;Silverlight package (NLog2-SL-PrivateBuild.msi - 6.4 MB) which includes NLog for Silverlight 2.0, 3.0 and 4.0&lt;/li&gt;

&lt;li&gt;Compact Framework package (NLog2-NetCF-PrivateBuild.msi - 4.6 MB) which includes NLog for .NET Compact Framework 2.0 and 3.5&lt;/li&gt;

&lt;li&gt;Mono package (NLog2-Mono-PrivateBuild.msi - 3.1 MB) which includes NLog for .NET Compact Framework 2.0 and 3.5&lt;/li&gt;

&lt;li&gt;Full package (NLog2-All-PrivateBuild.msi - 20 MB) which includes all 9 frameworks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each package comes with Visual Studio integration, which supports VS2010, VS2008 and VS2005 (completely untested) and should have the same functionality as in NLog 1.0:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code snippets for C# and VB (just type ‘nlogger&amp;#8217; and it will include logger declaration)&lt;/li&gt;

&lt;li&gt;Item templates for empty, console and typical log file&lt;/li&gt;

&lt;li&gt;XSD for intellisense&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that unlike in NLog 1.0, the installer installs those VS items for all users on the machine, not for the user who ran the installer.&lt;/p&gt;

&lt;p&gt;Please also note that debug symbols (pdb/mdb), binaries and documentation for some older frameworks, such as Silverlight 2.0 and .NET Framework 2.0 are excluded by default - use custom or full installation to enable them.&lt;/p&gt;

&lt;p&gt;Please give the installer a try on as many platform configurations as you can and report success/failure along with your configuration information as comments to this post. I&amp;#8217;m particularly interested in testing the following dimensions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;various combinations of Visual Studio SKUs installed on the same machine (with or without add-on packages such as Silverlight SDK, Resharper, etc.)&lt;/li&gt;

&lt;li&gt;different versions of Windows&lt;/li&gt;

&lt;li&gt;x86 and x64 CPUs&lt;/li&gt;

&lt;li&gt;non-English versions of Windows&lt;/li&gt;

&lt;li&gt;non-English versions of Visual Studio&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks in advance for all your help.&lt;/p&gt;</content>
 </entry>
 

</feed>