LoginSignup
1
2

More than 1 year has passed since last update.

NLogでログをSlackに通知する

Posted at

概要

NLogでロギングを仕込んだ.NETアプリケーションでエラーが発生した際に通知が届くようにしたい。
こういった場合お手軽な方法としてはメール通知が挙げられると思うが、メールを送信するためのメールサーバを用意するのが面倒。
他に良さそうな方法ないかなーと調べたところ、NLogをSlackに出力するパッケージを見つけたので、それを利用してNLogのログをSlackに通知するようにしたメモです。

環境

  • Windows 10
  • VisualStudio 2022
  • .NET 6
  • NLog 4.7.13
  • NLog.Slack 2.0.0
  • NLogはインストール&構成済み

NLog.Slackのインストール

VisualStudioの「Nugetパッケージの管理」か「パッケージマネージャコンソール」から「NLog.Slack」をインストールします。

Install-Package NLog.Slack

Slack側の準備

SlackへはIncomming Webhookを利用してログを出力するので、Incomming Webhook用のアプリを追加します。
手順は公式ドキュメントの通りですが、一応簡単に記載しておきます。

https://api.slack.com/ の「Create an app」→「From scratch」と進んで、適当なアプリ名とワークスペースを選択してアプリを追加。

nlog-slack-1.png
nlog-slack-2.png

「Features」→「App Home」からDisplay Nameとusernameを設定。(これを行わないとアプリがワークスペースに追加できないので)

nlog-slack-3.png

「Features」→「Incomming Webhooks」からIncomming Webhookを有効化して、下部の「Add New Webhook to Workspace」からワークスペースにアプリを追加。

nlog-slack-4.png
nlog-slack-5.png

後はWebhook URLをコピーすればSlack側の準備は以上です。

nlog-slack-6.png

NLog.Slackの構成

既に構成済みのNLog.configを以下として、NLog.SlackのターゲットとルールをNLog.configに追加します。

NLog.config(Slack構成前)
<?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" >
    <targets>
        <target xsi:type="Console" name="logconsole"
                layout="${longdate}|${level}|${message} |${all-event-properties} ${exception:format=tostring}" />
        </target>
    </targets>

    <rules>
        <logger name="*" minlevel="Trace" writeTo="logconsole" />
    </rules>
</nlog>
NLog.config(Slack構成後)
<?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" >

    <!-- NLog.Slackの拡張を使用 -->
    <extensions>
        <add assembly="NLog.Slack" />
    </extensions>

    <targets>
        <target xsi:type="Console" name="logconsole"
                layout="${longdate}|${level}|${message} |${all-event-properties} ${exception:format=tostring}" />
        <!-- NLog.Slackのターゲット -->
        <target xsi:type="Slack" name="logslack"
                layout="${longdate}|${level}|${message} |${all-event-properties} ${exception:format=tostring}"
                webHookUrl="https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX"
                compact="true" />
    </targets>

    <rules>
        <logger name="*" minlevel="Trace" writeTo="logconsole" />
        <!-- 全てのログをSlackに通知 -->
        <logger name="*" minlevel="Trace" writeTo="logslack" />
    </rules>
</nlog>

webHookUrlにはSlack側の準備で作成したアプリのWebhook URLを指定します。

構成後、アプリケーションで何らかのログが書き出された際にSlackに通知が飛ぶようになります。

logger.Info("NLogのログです。");

nlog-slack-7.png

実際に運用する際は全てのログがSlackに通知されてしまうとノイジーなので、Error以下(Error, Fatal)のログのみ通知させるのが良いと思います。

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" >
...
    <rules>
        ...
        <logger name="*" minlevel="Error" writeTo="logslack" />
    </rules>
</nlog>

通知メッセージのレイアウト

targetcompact属性を使用することで通知メッセージのレイアウトを変更することが可能です。
NLog.Slackの構成では省略形式(compact=true)を指定してログのレイアウトメッセージのみを通知してますが、compact=falseを指定すると、ログレベルに応じた色付けやプロセス情報等が付加できます。

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" >
    ...
    <targets>
        ...
        <target xsi:type="Slack" name="logslack"
                layout="${longdate}|${level}|${message} |${all-event-properties} ${exception:format=tostring}"
                webHookUrl="https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX"
                compact="false">
            <field name="Machine Name" layout="${machinename}" />
            <field name="Process Name" layout="${processname}" />
            <field name="Process PID" layout="${processid}" />
        </target>
    </targets>
</nlog>

nlog-slack-8.png

任意の項目も追加できます。

<field name="Field Name" layout="layout" />

targetsasync=true について

NLog.Slackのドキュメントによると、Webhookに失敗した場合やタイムアウトした場合にアプリケーションのパフォーマンスが劣化するため、targetsasync=trueを追加してログ出力を非同期で行うのが推奨とのこと。

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" >
    ...
    <targets async="true">
        ...
    </targets>
    ...
</nlog>

しかしこれを行った場合、アプリケーションが例外で不正終了する直前に書き出したログがSlackに通知されないため、その辺りの注意が必要です。

try
{
    // 何らかの例外が発生する可能性がある処理
}
catch(Exception ex)
{
    logger.Error(ex); // このログがasync="true"だとSlackに通知されない
    throw; // キャッチされずにアプリケーションが終了する
}

今回Slackに通知したかったアプリケーションの場合、「パフォーマンスは重要ではないが、エラーに気づけない可能性は出来るだけ排除したい」という性質だったのでログ出力は同期的に(async="false"で)行うようにしました。

参考文献

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2