この記事はMackerelアドベントカレンダー2025 15日目の記事です。
今年作ったmackerel-pluginの紹介として、mackerel-plugin-jsonl を紹介します。
このプラグインは、JSON Lines(JSONL)形式のログを読み取り、「複数の」任意のキーを集計して Mackerel のカスタムメトリクスとして送信するためのものです。 サーバローカルに蓄積される JSON ログを手軽に可視化したい、あるいはアクセスログ解析の代替として使いたい、というニーズがあるのではないかとふと思い、開発しました。
JSON ログがスタンダードになった今、ローカルでメトリクス化する選択肢
近年、アプリケーションのログ出力形式としてはJSON形式が事実上の標準となっています。 構造化されているため扱いやすく、クラウド基盤においても解析しやすいため、コンテナ環境・マイクロサービス環境では特に一般的です。
さくらのクラウドで今年リリースしたモニタリングスイートなどの「ログの収集・保管・検索・分析サービス」を活用するケースが増えています。こうしたサービスを使えば集中管理ができ、運用効率も良くなります。
一方で、さまざまな要件から依然としてサーバ上のログをその場で集計してメトリクス化したいという場面もあります。
mackerel-plugin-axslog のパフォーマンス、そして汎用化
以前、LTSVとJSON形式のWebサーバのアクセスログを読み取り Mackerel メトリクスを生成するプラグイン mackerel-plugin-axslog を開発しています。
axslogはアクセスログ特有の形式に特化したため、導入は簡単でかつ、パフォーマンスは高くなっています。しかし、汎用性は高くありません。
汎用的な JSON を扱える mackerel-plugin-json をfluentbitの監視に利用した際に、これは便利だと感動し、 「ログを行単位で処理できる JSONL 版があれば、もっと使いやすいはずだ」 というアイディアが生まれ、今回 JSONL に特化したメトリクス生成プラグインを作りました
mackerel-plugin-jsonl の特徴
mackerel-plugin-jsonl は以下のような特徴を持っています。
1. JSON Lines(JSONL)形式のログ読み取りに特化
各行が JSON であるログ形式にシンプルに対応できます。 例:
{"status":200,"latency":34,"path":"/api/users"}
{"status":500,"latency":123,"path":"/api/users"}
2. 任意のキーを抽出し集計可能
設定ファイルで、どのキーをメトリクス化するか指定できます。
- カウンタとして集計
- 数値フィールドの合計/平均などの簡易集計
- ステータスコード別のカウントなどにも対応
3. 軽量でシンプルな動作
ログを tail しながら集計し、Mackerel Agent 経由でメトリクスを送信します。
4. mackerel-plugin-json と異なるユースケースに最適化
JSON ファイルの全体構造を扱うのではなく、“ログ行単位の処理” を行います。
使い方
最も簡単な使い方は、以下のようにプラグインを実行し、ログファイルを指定するだけです。
インストール
$mkr plugin install kazeburo/mackerel-plugin-jsonl
基本的な実行例
./mackerel-plugin-jsonl \
--key-name status \
--json-key status \
--aggregator group_by \
--key-name latency \
--json-key latency \
--aggregator percentile \
--log-file /path/to/your.log \
--prefix jsonl
上記例では、
statusの値ごとに件数をカウントlatencyを数値として読み取り、合計・平均をメトリクスとして生成
といった処理を行うことができます。
一般的なJSON形式のWebサーバのアクセスログの例
ほぼaxslogと同じ動きをする例です
% /path/to/mackerel-plugin-jsonl --prefix json --log-file json.log \
-k total.count -j time -a count \
-k status -j 'status|replace("^(?:([1235])\d{2}|(4)(?:[0-8]\d|9[0-8]))$","${1}${2}xx")|have("2xx","3xx","4xx","499","5xx")' -a group_by_with_percentage \
-k latency -j reqtime -a percentile
以上を実行すると、以下のアウトプットが得られます
json.total.count 4800000.000000 1760339314 json.status.3xx 684256.000000 1760339314 json.status.4xx 1370792.000000 1760339314 json.status.499 344392.000000 1760339314 json.status.5xx 1031020.000000 1760339314 json.status.2xx 1369540.000000 1760339314 json.status_percentage.2xx 28.532083 1760339314 json.status_percentage.3xx 14.255333 1760339314 json.status_percentage.4xx 28.558167 1760339314 json.status_percentage.499 7.174833 1760339314 json.status_percentage.5xx 21.479583 1760339314 json.latency.mean 0.030000 1760339314 json.latency.p99 0.030000 1760339314 json.latency.p90 0.030000 1760339314 json.latency.p95 0.030000 1760339314
集計方式と変換関数
集計方式
--aggregator で渡す集計の方式は以下の種類を指定できます。
count: 対象となるキーが存在する行をカウントします- 例:
json.total.count 80000.000000 1760281381
- 例:
group_by: 指定したキーの値ごとに件数を集計します。- 例:
json.status.2xx 24769.733333 1760281381
- 例:
group_by_with_percentage: group_byの各値ごとの割合(%)も出力します。- 例:
json.status_percentage.5xx 23.139667 1760281381
- 例:
percentile: 指定した数値キーのパーセンタイル(mean, p90, p95, p99)を出力します。- 例:
json.latency.p95 0.030000 1760281381
- 例:
値に関する変換関数
--json-key には値までのパスに加えてパイプ(|)区切りで変換関数を指定できます。
例: foo.bar|tolower|replace('a','b')|trimspace
利用可能な関数:
tolower: 小文字化toupper: 大文字化trimspace: 前後の空白を除去replace('pattern','repl'): 正規表現で置換have('key1','key2','key3'): 初期状態のキーのリスト。集計した値がない時に0で結果を生成できます
例:
--json-key "user.name|trimspace|tolower"
--json-key "message|replace('error','warn')"
パフォーマンス
大量のログを高速に扱えるよう、mackerel-plugin-jsonlはパフォーマンスも意識して作成しています。
JSONの処理には、buger/jsonparser を利用しています。このライブラリはJSONの中から指定したキーの値を取り出すことを目的としており、高速に動作します。axslogのJSON処理にも使っています。
120万行のアクセスログに対して実行したところ、0.5秒以下で処理が完了しており、axslogと同等の性能を備えています。
jsonlのdemoディレクトリに含まれるベンチマークの実行例(Macbook Pro M3で実行)
-rw-r--r-- 1 m-nagano staff 318M Dec 13 22:56 json.log json.total.count 5142857.142857 1765634191 json.status.2xx 1468487.142857 1765634191 json.status.3xx 737027.142857 1765634191 json.status.4xx 1468530.000000 1765634191 json.status.499 366360.000000 1765634191 json.status.5xx 1102452.857143 1765634191 json.status_percentage.499 7.123667 1765634191 json.status_percentage.5xx 21.436583 1765634191 json.status_percentage.2xx 28.553917 1765634191 json.status_percentage.3xx 14.331083 1765634191 json.status_percentage.4xx 28.554750 1765634191 json.latency.mean 0.030000 1765634191 json.latency.p90 0.030000 1765634191 json.latency.p95 0.030000 1765634191 json.latency.p99 0.030000 1765634191 real 0m0.461s user 0m0.389s sys 0m0.041s
axslogのdemoに含まれるJSONログのベンチマーク結果(環境は同じ)
-rw-r--r-- 1 m-nagano staff 318M Dec 13 23:09 json.log 2025/12/13 23:09:57 Analysis start logFile:json.log lastPos:2780 Size:333602780 2025/12/13 23:09:58 Analysis completed logFile:json.log startPos:2780 endPos:333602780 Rows:1200000 axslog.latency_json.average 0.030000 1765634998 axslog.latency_json.99_percentile 0.030000 1765634998 axslog.latency_json.95_percentile 0.030000 1765634998 axslog.latency_json.90_percentile 0.030000 1765634998 axslog.access_ratio_json.1xx_percentage 0.000000 1765634998 axslog.access_ratio_json.2xx_percentage 100.000000 1765634998 axslog.access_ratio_json.3xx_percentage 0.000000 1765634998 axslog.access_ratio_json.4xx_percentage 0.000000 1765634998 axslog.access_ratio_json.499_percentage 0.000000 1765634998 axslog.access_ratio_json.5xx_percentage 0.000000 1765634998 real 0m0.468s user 0m0.400s sys 0m0.050s
まとめ
mackerel-plugin-jsonl の紹介をしました。
残念ながらまだ自分のみているサービスでの利用はない(DNSのサービスで使おうと考えてます!)のですが、さくらのクラウドの開発運用の現場で利用されており、「便利」との評価もいただいています。ぜひ機会があれば使っていただけると嬉しいです!