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に変換、最後にメッセージが出力されるのが判るだろう。
ただ一つ悩んだのだが例外が発生した場合のメッセージとスタックトレースのログを出力する場合のレイアウト。Log4jやAndroidの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