読み終わったログの置き場所 — 消す・残す・圧縮するの判断基準

技術解説

障害の調査が終わりました。報告書も出しました。手元に残っているのは、その調査に使った数十GBのログです。

さて、これをどうするか。

多くの現場で、この判断はその場の気分で行われています。今週は容量に余裕があるから残す。来月ディスクが逼迫したら、そのとき古い順に消す。判断基準が言語化されていないので、毎回ゼロから悩み、担当者が変われば結論も変わります。

この記事では、読み終わったログの置き場所をめぐる4つの場面を並べます。積み上がる・圧縮したら読めなくなる・遅いディスクに退避する・移設で行き場を失う。どれも手持ちのツールで一応は対処できます。そのうえで、その手がどこで止まるかまで踏み込みます。


1. 「とりあえず残す」が積み上がる — 保持期間を決めていないログ

状況

df -h を見たら、データ領域の半分近くがログでした。内訳を見ると、logrotate が管理している正規のログはむしろ少数派で、大半は調査のときに誰かが手でコピーしたものです。app.log.20250912.bakinvestigation/old_server_logs/。いつの何の調査で使ったのか、もう誰も思い出せません。

なぜ起きるか

消す判断と残す判断は、間違えたときのコストが対称ではないからです。

消して後から必要になった場合、取り返しがつきません。監査で求められた、同じ障害が再発した、顧客からの問い合わせが半年後に来た——どれも「あのときのログがあれば」で終わります。一方、残して結局使わなかった場合に失うのは、ディスクの一部だけです。

このコストの非対称性は本物なので、人間は合理的に「残す」へ倒れます。問題は倒れ方で、基準がないまま倒れると、消してよいものまで永久に残ります。そして数年後、誰も中身を把握していない数百GBの塊が、消すのも怖い状態で居座ることになります。

汎用ツールでの対処と限界

仕組みで削る手はあります。

