ログ出力の拡張(NLog)
1.4.11.0 から、システムログをデータベースの SysLogs テーブルだけでなくテキストファイルにも出力できるようになりました。この機能は NLog で実装されているため、appsettings.json に NLog のターゲットを追加すれば、ファイル以外(Slack、Application Insights、CloudWatch、メールなど)にもログを送れます。このページでは実装の仕組みと、Slack に送る設定例をまとめます。
仕組み
ロガー
ロギングは Implem.Pleasanter.Models.SysLogModel にまとまっており、syslogs という名前の NLog ロガーが定義されています。
private static readonly Logger logger = LogManager.GetLogger("syslogs");ログは SysLog.json の EnableLoggingToFile が true のときだけ、このロガーに出力されます。Info 以外の種別は Error レベル、Info は Info レベルで出力され、メッセージは UpdateSysLog または WriteSysLog です。
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 セクションにあります。既定では次のターゲットとルールが定義されています(内容の詳細は公式マニュアル システムログをテキスト出力できるようにする を参照)。
| ターゲット | 内容 |
|---|---|
jsonfile | logs/yyyy/MM/dd/syslogs.json に JSON で出力 |
csvfile | logs/yyyy/MM/dd/syslogs.csv に CSV で出力 |
logconsole | コンソールに出力 |
1.5.8.1 の appsettings.json には、このほか MCP ログ用の mcplogsfile(mcplogs ロガー)と、レート制限ログ用の ratelimitlogsfile・ratelimitlogsconsole もあります(appsettings.json)。
"rules": [
{
"logger": "console",
"minLevel": "Info",
"writeTo": "logconsole"
},
{
"logger": "syslogs",
"minLevel": "Info",
"writeTo": "csvfile"
}
]csvfile の layout では、各カラムが ${event-properties:syslog:objectpath=カラム名} の形で定義されています(抜粋)。
{
"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 から取得するのが楽です(フレームワークのバージョンを指定して検索できます)。ソースから自分でビルドしてもかまいません。
>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.0NLOG.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 などはそのまま)。
"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 にログが送られるようになります。
