MS_ApacheLog4net - NetDevInfraWGinOSSConsortium/NetDevInfraWiki GitHub Wiki

Apache log4net

抂芁

Apache log4net に぀いお。

補足珟況メンテナンス モヌドから埩垰した: 本ペヌゞを読む前に、
log4net の珟圚の立ち䜍眮を抌さえおおく。

【経緯】
   2004頃   Java の log4j から移怍。.NET のログの事実䞊の暙準に
   2010幎代 曎新が滞る2.0.8 が長く続いた
   2020     【開発䌑止が瀺唆され、NLog 等ぞの移行が進む】★
             [NLog](MS_NLog) の参考リンクがその時期のもの
   2021     Log4Shelllog4j 2 の重倧な脆匱性で泚目が集たる
             ※ log4net は【圱響を受けなかった】別実装のため
   2022   【メンテナンスが再開】。2.0.15 以降が継続的に曎新
   珟圚     3.x 系がリリヌスされ、.NET 8 等に察応

ずはいえ、新芏採甚の第䞀候補ではない。

【珟圚の遞択】
   新芏      → 【ILoggerMicrosoft.Extensions.Logging】★
                + Serilog / NLog をプロバむダヌずしお
   既存資産  → log4net のたた保守無理に移行しない
                → ILogger 経由に寄せるず、埌で差し替えられる

 → [.NETのログ](MS_DotNetLogging) 参照

本ペヌゞの䟡倀は、抂念レむアりトアペンダロガヌの解説にある。
この 3 分割は NLog にも Serilog にも共通するため、
1 ぀理解すれば他にも通じる。

詳现

コンポヌネント

  • log4net では、3 ぀の䞻芁なコンポヌネント

    • レむアりト
    • アペンダ
    • ロガヌ

    の蚭定を定矩ファむルに定矩できる。

  • アペンダ・ロガヌに぀いおは、以䞋が参考になる。

移行メモ原文の綎り: 原文は「lon4net」ずなっおいる箇所が
耇数あるが、正しくは log4net である本ペヌゞでは修正した。

レむアりトLayout

アペンダが出力するログのフォヌマットを定矩する。

アペンダAppender

  • 具䜓的な出力凊理を行う。
  • 出力先毎にアペンダの皮類が存圚する。
  • アペンダの皮類毎に蚭定可胜な項目が異なる。
  • 出力先、ロヌリング蚭定等を定矩する。

ロガヌLogger

  • 論理的なログファむル名
  • アペンダをロガヌで束ねるず耇数の出力先ぞ出力できる。
  • ログレベル毎に Filter するこずができる。
  • ルヌトロガヌずロガヌがあり階局構造をずる。

補足3 分割は珟圚も共通の蚭蚈である: この構造は
ログ ラむブラリ党般に共通するため、察応衚を瀺しおおく。

抂念 log4net NLog Serilog ILogger暙準
䜕を曞くか曞匏 Layout Layout Formatter / Template プロバむダヌ䟝存
どこぞ曞くか出力先 Appender Target Sink Provider
誰が曞くか分類・絞り蟌み Logger Logger Logger カテゎリILogger<T>
【階局構造の意味】★ これが最も実甚的な機胜

   ロガヌ名を【名前空間に合わせる】のが慣習
     MyApp
     MyApp.Data
     MyApp.Data.OrderRepository

   蚭定は【䞊䜍から継承される】
     <root level="INFO">                    ← 既定は INFO
     <logger name="MyApp.Data" level="DEBUG"> ← Data 配䞋だけ DEBUG

   → 【障害調査のずき、特定の局だけ詳现ログにできる】★
     本番でも党䜓を DEBUG にせずに枈む
// ロガヌ名を型から取るのが定石log4net
private static readonly ILog Log =
    LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
// ILogger珟圚では、型パラメヌタがそのたたカテゎリになる ★
public class OrderRepository(ILogger<OrderRepository> logger) { }
//   → カテゎリは "MyApp.Data.OrderRepository"
//   → appsettings.json の "Logging:LogLevel" で同じ階局制埡ができる

アペンダ皮類

アペンダには以䞋のような皮類がある。

ファむル

  • .FileAppender
    テキストファむル
  • .RollingFileAppender
    ロヌリング・テキストファむル

コン゜ヌル

  • .ConsoleAppender
  • .ColoredConsoleAppender
  • .AnsiColorTerminalAppender

むベントログ

  • .EventLogAppender

DBMS

  • .AdoNetAppender
  • .AdoNetAppenderParameter

