Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9703

NLogでログをSlackに通知する

$
0
0
概要 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」と進んで、適当なアプリ名とワークスペースを選択してアプリを追加。 「Features」→「App Home」からDisplay Nameとusernameを設定。(これを行わないとアプリがワークスペースに追加できないので) 「Features」→「Incomming Webhooks」からIncomming Webhookを有効化して、下部の「Add New Webhook to Workspace」からワークスペースにアプリを追加。 後はWebhook URLをコピーすればSlack側の準備は以上です。 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のログです。"); 実際に運用する際は全てのログが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> 通知メッセージのレイアウト targetのcompact属性を使用することで通知メッセージのレイアウトを変更することが可能です。 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> 任意の項目も追加できます。 <field name="Field Name" layout="layout" /> targetsのasync=true について NLog.Slackのドキュメントによると、Webhookに失敗した場合やタイムアウトした場合にアプリケーションのパフォーマンスが劣化するため、targetsにasync=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"で)行うようにしました。 参考文献 Sending messages using Incoming Webhooks | Slack eth0izzle/NLog.Slack

Viewing all articles
Browse latest Browse all 9703

Trending Articles