find /var/log/archive -name '*.log' -mtime +90 -print   # まず対象を見る
find /var/log/archive -name '*.log' -mtime +90 -delete  # 確認してから消す
du -sh /var/log/* | sort -h | tail -20                  # 何が太っているか

logrotaterotatemaxage を設定すれば、正規のログは自動で回ります。

限界は、この数字を決める根拠のほうが用意されていないことです。90日でよい理由を説明できないと、結局「怖いから残す」に戻ります。決めるには最低3つの軸を分けて考える必要があります。

  • 法令・契約:業種によって遡及を求められる年数が違います。ここは交渉の余地がなく、いちばん外側の制約になります。
  • 再現性:そのログでしか再現できない事象の寿命です。該当バージョンがすでに全台から落ちているなら、そのログの調査価値は実質ゼロです。
  • コスト:容量そのものより、バックアップとレプリケーションに乗って何倍にもなることが効きます。1本のログが3か所に複製されている構成は珍しくありません。

そして、この3軸を真面目に検討して「残す」と決めた瞬間から、次の3つの問題が始まります。


2. ディスクの半分がログで埋まっている — 圧縮したら読めなくなる問題

状況

容量が逼迫したので、古いログを gzip で固めました。テキストログはよく縮むので、それだけで空きが戻ります。半年後、「あのときのログを見たい」と言われました。解凍しようとして気づきます——展開先の空きが、もうありません

なぜ起きるか

gzipbzip2zstd も、既定の使い方ではストリーム圧縮です。ファイルの途中のバイト位置を直接指すことができず、n バイト目を読むには先頭から順に展開していく必要があります。

zgrep が便利に見えるのは、この全展開を裏でやってくれているからです。便利なのですが、中身は毎回の全展開なので、同じアーカイブを1日に5回検索すれば、5回ぶん全部を展開しています。しかもその展開結果は捨てられます。

もっと効くのは、ランダムアクセスができないこと自体です。ログ調査で本当にやりたいのは「12時34分あたりへ飛ぶ」「このIDが出る行の前後20行を見る」であって、全行を順に読むことではありません。ところが圧縮した瞬間、行番号で飛ぶ・位置で飛ぶという操作が失われます

汎用ツールでの対処と限界

分割してから圧縮すれば、部分的な取り出しはできます。

split -l 5000000 app.log part_ && gzip part_*   # 500万行ずつに割って圧縮
zstd --long=27 -19 app.log                      # 長距離マッチで圧縮率を上げる
zstd -d --stdout app.log.zst | less             # 展開しながら読む

zstd には seekable format という拡張もあり、対応ツールがあればブロック単位で途中から展開できます。

限界は3つです。ひとつめ、分割すると「1本のログ」という単位が壊れますpart_ac の 1,203 行目は原本の何行目なのか、人間が計算することになります。ふたつめ、展開しながら読む方式では検索ができませんless に流し込んだ先で / を打っても、それは展開済みの範囲に対する検索です。みっつめ、seekable format のような賢い方式は、読む側のツールがそれを知っている必要があることです。ビューアが .gz を「開ける」と言っていても、実際には裏で一時ファイルに全展開しているだけ、というのはよくあります。

要するに、現状の一般的な選択は「小さくして読めなくする」か「大きいまま読める」の二択になっています。


3. 「念のため取っておく」ログの置き場所 — NASと遅いディスク

状況

消せないログを NAS と外付けHDDに逃がしました。容量問題は解決しました。年に数回、そこを開く日が来ます。ファイルをダブルクリックして、コーヒーを淹れに行きます。

なぜ起きるか

I/O が律速だからです。 これは道具の出来とはほとんど関係がありません。

実効 100MB/s のネットワークストレージに置いた 48GB のファイルを全部読むには、単純計算で 8 分強かかります。ギガビットのLANなら理論値でも 125MB/s なので、この桁は動きません。CPU がどれだけ速くても、線が細ければそこで待ちます。

ここで効いてくるのが、多くのツールが「読み終わってから見せる」設計になっていることです。見たいのが末尾の1画面だけでも、あるいは特定の1行だけでも、全体を読み終わるまで何も表示されません。48GB のうち実際に必要なのが数KBだったとしても、8分待ちます。

さらに、前回扱った文字コードの確認のように、開き直しが発生する作業と組み合わさると悲惨です。判定を切り替えるたびに 8 分では、確認そのものを諦めることになります。

汎用ツールでの対処と限界

部分だけ取りに行けば、待ちは減ります。

tail -c 10M /mnt/nas/app.log > tail.log        # 末尾10MBだけ手元へ
dd if=/mnt/nas/app.log bs=1M skip=20000 count=50 of=part.log  # 位置指定で抜く
rsync -P /mnt/nas/app.log ./                    # 引き戻す(再開できる)

限界は、位置が分かっている場合にしか使えないことです。ddskip に入れる数字は、たいてい調査の結果として分かるものであって、調査の入り口では分かりません。「20000MB 目あたりだろう」と当たりをつけて抜き、外れていたらもう一度——を繰り返すことになります。

そして mmap に頼る実装は、ネットワーク越しでは期待した挙動になりません。NFS/SMB 上の mmap はページフォルトのたびにネットワーク往復が発生し、ローカルディスクのつもりで書かれたコードがそのまま遅くなります。「手元にコピーしてから開く」が結局いちばん確実、という結論に落ち着き、容量問題を解決するために逃がしたはずが、読むたびに手元へ戻ってくることになります。


4. サーバ移設で行き場を失う旧ログ

状況

サーバの移設が決まりました。アプリケーションもデータベースも移行計画に入っています。停止予定日の2週間前、誰かが気づきます。「旧サーバのログ、どうします?」

なぜ起きるか

ログが「資産」として棚卸しされていないからです。移行計画に載るのは、動かすと止まるもの——アプリ、DB、証明書、DNS、cron——であって、ログは止めても何も壊れません。だから最後まで議題に上がりません。

しかし監査の観点では、ログは移設を理由に消えてよいものではありません。しかも旧環境固有の事情がくっついています。ローテートの命名規則app.log.1app.log.52 の順序は移設先で意味を持つのか)、シンボリックリンク(実体はどこにあったのか)、文字コードとロケール(旧サーバの LANG に依存した出力が混ざっていないか)。そして最後に、読むための道具が旧サーバにしかないという問題。lnav の設定、誰かが書いた awk スクリプト、grep のエイリアス集。サーバを落とすと、それらも一緒に消えます。

汎用ツールでの対処と限界

やること自体は単純です。

tar -cf - /var/log/app | zstd -19 -T0 > applog.tar.zst   # 固めて圧縮
sha256sum applog.tar.zst > applog.tar.zst.sha256          # 完全性の証明を添える
rsync -avP applog.tar.zst backup:/archive/                # 転送(再開できる)

チェックサムを一緒に残すのは、後から「このログは移設時から改ざんされていない」と言うために要ります。証跡として扱う可能性があるなら、この一行を省略しないほうがいい。

限界は、この作業が「あとで読める」ことを保証していないことです。applog.tar.zst は保管はできています。しかし2年後に監査で「この日の分を出してください」と言われたとき、やることは——展開先の空きを確保して、数百GBを展開して、目的の1ファイルを探して、開く。第2章で見た問題が、そっくりそのまま2年後の自分に転送されているだけです。

そしてもうひとつ。移設の場で必ず出る「どこまで持っていくか」という問いには、第1章の3軸(法令・再現性・コスト)を持っていないと答えられません。基準がないと、全部持っていくか、期限に押されて雑に切るかの二択になります。


4つに共通していたもの

場面 現れ方 止まる場所
保持期間が決まっていない 出所不明のログが積み上がる 「何日で消してよいか」の根拠がない
圧縮して容量を空けた 半年後に展開先の空きがない 小さくすると読めなくなる二択
NAS・外付けへ退避した 開くたびに待たされる 全読み前提の設計とI/O律速
サーバ移設で持ち出した 保管はできたが読める保証がない 2年後の自分に問題を転送しただけ

4つとも、突き詰めると同じ一点で詰まっています。「小さく置くこと」と「すぐ読めること」が、いまの道具では両立していないことです。

だから判断が「消す or 残す」の二択になります。圧縮が読めなくなることと同義でなければ、この二択は成立しません。第1章の3軸(法令・再現性・コスト)で保持期間を決める作業も、圧縮した状態のまま読めるという前提が入るだけで、ずいぶん楽になります。コストの軸が1桁下がり、「迷ったら残す」の代償が小さくなるからです。

そしてこれは、この連載で繰り返し出てきた形でもあります。第1回で見た「開くのに全読みを要求する道具」、第2回の「一覧と現場の往復コスト」、第3回の「解釈を切り替えるたびの読み直し」。保管の話に見えて、実は読むときの前提が保管の判断まで縛っている、という構図です。


使っている道具

私が開発している UwView(無料)は、この「全読みを待たされる」前提を外すために作ったビューアです。巨大なファイルでも開いた瞬間から全体を表示・スクロール・検索でき、索引はバックグラウンドで作られて、完成すると行番号が付きます。NASや外付けの遅いディスクでも、必要な位置だけを読みに行くので、末尾の1画面を見るために全体を待つことはありません(ただしI/Oが律速なのは変わらないので、全文検索は物理時間ぶんかかります)。原本には書き込まないので、証跡として扱うログもそのまま開けます。

そして、ストレージを専有している巨大ログを圧縮して保管し、さらに高速に検索したいなら UwView Pro をどうぞ。永続索引・圧縮キャッシュ検索・約1/9保管で、開き直しも検索も一段速くなります(2回目以降は行番号付きで瞬時に開けます。チェックサム付きなので保管中の破損も検出できます。全OS対応・買い切り/月額プランあり)。

リンク

  • 第1回: 巨大ファイルに沈む4つの定番ツールと、その先: https://uvp.y42u.net/blog/uwview-ps01-huge-file-tool-limits/
  • 第2回: ログの因果を遡る4つの技法: https://uvp.y42u.net/blog/uwview-ps02-log-causality-tracing/
  • 第3回: 文字コード4つの罠と切り分け手順: https://uvp.y42u.net/blog/uwview-ps03-japanese-encoding-traps/
  • 消すか残すかの第三の選択肢: https://uvp.y42u.net/blog/uwview-pro-archive-teaser/
  • 圧縮率と速度の実測(条件つき): https://uvp.y42u.net/blog/uwview-pro-benchmark-3sizes/
  • ソースコード(GitHub): https://github.com/amru195704/UwView

開発者より: アプリ・Kindle本・オープンソースの一覧は GitHub: amru195704 にまとめています。


お願い
本記事の情報は参考目的で掲載しており、正確性・完全性を保証するものではありません。転送速度・圧縮率・保管年数は環境や業種の要件により大きく異なります。コマンド例は環境(GNU/BSD、zstd のバージョン、ファイルシステム等)により調整が必要な場合があります。法令上の保管義務については、必ず自組織の規程および所管の定めをご確認ください。誤記・不正確な情報がございましたら、コメント欄よりご指摘いただければ、確認のうえ修正いたします。

タイトルとURLをコピーしました