ネットワヌク

  • .UdpAppender
  • .NetSendAppender
  • .TelnetAppender
  • .SmtpAppender
  • .SmtpPickupDirAppender
  • .RemotingAppender

TraceListener

  • .DebugAppender
    System.Diagnostics.Debug system
  • .TraceAppender
    System.Diagnostics.Trace system
  • .AspNetTraceAppender
    ASP.NET TraceContext

SyslogLinuxおよびUNIX

  • .LocalSyslogAppender
  • .RemoteSyslogAppender

その他

  • .TextWriterAppender
    .TextWriter クラス

  • .OutputDebugStringAppender
    OutputDebugString Win32API

  • .MemoryAppender

  • .AppenderCollection

  • .ForwardingAppender

  • .BufferingForwardingAppender

補足アペンダの遞び方ず、避けるべきもの: 皮類は倚いが、
実務で䜿うのはごく䞀郚である。

アペンダ 評䟡
RollingFileAppender 最も䜿われる。オンプレVM 環境の基本 ★
ConsoleAppender コンテナでは必須埌述
EventLogAppender 少量の重芁むベントのみ.NETのログ
AdoNetAppender 掚奚しない埌述
SmtpAppender 掚奚しない埌述
UdpAppender / RemoteSyslogAppender ログ集玄基盀ぞ送る堎合
RemotingAppender .NET Remoting は廃止枈み。䜿わない
TelnetAppender / NetSendAppender 歎史的
【AdoNetAppender を掚奚しない理由】★
   ・ログ出力のたびに【DB ぞ曞き蟌む】
      → DB が遅い/萜ちるず、アプリたで遅くなる/萜ちる
      → 「ログを出すために業務凊理が止たる」本末転倒
   ・DB 障害の調査ログが DB に曞けない䞀番必芁なずきに䜿えない
   ・トランザクションずの盞互䜜甚が読みにくい

  【代替】 ファむルに出し、収集基盀が取り蟌む
           [ログ収集いろいろ](MS_LogCollection)

【SmtpAppender を掚奚しない理由】
   ・障害時に【倧量のメヌルが飛ぶ】メヌルストヌム★
   ・SMTP が遅いずアプリが詰たる
   【代替】 監芖基盀アラヌト ルヌルで通知する
            → ログ出力ず通知は【責務を分ける】
【コンテナ環境での定石】★
   ・ファむルではなく【暙準出力Consoleに出す】
      → コンテナのログ ドラむバが回収する
      → Kubernetes / Docker の暙準的な流儀
   ・ファむルに出すず、
      ・コンテナが消えるずログも消える
      ・ロヌリングの管理が二重になる
      ・ボリュヌムのマりントが必芁になる

その他

ログ ヘッダ

定矩ファむルでレむアりトを定矩するこずにより、
アペンダ毎、ログ ヘッダを蚭定できる。

䟋

↓時間               ↓レベル ↓スレッドID ↓メッセヌゞ
[2007/10/25 15:22:21,750], [DEBUG], [9], 任意のメッセヌゞ

補足ログに含めるべき項目: 䟋に挙がっおいる
時刻・レベル・スレッド ID・メッセヌゞは最䜎限であり、
珟圚はさらに項目が芁る。

項目 理由
時刻 タむムゟヌンを明瀺yyyy-MM-ddTHH:mm:ss.fffzzz★
レベル 絞り蟌みの基本
ロガヌ名カテゎリ どの局のログか。原文の䟋には入っおいない
スレッド ID 䞊行凊理の远跡ただし埌述
盞関 ID / TraceId 1 リク゚ストを䞲刺しで远う ★
ナヌザヌ ID / テナント ID 誰の操䜜か個人情報に泚意
マシン名 / むンスタンス ID 耇数台構成での特定
【スレッド ID の限界】★
   async/await では【await の前埌でスレッドが倉わる】
     → スレッド ID では 1 ぀の凊理を远えない
     → [async/await](MS_AsyncAwait) 参照

   【珟圚の解】 盞関 IDTraceIdを䜿う
     ・ASP.NET Core は Activity.Current.Id を持っおいる
     ・W3C Trace Contexttraceparent ヘッダで
       【サヌビスをたたいで匕き継がれる】
<!-- log4net で盞関 ID を出す%property を䜿う -->
<param name="ConversionPattern"
       value="%date{yyyy-MM-ddTHH:mm:ss.fffzzz} [%-5level] [%logger] [%property{TraceId}] %message%newline" />
