-
Notifications
You must be signed in to change notification settings - Fork 0
MS_NLog
log4net と I/F レベルで仕様の互換性は高い。
補足(NLog の現況): log4net と比べた
現在の立ち位置を先に示しておく。
log4net NLog Serilog 開発 Apache。一時休止 → 再開 継続的に活発 ★ 活発 設計思想 log4j 由来(テキスト ログ) log4j 由来+独自拡張 構造化ログが前提 ★ 設定 XML XML / JSON / コード 主にコード .NET 対応 .NET 8 等に対応 対応が速い 対応が速い ILogger統合あり あり( NLog.Extensions.Logging)あり( Serilog.AspNetCore)新規採用 少ない あり 最も多い 【現在の指針】([.NETのログ](MS_DotNetLogging) と同じ) ・アプリのコードは【ILogger<T> に書く】★ ・NLog / Serilog は【その裏側のプロバイダー】として使う → 出力先ライブラリは後から差し替えられる状態にしておく
log4net との違い
log4net と同様に、
- アペンダが出力するログのフォーマット(ヘッダとボティ)を定義する。
- 豊富なレイアウト・レンダラーが準備されている。
log4net の Appender と同様
- ラッパー・ターゲットというバッファリング・レイヤを挿入できるらしい。
こちらも、log4net と同様
log4net と同様にレイアウトで定義。
log4net と比べると、Trace が増設されている。
補足(ラッパー ターゲットが NLog の特徴): 原文が「らしい」と
書いているラッパー ターゲットは、
NLog を選ぶ実質的な理由の 1 つなので具体化しておく。【発想】 Target(出力先)を【別の Target で包む】ことができる → デコレーター パターン → [エンコーディング](MS_Encoding) の Stream の重ね方と同じ発想 ★
ラッパー 効果 AsyncWrapper 非同期化。呼び出し側を待たせない ★ BufferingWrapper バッファリングしてまとめて書く RetryingWrapper 失敗したら再試行する FallbackGroup 失敗したら別の出力先へ(DB → ファイル 等) AutoFlushWrapper 特定条件(Error 以上)で強制フラッシュ FilteringWrapper 条件に合うものだけ通す LimitingWrapper 単位時間あたりの件数を制限(ログの洪水対策) <!-- 例:非同期+失敗時のフォールバック --> <target name="db" xsi:type="FallbackGroup"> <target xsi:type="AsyncWrapper"> <target xsi:type="Database" connectionString="..." /> </target> <target xsi:type="File" fileName="logs/fallback.log" /> </target>【これが解決すること】 [log4net](MS_ApacheLog4net) の AdoNetAppender の問題 「DB が落ちるとアプリまで落ちる/遅くなる」 → AsyncWrapper で【業務処理を待たせない】 → FallbackGroup で【DB が駄目ならファイルへ】★ ただし、非同期化には代償がある → プロセスが強制終了すると【バッファ内のログが失われる】 → 終了時に LogManager.Shutdown() を呼ぶ → 重要なログには AutoFlushWrapper を併用する**
LimitingWrapper(件数制限)**も実務で効く。【ログの洪水】 ループの中で例外が出続ける → 1 秒間に数万行 → ディスクが埋まる、他のログが埋もれる、CPU を食う ★ → LimitingWrapper で上限を設ける
-
log4net の開発休止宣言に伴い NLog に移行 - Life like a clown
https://clown.cube-soft.jp/entry/2020/06/01/log4net-to-nlog -
log4net, LoggingAB, NLogを比較してみた | Kurusugawa
https://www.kurusugawa.jp/log4net-loggingab-nlog%E3%82%92%E6%AF%94%E8%BC%83%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F/
移行メモ(「log4net の開発休止宣言」について): 参考リンクは
2020 年時点の状況を反映している。
Apache log4net に記した通り、
その後 log4net はメンテナンスが再開された。【したがって】 「log4net は開発が止まったから移行が必要」という 当時の前提は【現在は当てはまらない】★ 【現在、移行を検討する理由があるとすれば】 ・構造化ログにしたい(Serilog / NLog の JSON 出力) ・ILogger 経由に統一したい ・ラッパー ターゲットのような機能が欲しい ・.NET の新しい版への追随速度 【移行しない判断も妥当】 ・動いているものを触るリスク ・ログの形式が変わると、既存の解析基盤・運用手順に影響する → ILogger 経由に寄せておけば、必要になった時点で差し替えられる
-
ターゲット(アペンダ)があるのではなく、ファイルの場合の属性として指定する。
-
また、属性は、archive 系属性と、fileName 属性を個別に使用する(併用は不可能とのこと)。
-
参考
-
NLog の archiveNumbering="Rolling" を使う - VB.NETで作る!
https://mk3008net.hatenablog.com/entry/2014/12/14/102254 -
.NETでログファイルのローテーションに日付を使用する - redwarrior’s diary
https://redwarrior.hateblo.jp/entry/2015/05/26/090000 -
NLOGのアーカイブ機能を日付ファイル名で #NLog - Qiita
https://qiita.com/mak_in/items/b64899b27b5fcf472daaNLOG のアーカイブ機能(archive 系属性)と、
ファイル名の {shotdate}(fileName 属性)は併用できない。
-
補足(log4net との設計の違い): 原文が指摘する
**「ターゲットが別にあるのではなく、属性として指定する」**という
違いは重要である。【log4net】 FileAppender と RollingFileAppender が【別のクラス】 → ローリングするかどうかで型を選ぶ 【NLog】 File ターゲットが 1 つあり、 【archive* 属性を書けばローリングになる】★ → 型を変えずに設定だけで切り替えられる<!-- 日付でアーカイブ(現在の一般的な書き方) --> <target name="file" xsi:type="File" fileName="${basedir}/logs/app.log" archiveFileName="${basedir}/logs/archives/app.{#}.log" archiveEvery="Day" archiveNumbering="Date" archiveDateFormat="yyyyMMdd" maxArchiveFiles="30" <!-- ← 保持世代数 ★ --> encoding="utf-8" concurrentWrites="true" keepFileOpen="true" layout="${longdate}|${level:uppercase=true}|${logger}|${message} ${exception:format=tostring}" />
maxArchiveFilesが log4net にない利点である。【log4net の composite の問題】([Apache log4net](MS_ApacheLog4net) 参照) 日付+サイズの併用では【古い日付が消えない】= ディスクを食う 【NLog では】 maxArchiveFiles で【総世代数を制限できる】★ maxArchiveDays で【保持日数を制限できる】 → ディスク枯渇を設定だけで防げる原文の「併用は不可能」について:
【当時の制約】 fileName に ${shortdate} を入れて日付分割する方式と、 archiveFileName によるアーカイブ方式は【併用できない】 → 前者は「その日のファイルに書く」 → 後者は「書き終えたら別名で退避する」 → 役割が重複するため 【現在の推奨】 ・【archive* 系を使う】(世代管理ができるため)★ ・fileName に日付を埋める方式は、世代管理ができない 【なお、現在の NLog では】 両者を組み合わせた場合の挙動が改善されているが、 【意図が読みにくくなる】ため、どちらかに統一するのが無難性能に関わる属性も押さえておく。
keepFileOpen="true" … ファイルを開いたままにする【速い】★ concurrentWrites="true" … 複数プロセスからの書き込みを許す ([Apache log4net](MS_ApacheLog4net) の MinimalLock 相当) 【両立させると遅くなる】 → 複数プロセスから書く必要がないなら concurrentWrites="false" + keepFileOpen="true" が最速 → プロセスごとにファイルを分ける方が根本的 fileName="logs/app_${processid}.log"
ログ出力方式 (NLog) - Open 棟梁 Wiki(OTR_LoggingNLog.md)
補足(ASP.NET Core / ILogger との統合): 原文は
.NET Framework 期の記述だが、現在の使い方を補っておく。// Program.cs(ASP.NET Core) using NLog.Web; var builder = WebApplication.CreateBuilder(args); builder.Logging.ClearProviders(); builder.Host.UseNLog(); // ← NLog を ILogger の裏側にする ★// アプリのコードは ILogger<T> のまま(NLog に依存しない) public class OrderService(ILogger<OrderService> logger) { public void Place(Order o) => logger.LogInformation("Order {OrderId} placed by {UserId}", o.Id, o.UserId); }<!-- 構造化(JSON)で出す --> <target name="json" xsi:type="File" fileName="logs/app.json"> <layout xsi:type="JsonLayout" includeEventProperties="true"> <attribute name="time" layout="${date:format=o}" /> <attribute name="level" layout="${level}" /> <attribute name="logger" layout="${logger}" /> <attribute name="message" layout="${message}" /> <attribute name="traceId" layout="${activity:property=TraceId}" /> <attribute name="exception" layout="${exception:format=tostring}" /> </layout> </target>【JsonLayout の価値】★ includeEventProperties="true" にすると、 ILogger のテンプレート引数({OrderId} 等)が 【個別のフィールドとして出力される】 → 収集基盤(Elasticsearch / Log Analytics)で OrderId による検索・集計ができる → [.NETのログ](MS_DotNetLogging) の「構造化ログ」がここで効く【NLog 使用時の注意】 ① 【終了時に必ず Shutdown する】★ LogManager.Shutdown(); → AsyncWrapper 使用時、バッファ内のログが失われるのを防ぐ ② 【起動直後のログ】 ホストの構築前に例外が出るとログが残らない → try/catch で囲み、NLog を先に初期化しておく定石がある ③ 【設定の自動リロード】 <nlog autoReload="true"> で実行中の変更を反映できる → log4net の Watch=true 相当
-
Nlog - Wikipedia
https://ja.wikipedia.org/wiki/Nlogマイクロソフトの社員である Jarek Kowalski により主導されているが、
あくまでも勤務時間外に開発しているものであり、マイクロソフトとは関係ないとしている。 -
ロギングライブラリ「NLog」で簡単ログ出力 | マイナビニュース
- (1) log4netに比べて導入が簡単
https://news.mynavi.jp/article/20100319-nlog/1 - (2) ログ出力コードの記述
https://news.mynavi.jp/article/20100319-nlog/2 - (3) 例外出力とNLog.configサンプル
https://news.mynavi.jp/article/20100319-nlog/3
- (1) log4netに比べて導入が簡単
-
Qiita
-
C# NLog チュートリアル
https://qiita.com/developpermanati/items/1de20d836070f42049cf -
NLogでログを記録する
https://qiita.com/hsagae/items/9f09e6ee204745fd2481 -
【備忘録】
- NLog よく使う出力レイアウト
https://qiita.com/shusakuorz/items/47be13a66a7c93cef460 - NLog 出力するファイルを分ける
https://qiita.com/shusakuorz/items/33b391968b5f11019f69
- NLog よく使う出力レイアウト
-
-
NLog 設定項目 詳細: C# プログラミング 再入門
http://dotnetcsharptips.seesaa.net/article/419883987.html -
NLog.config の読み込み方法。
- c# - make NLog.config file load the file from (d:\dev) instead of "\bin\debug" - Stack Overflow
https://stackoverflow.com/questions/15958271/make-nlog-config-file-load-the-file-from-d-dev-instead-of-bin-debug - NLog で設定ファイル NLog.config を埋め込みリソースから読み込む
https://mseeeen.msen.jp/load-nlog-config-from-embedded-resources/
- c# - make NLog.config file load the file from (d:\dev) instead of "\bin\debug" - Stack Overflow
-
NLogをプログラマブルに初期化し動的に構成変更する - M12i.
https://m12i.hatenablog.com/entry/2016/11/26/220019
- .NET でのログ記録
https://learn.microsoft.com/ja-jp/dotnet/core/extensions/logging - サード パーティ製のログ プロバイダー
https://learn.microsoft.com/ja-jp/dotnet/core/extensions/logging-providers - .NET の可観測性(OpenTelemetry)
https://learn.microsoft.com/ja-jp/dotnet/core/diagnostics/observability-with-otel
Tags: 移行, プログラミング, .NET開発
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。