Logging in .NET with NLog (default config file, catch all exceptions and route to logger, ...)


/ Published in: C#
Save to your folder(s)

[NLog](http://nlog-project.org) is an awesome, simple logging solution for .NET. In the code below, there is an example entry into app.config (there are other methods for doing NLog config files, but I have found that this one works with ClickOnce deployments). There is also a snippet for catching and logging all exceptions in a WinForms application and one for a WPF application.

I also have a [question on stackoverflow](http://stackoverflow.com/questions/4091606/most-useful-nlog-configurations) with a lot of useful NLog configuration answers.


Copy this code and paste it in your HTML
  1. [app.config]
  2. <?xml version="1.0"?>
  3. <configuration>
  4. <configSections>
  5. <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
  6. </configSections>
  7.  
  8. <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  9. <variable name="appTitle" value="My Application"/>
  10. <variable name="logFilePath" value="${specialfolder:folder=Desktop:file=${appTitle} log.log}"/>
  11.  
  12. <targets async="true">
  13. <target name="file" xsi:type="File" fileName="${logFilePath}" layout="${longdate} ${level:upperCase=true}: ${message}${newline}(${stacktrace}) ${exception:format=ToString}"/>
  14.  
  15. <target name="fileAsInfo" xsi:type="File" fileName="${logFilePath}" layout="${longdate} ${level:upperCase=true}: ${message} ${exception:format=ToString}"/>
  16.  
  17. <target xsi:type="EventLog" name="eventLog" source="${appTitle}" layout="${message}${newline}${exception:format=tostring}"/>
  18. </targets>
  19.  
  20. <targets>
  21. <target xsi:type="MessageBox" name="mbox" caption="Error" layout="An error has occurred. Please see the log file (${logFilePath}) or event log for more details."/>
  22. </targets>
  23.  
  24. <rules>
  25. <logger name="*" level="Info" writeTo="fileAsInfo"/>
  26. <logger name="*" minlevel="Warn" writeTo="file"/>
  27. <logger name="*" minlevel="Warn" writeTo="eventLog"/>
  28. <logger name="*" minlevel="Error" writeTo="mbox"/>
  29. </rules>
  30. </nlog>
  31. </configuration>
  32.  
  33. // WinForms App
  34. static class Program
  35. {
  36. private static Logger _logger = LogManager.GetCurrentClassLogger();
  37.  
  38. /// <summary>
  39. /// The main entry point for the application.
  40. /// </summary>
  41. [STAThread]
  42. static void Main()
  43. {
  44. Application.ThreadException += OnThreadException;
  45. AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
  46.  
  47. Application.EnableVisualStyles();
  48. Application.SetCompatibleTextRenderingDefault(false);
  49.  
  50. try
  51. {
  52. Application.Run(new PrimaryForm());
  53. }
  54. catch (Exception exc)
  55. {
  56. LogFatalException(exc);
  57. throw;
  58. }
  59. }
  60.  
  61. private static void LogFatalException(Exception exc)
  62. {
  63. string message = String.Format(
  64. "(Application version {0}) {1}", Application.ProductVersion, exc.Message);
  65.  
  66. _logger.FatalException(message, exc);
  67. Application.Exit(); // Encouraged, but not required
  68. }
  69.  
  70. private static void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
  71. {
  72. if (e.IsTerminating)
  73. {
  74. _logger.Info("Application is terminating due to an unhandled exception in a secondary thread.");
  75. }
  76. LogFatalException(e.ExceptionObject as Exception);
  77. }
  78.  
  79. private static void OnThreadException(object sender, ThreadExceptionEventArgs e)
  80. {
  81. LogFatalException(e.Exception);
  82. }
  83. }
  84.  
  85. // WPF App
  86. // App.xaml:
  87. <Application x:Class="UI.App"
  88. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  89. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  90. DispatcherUnhandledException="Application_DispatcherUnhandledException"
  91. Startup="Application_Startup"
  92. StartupUri="UserInterface.xaml">
  93. <Application.Resources>
  94.  
  95. </Application.Resources>
  96. </Application>
  97.  
  98. // App.xaml.cs
  99. /// <summary>
  100. /// Interaction logic for App.xaml
  101. /// </summary>
  102. public partial class App : Application
  103. {
  104. private readonly Logger _logger = LogManager.GetLogger("App");
  105.  
  106. private void Application_Startup(object sender, StartupEventArgs e)
  107. {
  108. // UI Exceptions
  109. this.DispatcherUnhandledException += Application_DispatcherUnhandledException;
  110.  
  111. // Thread exceptions
  112. AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
  113. }
  114.  
  115. private void Application_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
  116. {
  117. e.Handled = true;
  118. var exception = e.Exception;
  119. HandleUnhandledException(exception);
  120. }
  121.  
  122. private void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs unhandledExceptionEventArgs)
  123. {
  124. HandleUnhandledException(unhandledExceptionEventArgs.ExceptionObject as Exception);
  125. if (unhandledExceptionEventArgs.IsTerminating)
  126. {
  127. _logger.Info("Application is terminating due to an unhandled exception in a secondary thread.");
  128. }
  129. }
  130.  
  131. private void HandleUnhandledException(Exception exception)
  132. {
  133. string message = "Unhandled exception";
  134. try
  135. {
  136. AssemblyName assemblyName = System.Reflection.Assembly.GetExecutingAssembly().GetName();
  137. message = string.Format("Unhandled exception in {0} v{1}", assemblyName.Name, assemblyName.Version);
  138. }
  139. catch (Exception exc)
  140. {
  141. _logger.ErrorException("Exception in unhandled exception handler", exc);
  142. }
  143. finally
  144. {
  145. _logger.ErrorException(message, exception);
  146. }
  147. }
  148. }

URL: http://nlog-project.org

Report this snippet


Comments

RSS Icon Subscribe to comments

You need to login to post a comment.