// 倀を積むLogicalThreadContext は async でも匕き継がれる
log4net.LogicalThreadContext.Properties["TraceId"] = Activity.Current?.TraceId.ToString();
【ThreadContext ず LogicalThreadContext の違い】★
   ThreadContext        
 スレッド単䜍。【async をたたぐず倱われる】
   LogicalThreadContext 
 論理的な呌び出しコンテキスト単䜍。匕き継がれる
     → 非同期凊理があるなら【必ず LogicalThreadContext】

時刻のタむムゟヌンも重芁である。

【ロヌカル時刻だけで蚘録するず】
   ・サヌバが海倖にあるUTC 蚭定だず、時差で混乱する
   ・サマヌタむムで【同じ時刻が 2 回珟れる】
      → [囜際化察応項目](MS_InternationalizationItems) 参照
   【察策】 オフセット付きISO 8601で出す。たたは UTC で統䞀する

ログ レベル

定矩ファむルでロガヌLoggerを定矩するこずにより、
出力するログ レベルのフィルタを蚭定できる。

ログ レベルには次の぀のレベルがあり、
ロガヌLoggerのログ出力 API を䜿い分ける。

レベル 説明
Fatal システム停止するような臎呜的な障害
Error システム停止はしないが、問題ずなる障害
Warn 障害ではない泚意譊告
Info 操䜜ログなどの情報
Debug 開発甚のデバッグメッセヌゞ

補足レベルの察応衚: .NETのログ で挙げた
ILogger のレベルずの察応を瀺しおおく。

log4net NLog ILogger暙準
— Trace Trace
Debug Debug Debug
Info Info Information
Warn Warn Warning
Error Error Error
Fatal Fatal Critical
【log4net には Trace がない】
   → [NLog](MS_NLog) が「Traceが増蚭されおいる」ず述べおいる点
   → ILogger には Trace / None がある

レベルの䜿い分けの原則.NETのログ ず共通:

【刀断基準】
   Fatal/Critical 
 【即座に人を起こす】必芁があるか
   Error          
 【調査が必芁】かアラヌトの察象
   Warn           
 続いたら問題になるか傟向を芋る
   Info           
 【平垞時に残す】業務の節目
   Debug/Trace    
 【本番では出さない】

【よくある誀り】
   ・䜕でも Error にする → アラヌトが鳎りっぱなしで無芖される ★
   ・想定内の䟋倖を Error にする入力゚ラヌ等→ Warn か Info
   ・本番で Debug を出しっぱなし → ディスク圧迫、性胜䜎䞋、情報挏掩

ログの蚭定

ロヌリング

  • 既定日付でロヌリング、バックアップ数管理無し
<!-- ロヌリング・ログファむル出力甚アペンダ -->
<appender name="ACCESS" type="log4net.Appender.RollingFileAppender">
    <param name="File" value="C:\root\files\resource\Log\ACCESS" />
    <!-- ロヌリングの蚭定 -->
    <param name="StaticLogFileName" value="false" />
    <param name="RollingStyle" value="date " />
    <param name="DatePattern" value='"."yyyy-MM-dd".log"' />
    <!-- 曞き蟌み時の蚭定远加 or 䞊曞き、出力゚ンコヌディング -->
    <param name="AppendToFile" value="true" />
    <encoding value="utf-8" />
    <!-- メッセヌゞのフォヌマット -->
    <layout type="log4net.Layout.PatternLayout">
        <param name="ConversionPattern" value="[%date{yyyy/MM/dd HH:mm:ss,fff}],[%-5level],[%thread],%message%newline" />
    </layout>
    <!-- フィルタ範囲の蚭定 -->
    <filter type="log4net.Filter.LevelRangeFilter">
        <levelMin value="DEBUG" />
        <levelMax value="FATAL" />
    </filter>
</appender>
  • バックアップ数が固定ずなるロヌリング
    指定のサむズを超えおいる堎合にロヌリングを行う。
    ファむル サむズは必ず、この蚭定倀未満になるわけではない。
<!-- ロヌリングの蚭定-->
<param name="StaticLogFileName" value="true" />
<param name="RollingStyle" value="size" />
<param name="MaximumFileSize" value="10MB" />
<param name="MaxSizeRollBackups" value="2" />
<param name="CountDirection" value="-1" />
  • 付䞎される番号の順番は、CountDirection パラメタ倀により制埡する。

  • サむズ 10MBMaximumFileSize毎にロヌリングし、
    䞋蚘のように、2 ぀ (MaxSizeRollBackups) のバックアップを保持する 。

    • ログファむル名   → 珟圚出力䞭のログ
    • ログファむル名.1  → 過去のログバックアップ叀い
    • ログファむル名.2  → 過去のログバックアップ最も叀い
  • 日付ずサむズを合わせたロヌリング

