概要
ログファイル内の改行コードに LF (\n) 以外(CRLF, CR など) が含まれる場合、ByteOffsetMap が正しく作成されず、結果として後続のオフセット参照処理にずれが発生する。CRのみの場合や、CRとLFの混在の場合は問題が起こらないかも。
原因
ByteOffsetMap の生成に使用している awk コマンドが、LF を前提とした length($0)+1 による改行文字数の加算を行っているため、CRLF のように 2バイト改行を含む場合、実際のオフセットとの誤差が累積する。
var cmd = $"LC_ALL=C awk '{{ offset+=length($0)+1 }} NR%{interval}==0 {{ print NR, offset }} END {{ if (NR%{interval} != 0) print NR, offset }}' '{escapedPath}' 2>/dev/null";
影響範囲
- ByteOffsetMap に基づくシーク(ランダムアクセス)
- 部分読み込み位置の誤差
回避策
- LF 改行のログファイルを使用することで問題は回避可能。
対応方針
- GNU awkであれば、
length(RT)で区切り文字の長さを取得できるので、対応可能と思われる。
- GNU awkのない環境ではperlなどにフォールバックするか、そもそもByteOffsetMapの作成を行わなければパフォーマンスは落ちるが問題は発生しない。