Skip to content

ログ出力の拡張(NLog) ​

第8版作成 最終更新 (日本時間)
対応バージョンPleasanter 1.4.11.0 以降確認バージョン1.5.8.1

1.4.11.0 から、システムログをデータベースの SysLogs テーブルだけでなくテキストファイルにも出力できるようになりました。この機能は NLog で実装されているため、appsettings.json に NLog のターゲットを追加すれば、ファイル以外(Slack、Application Insights、CloudWatch、メールなど)にもログを送れます。このページでは実装の仕組みと、Slack に送る設定例をまとめます。

仕組み ​

ロガー ​

ロギングは Implem.Pleasanter.Models.SysLogModel にまとまっており、syslogs という名前の NLog ロガーが定義されています。

csharp
private static readonly Logger logger = LogManager.GetLogger("syslogs");

(SysLogModel.cs)

ログは SysLog.json の EnableLoggingToFile が true のときだけ、このロガーに出力されます。Info 以外の種別は Error レベル、Info は Info レベルで出力され、メッセージは UpdateSysLog または WriteSysLog です。

csharp
if (Parameters.SysLog.EnableLoggingToFile)
{
    logger.ForLogEvent(SysLogType != SysLogTypes.Info ? LogLevel.Error : LogLevel.Info)
        .Message("UpdateSysLog")
        .Property("syslog", ToLogModel(this))
        .Log();
}

(UpdateSysLog 側、WriteSysLog 側)

確認したソースでは、ログレベルの割り当てが種別ごとに細かくなっています。Info は Info、Warning は Warn、UserError と SystemError は Error、Exception は Fatal です(UpdateSysLog 側、WriteSysLog 側)。

カスタムプロパティ syslog には、ToLogModel メソッドで SysLogModel を変換した SysLogLogModel がセットされます(ToLogModel)。SysLogLogModel のプロパティ(SysLogId、SysLogType、Url、ErrMessage、ErrStackTrace など)は、SysLogs テーブルのカラムと 1 対 1 で対応 しています。

設定ファイル(appsettings.json) ​

出力先の設定は appsettings.json の NLog セクションにあります。既定では次のターゲットとルールが定義されています(内容の詳細は公式マニュアル システムログをテキスト出力できるようにする を参照)。

ターゲット内容
jsonfilelogs/yyyy/MM/dd/syslogs.json に JSON で出力
csvfilelogs/yyyy/MM/dd/syslogs.csv に CSV で出力
logconsoleコンソールに出力

1.5.8.1 の appsettings.json には、このほか MCP ログ用の mcplogsfile(mcplogs ロガー)と、レート制限ログ用の ratelimitlogsfile・ratelimitlogsconsole もあります(appsettings.json)。

json
"rules": [
    {
        "logger": "console",
        "minLevel": "Info",
        "writeTo": "logconsole"
    },
    {
        "logger": "syslogs",
        "minLevel": "Info",
        "writeTo": "csvfile"
    }
]

csvfile の layout では、各カラムが ${event-properties:syslog:objectpath=カラム名} の形で定義されています(抜粋)。

json
{
    "name": "SysLogId",
    "layout": "${event-properties:syslog:objectpath=SysLogId}"
},
{
    "name": "ErrMessage",
    "layout": "${event-properties:syslog:objectpath=ErrMessage}",
    "quoting": "All"
},
{
    "name": "ErrStackTrace",
    "layout": "${replace-newlines:replacement=|:${event-properties:syslog:objectpath=ErrStackTrace}}",
    "quoting": "All"
}

objectpath に指定するのは SysLogLogModel のプロパティ名、つまり SysLogs テーブルのカラム名です。独自のターゲットの layout を書くときは、この csvfile の定義を参考にします。

カスタムターゲットを追加する(Slack の例) ​

NLog では出力先を「ターゲット」と呼びます。使えるターゲットは NLog 公式の Configuration options/Targets や、GitHub で「NLog Custom Target」と検索すると見つかります。ここでは NLog.Slack を使います。

対応フレームワークに注意

プリザンターの .NET バージョンと互換性のあるライブラリしか使えません。1.4 系は .NET 8 で、.NET Standard 2.0 / 2.1 や .NET 8 に対応したものを選ぶのが無難です。1.5 系は .NET 10 に変わっています(バージョンアップ 参照)。

1. DLL を配置する ​

カスタムターゲットの DLL を NLog.dll と同じフォルダ(マニュアルどおりのセットアップなら Implem.Pleasanter の中。Enterprise Edition の License.dll と同じ場所)に置きます。

DLL は nuget.org から取得するのが楽です(フレームワークのバージョンを指定して検索できます)。ソースから自分でビルドしてもかまいません。

