2026年に50MBのJSONLログをビューアで読む
ブラウザベースのJSONLビューアを使用して、各行を個別のJSONオブジェクトとして解析し、その結果をフィルタ可能でソート可能なテーブルにレイアウトします。これが、スクリプトを一時的に書くことなく、改行区切りログを読む最速の方法です。ファイルを貼り付けて列を取得し、関心のある行をフィルタリングして、残りをエクスポートします。ターミナルでの操作も、2GBのファイルでエディタがクラッシュすることもありません。すべてがクライアントサイドで実行されるため、オフラインでも動作します。
以下にリンクしているjsonlビューアは、私が作成したものです。うんざりしたことがきっかけです。去年の春に6つの異なるオンラインJSONツールを試してみましたが、どれも改行区切りデータを貼り付けるとすぐに詰まってしまいました。なぜなら、それらはすべて単一のJSONドキュメントを想定しており、JSONLはそれらのストリームだからです。私のものは完全にブラウザ内で動作します。サインアップ不要、アップロード不要、データはマシンから出ることはなく、無料です。より良いものがある場合は、ぜひ教えてください。
テキストエディタを殺したログファイル
先週の火曜日、午前2時頃、本番環境のタイムアウトを追っていました。私が持っていた唯一の証拠は、サービスがディスクにストリーミングしていたNDJSONログでした。340MB、約120万行、各行に1つのJSONオブジェクト。私は当然のことをまず行い、それをエディタで開きました。しばらく考え込んでいました。ファンが回転し始めました。その後、ウィンドウが白くなり、応答しなくなりました。素晴らしい。
そこでjqに頼りました。jq 'select(.level == "error")' app.logは動作しますし、正直jqは素晴らしいツールです。しかし、正確なフィールド名を思い出せませんでした。フィルタを少し間違え続けるたびに、ファイル全体を最初から再ストリーミングすることになりました。20分経っても、まだ1行も見ていませんでした。エラーは811,406行目にありましたが、まだそれを知りませんでした。私が望んでいたのは、まずデータの形状を確認してから、フィルタリングする内容を決めることでした。それがギャップでした。
JSONL(NDJSONまたはJSON Linesとも呼ばれ、異なる名前で同じアイデアを指します)は、1行に1つのJSON値のストリームです。ログパイプラインがこれを好むのは、ファイルを書き換えることなく行を追加できるためで、書き込み途中でクラッシュしても、最後の行だけが失われるだけで、ドキュメント全体が失われるわけではありません。問題は、ほとんどのJSONツールが単一のドキュメントを想定しているため、120万行を読み込んで、すぐに2番目の{でエラーをスローすることです。
JSONLビューアがオブジェクトのストリームを解析する方法
JSONLビューアのコアは、ほとんど恥ずかしいほど小さいです。改行で分割し、空白でない各行を個別に解析します。重要な1つのトリックは、1つの不良行がレンダリング全体を殺さないようにすることなので、各行でエラーをキャッチして続行します。
// Split, drop blanks, parse each line independently.
function parseJSONL(text) {
return text
.split('\n')
.filter((line) => line.trim() !== '')
.map((line, i) => {
try {
return { ok: true, row: JSON.parse(line) };
} catch (err) {
return { ok: false, line: i + 1, raw: line, error: err.message };
}
});
}
const sample = `{"ts":"2026-04-11T02:14:03Z","level":"error","msg":"timeout","ms":9812}
{"ts":"2026-04-11T02:14:04Z","level":"info","msg":"retry","attempt":2}
not valid json
{"ts":"2026-04-11T02:14:06Z","level":"info","msg":"ok"}`;
console.log(parseJSONL(sample));
Enter fullscreen mode Exit fullscreen mode
これを実行すると、4つの結果が返ってきます。3つは行オブジェクトに正常に解析され、not valid json行は、他の3つを破壊するのではなく、{ ok: false, line: 3, ... }として返されます。ビューアはその配列を取得し、表示されるすべてのキーを結合して列(ts、level、msg、ms、attempt)を構築し、テーブルを描画します。これでlevelは、grepする必要のある文字列ではなく、フィルタ可能な列になります。
自分でこれを実行する必要はありません。JSONLビューアにファイルを貼り付けるだけで、ブラウザでこれを正確に行い、破損した行を赤でフラグ付けした、ソート可能でフィルタ可能なテーブルを提供します。その赤フラグの動作は、奇妙なことに私が最も使用する部分です。私の「バグ」レポートの半分は、1つの切り詰められたログ行であることが判明します。
テーブルが実際に提供するもの
解析は退屈な半分です。テーブルがテキストの壁に勝る理由は、そこにあるものに対して何ができるかです。ほとんどの場合、まずフィルタリングします。level列にerrorと入力すると、120万行が、関係のある3,000行に縮小されます。次に、タイムスタンプでソートして最初のものを見つけます。最初のエラーは通常、本当の原因であり、残りは余波であるためです。
数値フィールド(ms単位の期間など)でソートするのは、テーブルがその価値を発揮する場面です。エディタでは、手で数字を目視することになります。ここでは、msヘッダーをクリックするだけで、最も遅いリクエストが一番上に浮かび上がります。先週、それによって14,203 msの単一の外れ値が浮上し、私はスクロールしていては気づかなかったでしょう。そして、それがバグ全体でした。
エクスポートでループが閉じます。関心のある行にフィルタリングしたら、それらをJSONまたはCSVとして取り出し、そのスライスをチケットにドロップします。そうすれば、引き継ぐ人は340 MBのファイルと肩をすくめるのではなく、40行の関連する行を見ることになります。
jqとスプレッドシートとテキストエディタの比較
これらにはそれぞれ役割があります。実際にどのように使い分けるかを以下に示します。
| アプローチ | JSONLをそのまま読み込む | ライブフィルタリング | 大規模ファイル | セットアップコスト |
|---|---|---|---|---|
| ブラウザJSONLビューア | はい | はい、即時 | ~100 MBまで問題なし | なし、ウェブページです |
| CLIのjq | はい | いいえ、クエリごとに再実行 | 優れている、ストリーミング | インストールに加え、構文の学習 |
| スプレッドシートへのインポート | いいえ、フラット化が必要 | はい | 数MBを超えると不向き | 手動変換ステップ |
| テキストエディタとgrep | いいえ | テキスト検索のみ | 悪い、全てを読み込む | すでに開いている |
探索中で、まだ何を探しているかわからない場合、ビューアが勝ちます。jqは、正確なクエリがわかっていて、スクリプトやパイプラインで必要とする場合に勝ちます。CI内ではjqを使い、脳が半分オフラインの午前2時にはビューアを使います。仕事が違うので、両方を使うことに罪悪感を感じることはやめました。
それを使うべきでない場合
私はこのツールを作りましたが、それでもすべてに使うわけではありません。いくつかの正直な限界があります。
ファイルが本当に巨大(数GB)である場合、jqまたはストリーミングパーサーに任せましょう。ブラウザタブにはメモリの上限があり、3 GBをテーブルに読み込もうとすると、エディタがハングしたのと同じようにページがハングします。このビューアは、エディタが苦戦するが、データがまだRAMに収まる範囲、つまり数百MB以下を対象としています。
タスクが自動化されている場合、ビューアは全く違う形状です。スケジュールで実行されるものやビルド内で実行されるものは、jqまたは小さなスクリプトであるべきです。cronジョブに人間がウェブページをクリックすることはなく、試せばそれを維持するのが嫌になるでしょう。
深くネストされたオブジェクトを扱っている場合、フラットなテーブルはすぐに扱いにくくなります。このビューアは可能な限りフラット化し、ネストされたブロブを折りたたまれたJSONとして表示します。これは読みやすいですが、魔法ではありません。重いネストには、jqのパス式に戻ります。どのツールもすべてのラウンドで勝つわけではなく、そうでないふりをすることは、午前2時に間違ったツールを開く原因になります。
FAQ
Q: JSONLはNDJSONと同じものですか?
A: 実質的に同じです。JSONL、NDJSON、JSON Linesはすべて同じフォーマットを指します。1行に1つのJSON値で、\nで区切られます。末尾の改行や空行に関する細かいエッジケースはありますが、まともなビューアは3つの名前を同じように扱います。
Q: 私のデータはどこかにアップロードされますか?
A: いいえ。解析はブラウザのクライアントサイドで実行されるため、ファイルはマシンから出ることはありません。それが私がこのように構築した理由のすべてです。本番ログを誰かのサーバーに貼り付けて最善を期待したくはありませんでした。
Q: 実際に扱えるファイルのサイズはどれくらいですか?
A: 利用可能なRAMに最も依存します。通常のノートPCで90 MBのファイルを問題なく処理できました。数百MBを超えると、タブが重くなるのを感じるでしょう。その時点でjqに切り替える合図です。
Q: フィルタリングされた行をエクスポートできますか?
A: はい。目的の行に絞り込んだら、表示されているセットをJSONまたはCSVとしてエクスポートできます。これは、生のダンプではなく、きれいなスライスをチームメイトに渡すのに便利です。
Q: なぜjqだけでやらないのですか?
A: できますし、多くの人がそうしています。私は既知のクエリやパイプラインにはjqが好きです。ビューアは、それ以前のより混乱した瞬間、つまりまだフィールド名がわからず、何を探しているかもわからず、目でデータを突っつきたい時に使います。
AIの支援と人間によるレビューで作成されました。aidevhub.io/jsonl-viewerでツールをお試しください。
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.