VB.NETで作る!

VB.NETに関するあれこれ

NLog4 Configサンプル

今更ですが、NLogのバージョンが4に上がっていました。 ログファイルをアーカイブする際、ZIP化してくれるのが嬉しいですね。

www.infoq.com

NLog 4.0 has been released. | NLog

あと、拡張属性を自動的に呼んでくれるのも嬉しいです。ただ、バイナリファイルの命名規則に依存するため、別のプロジェクトに切り出さないといけないですけど。

Auto load extensions Assemblies with the name “NLog*.dll”, like “NLog.CustomTarget.dll” are now loaded automatically. This assembly should be in the same folder as NLog.dll. Of course you can load NLog extensions manually with the config

意外とタイトル名を取得するRendererがないので、拡張してもいいかも。ってか、本物(GitHub)に反映させたほうがいいか…

Imports System.Text
Imports NLog
Imports NLog.LayoutRenderers

'バイナリ名が「NLog*.dll」であれば自動的に読み込まれます

''' <summary>
''' タイトル名出力
''' </summary>
<LayoutRenderer("titlename")>
Public Class TitleNameLayoutRenderer
    Inherits LayoutRenderer

    Protected Overrides Sub Append(builder As StringBuilder, logEvent As LogEventInfo)
        builder.Append(My.Application.Info.Title)
    End Sub
End Class

サンプル

簡単な奴は説明飛ばしますが、ちょい工夫したやつを補足。

console

ヘッダーとしてアセンブリ名とバージョンを出すようにしてみました。なんとなくそれっぽい画面になりますね。

txtFile

アーカイブ時に圧縮するようにしてみました。(enableArchiveFileCompression

csvFile

CSVに対応してたんですね。いつのバージョンからできたのだろうか…

二次加工も楽だし、普通のテキストにするよりはこちらのほうがいいかも。

mail

GMailの設定を書いてみました。

mail送信処理はテキストファイル出力などと比べると圧倒的に遅いので非同期処理(AsyncWrapper)をしています。 ただ、非同期処理にした場合、メインプロセスが先に終了してしまうとメールが飛ばないようです。 どうウェイトを入れるかのかは不明であったので、メインプロセスを抜ける前に

Threading.Thread.Sleep(1000)

のような待機コードを書かないといけないかも。

NLog.config

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
      autoReload="true"
      throwExceptions="false"
      internalLogLevel="Off"
      internalLogFile="logs/nlog-internal.log" >

  <!--
  https://github.com/nlog/NLog/wiki/Configuration-file#variables
  -->

  <!-- "titlename" is custom renderer -->
  <variable name="splitter" value="--------------------------------------------------"/>

  <!-- 
  https://github.com/nlog/NLog/wiki/Targets
   -->
  <targets>
    <!--
    https://github.com/nlog/NLog/wiki/Debugger-target
    -->
    <target name="debugger" xsi:type="Debugger"
            header="${splitter}${newline}${processname} ver.${assembly-version}"
            layout="${date:format=HH\:mm\:ss.fff} | ${pad:padding=-5:inner=${level:uppercase=true}} | ${replace-newlines:${message}}${onexception:inner=${newline}${exception}"
            />

    <!--
    https://github.com/nlog/NLog/wiki/ColoredConsole-target
    -->
    <target name="console" xsi:type="ColoredConsole"
            header="${splitter}${newline}${processname} ver.${assembly-version}${newline}${splitter}"
            layout="${date:format=HH\:mm} ${message}"
            />

    <!-- 
    https://github.com/nlog/NLog/wiki/File-target
    https://github.com/nlog/NLog/wiki/CsvLayout 
    -->
    <target name="csvFile" xsi:type="File"
            fileName="${basedir}/logs/current.csv"
            archiveFileName="${basedir}/logs/archives/archive.{#}.csv.zip"
            archiveEvery="Day"
            archiveNumbering="Rolling"
            maxArchiveFiles="7"
            enableArchiveFileCompression="true">

      <layout xsi:type="CsvLayout">
        <quoting>Auto</quoting>
        <quoteChar>"</quoteChar>
        <withHeader>true</withHeader>
        <delimiter>Comma</delimiter>

        <column name="time"      layout="${longdate}"/>
        <column name="level"     layout="${level:upperCase=true}" />
        <column name="logger"    layout="${logger}" />
        <column name="message"   layout="${message}" />
        <column name="exception" layout="${exception}" />
      </layout>
    </target>

    <!--
    https://github.com/nlog/NLog/wiki/File-target
    -->
    <target name="txtFile" xsi:type="File"
        fileName="${basedir}/logs/current.log"
        archiveFileName="${basedir}/logs/archives/archive.{#}.log.zip"
        archiveEvery="Day"
        archiveNumbering="Rolling"
        maxArchiveFiles="7"
        enableArchiveFileCompression="true"
        layout="${date} | ${pad:padding=-5:inner=${level:uppercase=true}} | ${pad:padding=-40:inner=${logger}} | ${replace-newlines:${message}}${onexception:inner=${newline}${exception}"
    >
    </target>

    <!--
    https://github.com/nlog/NLog/wiki/JsonLayout
    -->
    <target name="jsonFile" xsi:type="File" fileName="${basedir}/logs/current.json">
      <layout xsi:type="JsonLayout">
        <attribute name="time" layout="${longdate}" />
        <attribute name="level" layout="${level:upperCase=true}"/>
        <attribute name="logger" layout="${logger}" />
        <attribute name="message" layout="${message}" />
        <attribute name="exception" layout="${exception}" />
      </layout>
    </target>

    <!--
    https://github.com/nlog/NLog/wiki/AsyncWrapper-target
    batchsize=1 にするとメールが1つずつ送られます。
    デフォルトでは100メッセージが1メールにまとめられます。
    timeToSleepBetweenBatches プロパティも参照してください。
    -->
    <target name="mail" xsi:type="AsyncWrapper">
      <!--
      https://github.com/NLog/NLog/wiki/Mail-target
      https://github.com/NLog/NLog/wiki/Examples
      -->
      <target xsi:type="Mail"
              header="process:${processname}${newline}version:${assembly-version}${newline}machine:${machinename}${newline}user:${windows-identity}"
              layout="${newline}${splitter}${newline}date:${longdate}${newline}level:${level:upperCase=true}${newline}logger:${logger}${newline}${message}${onexception:inner=${newline}${exception}"
              subject="${processname} system mail"
              smtpServer="smtp.gmail.com"
              smtpPort="587"
              smtpAuthentication="Basic"
              smtpUserName="input_from_account@gmail.com"
              smtpPassword="******"
              enableSsl="true"
              from="system.${processname}@gmail.com"
              to="input_to_account@gmail.com" />
    </target>

  </targets>

  <!--
  https://github.com/nlog/NLog/wiki/Configuration-file#rules
  -->
  <rules>
    <logger name="*" minlevel="Trace" writeTo="debugger" enabled="true" />
    <logger name="*" minlevel="Info"  writeTo="console" enabled="true" />

    <logger name="*" minlevel="Debug" writeTo="csvFile" enabled="true" />
    <logger name="*" minlevel="Debug" writeTo="txtFile" enabled="true" />
    <logger name="*" minlevel="Info"  writeTo="jsonFile" enabled="true" />

    <logger name="*" minlevel="Error"  writeTo="mail" enabled="true" />
  </rules>
</nlog>
. .