console
>ren nlog.slack.2.0.0.nupkg nlog.slack.2.0.0.zip
>mkdir nlog.slack.2.0.0
>tar -xf nlog.slack.2.0.0.zip -C nlog.slack.2.0.0
>tree /f nlog.slack.2.0.0
text
NLOG.SLACK.2.0.0
│  .signature.p7s
│  NLog.Slack.nuspec
│  [Content_Types].xml
│
├─lib
│  ├─net45
│  │      NLog.Slack.dll
│  │
│  └─netstandard2.0
│          NLog.Slack.dll
│ (以下略)

netstandard2.0 の中の NLog.Slack.dll を使います。

2. 依存関係を解消する ​

追加した DLL が依存する DLL も同じフォルダに置く必要があります。依存関係は nuget.org の Dependencies タブで確認できます。NLog.Slack には依存関係がありませんが、たとえば NLog.Targets.Syslog は Polly.Contrib.WaitAndRetry に依存しているため、これも同じ方法で取り出して配置します。依存先にさらに依存関係がある場合は、すべて解消するまで繰り返します。

WARNING

プリザンターが標準で持っているライブラリに依存している場合は、標準のライブラリのバージョンが依存関係を満たすか確認が必要です。満たさない場合、バージョンアップ方向なら上書きで対応できる場合もありますが、他の依存関係が満たせるかは分からないため、厳密にはプリザンターのソースを取得して NuGet で依存関係を調べる必要があります。

3. SysLog.json を変更する ​

公式マニュアル に従い、SysLog.json の EnableLoggingToFile を true にします。

4. appsettings.json にターゲットとルールを追加する ​

Slack の Webhook URL を取得しておき、NLog セクションに次の 3 か所を追加します(既存の jsonfile・csvfile などはそのまま)。

diff
     "NLog": {
         "throwConfigExceptions": true,
+        "extensions": [
+            { "assemblyFile": "NLog.Slack.dll" }
+        ],
         "targets": {
             "async": true,
             ...
             "logconsole": {
                 "type": "AsyncWrapper",
                 "target": {
                     "type": "Console",
                     "detectConsoleAvailable": true,
                     "writeBuffer": true
                 }
-            }
+            },
+            "slack": {
+                "type": "Slack",
+                "layout": "${longdate}|${level}|${message} |${event-properties:syslog:objectpath=ErrMessage} |${replace-newlines:replacement=|:${event-properties:syslog:objectpath=ErrStackTrace}}",
+                "webHookUrl": "https://hooks.slack.com/services/XXXXXXXX/XXXXXXXX/XXXXXXXXXXXXXXXX"
+            }
         },
         "rules": [
             ...
             {
                 "logger": "syslogs",
                 "minLevel": "Info",
                 "writeTo": "csvfile"
-            }
+            },
+            {
+                "logger": "syslogs",
+                "minLevel": "Info",
+                "writeTo": "slack"
+            }
         ]
     }
設定内容
extensions配置したカスタムターゲットの DLL を指定
targets.slack.layout出力内容。SysLogs テーブルのカラム名で event-properties を指定する
rules の minLevel出力するログレベル。Info なら Info 以上。1.5.8.1 のプリザンターは syslogs ロガーに Info・Warn・Error・Fatal を出す。エラー以上だけでよい場合は "minLevel": "Error" にする

細かい設定は NLog の Wiki などを参照してください。

UserError(60)と SystemError(80)はどちらも Error レベルなので、minLevel だけでは区別できません。SystemError と Exception だけを送るフィルタや、DB トリガー・ポーリングなど NLog 以外の方法は システムログのエラーを外部に通知する にまとめています。

5. 再起動する ​

プリザンターのプロセスを再起動すると、Slack にログが送られるようになります。

Slack に届いたプリザンターのログ

関連ページ ​

変更履歴

第8版記事の確認版を繰り返す表現を整理する
第7版「ログ出力の拡張(NLog)」の画像をこのサイトで配信するようにする
第6版通知とリマインダーの書式・置き換わらない書き方・タイムゾーンの影響、システムログの外部通知の解説と、関連する改修・設計メモを追加
第5版「外部連携・AI」「構築・運用」「内部実装を読む」に対応バージョンを表示
第4版「構築・運用」を 1.5.8.1 のソースで検証して修正
第3版元記事への言及を整理し、必要なコードをページに収録。検索機能に一覧の検索と絞り込みを追加
第2版記事のファイル名に並び順の番号を付け、元記事リンクを frontmatter の sources に移行
第1版「構築・運用」セクションの記事を追加