VB.NETでもNLogで独自のレンダラーとターゲットを定義したい

はじめに

今回はNLogで自前のレンダラーとターゲットを実装するお話です。

と、言っても公式の説明がかなり分かりやすいのでこっちを見た方が良いです。

Extending NLog · NLog/NLog Wiki · GitHub

ちなみにNLogのバージョンは4.0を対象としてます。

レンダラー

まずはレンダラーです。 クラスを継承して属性で殴るだけなのでそんなに手間じゃないです。

NLog.LayoutRenderers.LayoutRendererを継承してNLog.LayoutRenderers.LayoutRendererAttribute属性をクラスにくっつけるだけの簡単な仕事です。

今回はキチガイなレンダラーを実装します。

<LayoutRenderer("docodoco")>
Public Class DocodocoRenderer
    Inherits LayoutRenderer

    Protected Overrides Sub Append(builder As Text.StringBuilder, logEvent As LogEventInfo)
        If Not logEvent.Exception Is Nothing Then
            builder.Append(String.Format(
                           "例外だ!!┗(^o^;)┓NullReferenceExceptionかな????www" +
                           "┏(;^o^)┛ArgumentOutOfRangeExceptionかな????www" +
                           " こ…これ…これは…………{0}だあああああ┗(^o^)┛wwwww┏(^o^)┓ドコドコドコドコwwwww",
                           logEvent.Exception.GetType.FullName))
        End If
    End Sub
End Class
<extensions>
  <add assembly="NLogCustomTarget"/>
</extensions>

<targets>
  <target xsi:type="Console" name="docodoco" layout="${time}${newline}${docodoco}"/>
</targets>

<rules>
  <logger name="*" minlevel="Info" writeTo="docodoco" />
</rules>
logger.Info(New FileNotFoundException(), "メッセージ")
22:15:44.5312
例外だ!!┗(^o^;)┓NullReferenceExceptionかな????www
┏(;^o^)┛ArgumentOutOfRangeExceptionかな????www 
こ…これ…これは…………System.IO.FileNotFoundExceptionだあああああ┗(^o^)┛wwwww
┏(^o^)┓ドコドコドコドコwwwww

ちなみにメッセージは見やすいように適当に改行を挟んでいますが、本当は1行です。

あとはカスタムレンダラーを含んだアセンブリ<extensions/>でぶち込んだりいいかんじかつテキトーにターゲットとルールを定義すれば無事にキチガイをログファイルに含めることが出来ます。

ターゲット

お次はターゲットです。

こちらも継承して属性で殴るだけです。

今回は手抜きとしてコンソールに出力します。

<Target("Sugoi")>
Public Class SugoiTarget
    Inherits TargetWithLayout

    Protected Overrides Sub Write(logEvent As LogEventInfo)
        Dim logmessage = Me.Layout.Render(logEvent)
        Console.WriteLine("Sugoi:{0}", logmessage)
    End Sub
End Class

頑張ればTwitterにつぶやいてくれるターゲットも実装できそうですが、そこまでする気力や技術力がありませんでした。辛いね。

<extensions>
  <add assembly="NLogCustomTarget"/>
</extensions>

<targets>
  <target xsi:type="Console" name="docodoco" layout="${time}${newline}${docodoco}"/>
  <target xsi:type="Sugoi" name="sugoi" layout="${time} ${message} ${exception:format=tostring}"/>
</targets>

<rules>
  <logger name="*" minlevel="Info" writeTo="sugoi,docodoco" />
</rules>
Sugoi:22:41:30.0157 メッセージ System.IO.FileNotFoundException: 指定されたファイルが見つかりません。
22:41:30.0157
例外だ!!┗(^o^;)┓NullReferenceExceptionかな????www
┏(;^o^)┛ArgumentOutOfRangeExceptionかな????www 
こ…これ…これは…………System.IO.FileNotFoundExceptionだあああああ┗(^o^)┛wwwww
┏(^o^)┓ドコドコドコドコwwwww

追加って体なので、変更があった分だけ載っけてます。 ログだけあって時間を載っけてますが、こんだけ短い記事にどんだけ時間を掛けてんだよってかんじですね。

おわりに

例の如く余談ですが、NLog.ConfigNLog.Schemaを導入している場合にターゲットを自前で定義した場合はNLog.xsdも適切に書き換えてやらないと検証違反でVisual Studioのエディタが文句を言ってきます。

今回の場合はSugoiターゲットが文句を言われます。 いくらすごくてもスキーマになければ文句を言われるのですね。

まぁ、書き換えなくても動作するのでそこまで気にならないなら無視しても問題無いかと。

おわり