NLogで例外とスタックトレースをログに採取する

NLog – Advanced .NET Logging
NLogにも大分慣れてきた。設定ファイル(NLog.config)もかなり考えられており、内部のパーサと拡張構文(${〜})によるプロパティの設定も柔軟性がある。 

例えばログターゲット(Target)のレイアウトプロパティだがフォーマット文字とパラメタの両方を記述することが出来、

layout="[${longdate}][${level:uppercase=true}][${callsite}] ${message}"

と書くと、実際のログには

[2011-11-04 21:51:06.4160][INFO][DataBindApp1.Page1..ctor] NLogでログを出力してみよう

とように出力される。"["と"]"はそのまま出力されており、LogLevelはuppercaseに変換、最後にメッセージが出力されるのが判るだろう。

ただ一つ悩んだのだが例外が発生した場合のメッセージとスタックトレースのログを出力する場合のレイアウト。Log4jAndroidのLogCatのようにスタックトレースは問題を追いやすいようにそのまま出力されて欲しいのだが、そのような書式が無い。

最初は

layout="[${longdate}][${level:uppercase=true}][${callsite}] ${newline} ${exception} ${newline} ${stacktrace}"

このように指定してみたのだが、出力されるのは

[2011-11-04 21:51:13.1470][ERROR][Mandarine.Util.Util.<.cctor>b__0] 
 No XAML was found at the location '//Settings3.xaml'. 
 Error.GetXresultForUserException => Error.CallApplicationUEHandler => Util.<.cctor>b__0

このように詳細がすっぽり抜けた内容だけなのだ。

正解は以下のようなレイアウトになる。

layout="[${longdate}][${level:uppercase=true}][${callsite}] ${newline} ${exception:format=Message, Type, ToString:separator=*}"

このように記述すると以下のようなログ出力を得ることができる。

[2011-11-04 21:47:48.8050][ERROR][Mandarine.Util.Util.<.cctor>b__0] 
 No XAML was found at the location '//Settings3.xaml'.*System.InvalidOperationException*System.InvalidOperationException: No XAML was found at the location '//Settings3.xaml'.
   at System.Windows.Navigation.PageResourceContentLoader.EndLoad(IAsyncResult asyncResult)
   at System.Windows.Navigation.NavigationService.ContentLoader_BeginLoad_Callback(IAsyncResult result)
   at System.Windows.Navigation.PageResourceContentLoader.BeginLoad_OnUIThread(AsyncCallback userCallback, PageResourceContentLoaderAsyncResult result)
   at System.Windows.Navigation.PageResourceContentLoader.<>c__DisplayClass4.<BeginLoad>b__0(Object args)
   at System.Reflection.RuntimeMethodInfo.InternalInvoke(RuntimeMethodInfo rtmi, Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark)
   at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark)
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
   at System.Delegate.DynamicInvokeOne(Object[] args)
   at System.MulticastDelegate.DynamicInvokeImpl(Object[] args)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.Dispatch(DispatcherPriority priority)
   at System.Windows.Threading.Dispatcher.OnInvoke(Object context)
   at System.Windows.Hosting.CallbackCookie.Invoke(Object[] args)
   at System.Windows.RuntimeHost.ManagedHost.InvokeDelegate(IntPtr pHandle, Int32 nParamCount, ScriptParam[] pParams, ScriptParam& pResult)

${exception}レイアウトレンダラのプロパティを使うだけなのだが、これが中々判らなかった。

NLogはドキュメントも中々充実しており、本家サイトとサンプルコード、それと少しの試行錯誤でなんとかなるのがとても良い。
Home · NLog/NLog Wiki · GitHub