<!-- ロヌリングの蚭定 -->
<param name="StaticLogFileName" value="false" />
<param name="RollingStyle" value="composite" />
<param name="DatePattern" value='"."yyyy"-"MM"-"dd".log"' />
<param name="MaximumFileSize" value="10MB" />
<param name="MaxSizeRollBackups" value="10" />
<param name="CountDirection" value="-1" />
  • MaxSizeRollBackups パラメタ倀は、サむズによるロヌリングにのみ適甚される。
  • 日付ずサむズを合わせたロヌリングcompositeでは、
    ログファむル数を䞀定数に保぀圹割を果たさない。

補足この節が本ペヌゞで最も䟡倀がある: ロヌリングの萜ずし穎を
実際に怜蚌しお蚘録しおいる点が有甚である。芁点を敎理・補匷する。

① 原文が指摘する 2 ぀の萜ずし穎どちらも実際に起きる

【萜ずし穎 1】「ファむル サむズは必ず蚭定倀未満になるわけではない」
   ・log4net は【1 行を曞き終えおからサむズを刀定する】
   ・10MB を超えた「埌」にロヌリングする
     → 10MB ちょうどには収たらない
     → ディスク容量の芋積りでは【䜙裕を持぀】★

【萜ずし穎 2】「composite ではファむル数を䞀定に保おない」★
   ・MaxSizeRollBackups は【同䞀日付内】のバックアップ数にしか効かない
   ・日付が倉わるず新しい系列が始たり、【叀い日付は消えない】
     → 攟眮するず【ディスクを食い朰す】
     → 実際にディスク枯枇の障害原因になる

② composite を䜿う堎合の察策

・OS 偎で叀いファむルを削陀するタスク スケゞュヌラ / cron★
・ログ収集基盀に転送し、ロヌカルは短期保持にする
・監芖で【ディスク䜿甚率にアラヌト】を蚭定する
・そもそも【日付のみ】たたは【サむズのみ】にする

③ CountDirection の意味分かりにくいので明蚘

CountDirection = -1既定
   ログ.1 が【最新のバックアップ】、番号が倧きいほど叀い
   → ロヌリングのたびに【党ファむルの名前を倉える】.1→.2、.2→.3
   → ファむル数が倚いず【リネヌムのコストが増える】

CountDirection = 1 以䞊
   番号が倧きいほど新しいむンクリメンタル
   → リネヌムが発生しない 速い ★
   → ただし「.1 が最新」ずいう盎感には反する

④ 耇数プロセスからの曞き蟌み原文にない重芁な点

【問題】
   IIS のワヌカヌ プロセスが耇数Web ガヌデン
   あるいは耇数のサヌビスが【同じログ ファむルに曞く】
     → 既定ではファむルがロックされ、
       埌発のプロセスが【ログを出せない】★

【察策】
   <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
     → 曞き蟌みのたびに開閉する安党だが【遅い】

   あるいは【プロセスごずにファむルを分ける】掚奚
     <file type="log4net.Util.PatternString"
           value="Log\app_%processid.log" />

â‘€ 文字コヌド

<encoding value="utf-8" />
   → 原文の蚭定は正しい
   → 【BOM が付かない】ので、grep 等での扱いも良い
   → 指定しないず環境䟝存CP932になり、
     Linux で収集した際に化ける
     [゚ンコヌディング](MS_Encoding) 参照

⑥ 蚭定ファむルの読み蟌み

// AssemblyInfo.cs に曞くのが䌝統的なやり方
[assembly: log4net.Config.XmlConfigurator(
    ConfigFile = "log4net.config", Watch = true)]
//                                  ↑ 【実行䞭の蚭定倉曎を反映】★
【Watch = true の䟡倀】
   本番で「調査のため䞀時的に DEBUG にしたい」堎合、
   【再起動せずに】蚭定ファむルを曞き換えるだけで反映される
     → 障害調査で極めお有甚

【泚意】 .NET Core 以降は AssemblyInfo の属性が䜿いにくいため、
         起動時にコヌドで読み蟌む方匏が䞀般的
           var repo = LogManager.GetRepository(Assembly.GetEntryAssembly());
           XmlConfigurator.ConfigureAndWatch(repo, new FileInfo("log4net.config"));

詳现・䟋

ログ出力方匏 (log4net) - Open 棟梁 WikiOTR_LoggingLog4net.md

参考

Microsoft Learn


Tags: 移行, プログラミング, .NET開発

⚠ **GitHub.com Fallback** ⚠