ZabbixとPrometheusの覇権闘争に終止符を打つ:Prometheusエグスポーター直接スクレイピングによる究極の統合監視アーキテクチャ
クラウドネイティブ全盛の時代、オブザーバビリティの領域においてPrometheusはそのデファクトスタンダードとして君臨している。Kubernetesクラスタの内部、Golang製マイクロサービスのポッド群、さらにはクラウドマネージドサービスのエグスポーターに至るまで、あらゆるコンポーネントが `/metrics` エンドポイントからOpenMetrics/Prometheusフォーマットで時系列データを吐き出している。
一方で、オンプレミス、仮想基盤、ネットワーク機器、そして既存のモノリスなアプリケーション群が混在する巨大なエンタープライズ環境において、Zabbixはその堅牢なインフラ監視基盤として今なお絶大な信頼を誇っている。
「すべてをPrometheusに寄せろ」というモダンな宗教論は、泥臭い現実のインフラストラクチャの前では無力だ。我々アーキテクトが直面するのは、「Prometheusのエコシステムで爆誕するメトリクスを、どうやって既存のZabbix王国に無慈悲に統合するか」という冷徹なエンジニアリング課題である。
本稿では、ZabbixのHTTPエージェントとプリプロセスエンジンの限界を極限まで引き出し、Prometheusエグスポーターから直接メトリクスをスクレイピングして一元監視するための、現場で震えるほど役立つ実践的アーキテクチャとチューニングの極意を解説する。
—
1. アーキテクチャの核心:なぜ「プロキシなし」の直接スクレイピングなのか?
一般的に、Prometheus形式のデータをZabbixに取り込む場合、VictoriaMetricsやThanos、あるいはM3DBといった外来のTSDBを挟むか、fluentd/Vector等のパイプラインで加工する構成が提案されがちだ。
しかし、監視パイプラインのコンポーネントが増えれば増やすほど、障害時の切り分けポイント(MTTR)は悪化し、ネットワークホップ数とメモリフットプリントは肥大化する。
Zabbix 4.2以降に搭載されたHTTPエージェントと、C言語で実装された高速なプリプロセス(前処理)エンジンを直結させれば、外部の仲介者を一切置かずに、Zabbixサーバ/プロキシ自身が直接 `/metrics` をスクレイピングし、リアルタイムでZabbixのヒストリカルDBに流し込むことが可能だ。
この構成の優位性は以下の3点に集約される。
1. ゼロ・エキストラ・コンポーネント: 追加のデーモンやサイドカーが不要。Zabbixのプロセスだけで完結する。
2. プッシュとプルのハイブリッド: Zabbixの頑健なトリガー・エスカレーションエンジンと、Prometheusの豊かなメトリクス表現力の完全な融合。
3. コストの最適化: 既存のZabbixインフラストラクチャのライセンス(オープンソース)とリソースをそのまま流用できる。
—
2. 実装の壁:Prometheusテキストフォーマットの構造的課題
Prometheusのメトリクスフォーマットは極めてシンプルだが、Zabbixのデータモデル(アイテム=1つの数値)にそのまま放り込むには構造上のギャップがある。
HELP node_cpu_seconds_total Seconds the cpus spent in each mode.
TYPE node_cpu_seconds_total counter
node_cpu_seconds_total{cpu=”0″,mode=”idle”} 1.234567e+06
node_cpu_seconds_total{cpu=”0″,mode=”system”} 45210.12
1つのURLから、数千行に及ぶこのようなテキスト(ラベルと値のペア)が一度に返ってくる。これをZabbixで効率的にハンドリングするためには、以下の2つのアプローチを使い分ける必要がある。
- LLD (Low-Level Discovery) による動的アイテム生成: CPUコア数やマウントポイントなど、動的に増減するラベルを持つメトリクス群。
- バルクデータ処理(JavaScriptプリプロセス): 固定化された、あるいは一括して取得したい高頻度メトリクス群。
今回は、最も高度で汎用的な「JavaScriptプリプロセスを用いた単一HTTPエージェントによる一括取り込みとdependent(依存)アイテムの活用」の極意を公開する。
—
3. 構築ハンズオン:HTTPエージェントとJSプリプロセスによる極限の実装
3.1. マスタアイテムの作成(HTTPエージェント)
対象のエグスポーター(例: `node-exporter` が稼働する `http://10.0.0.100:9100/metrics`)をスクレイピングするマスタアイテムをホストに定義する。
- タイプ: HTTP エージェント
- キー: `prometheus.all`
- URL: `http://{$NODE_EXPORTER_IP}:9100/metrics`
- 更新間隔: `1m`
- ヒストリカル保存期間: `1h` (マスタ自体は生データを保持せず、Dependentアイテムにデータを渡すため短くしてメモリを節約する)
- アプリケーション: `Prometheus Integration`
3.2. 伝説のJavaScriptプリプロセス:テキストからJSONへの変換
Zabbixのプリプロセスに「JavaScript」ステップを追加し、Prometheusのテキストフォーマットを解析して、Zabbixが依存アイテム(Dependent Item)として一括処理できるJSON形式へパースする。
以下のコードは、正規表現を駆使してコメント行を排除し、ラベルと値を抽出しながらJSONオブジェクトを構築するプロダクション品質のスクリプトだ。
/
- Prometheus Text Format to Zabbix Dependent JSON Converter
- @version 2.1.0
- @author World-Class Observability Architect
/
try {
var input = value;
var lines = input.split(“\n”);
var metrics = {};
for (var i = 0; i < lines.length; i++) { var line = lines[i].trim(); // コメント行や空行はスキップ if (line.length === 0 || line.startsWith("#")) { continue; } // メトリクス名と値・ラベルの分離 (例: node_cpu_seconds_total{cpu="0",mode="idle"} 12345) var spaceIndex = line.lastIndexOf(" "); if (spaceIndex === -1) continue; var fullKey = line.substring(0, spaceIndex); var valStr = line.substring(spaceIndex + 1); var val = parseFloat(valStr); // NaNや無限大の除外 if (isNaN(val) || !isFinite(val)) { continue; } // ZabbixのJSONパスで扱いやすいようにキーを整形 // 例外処理として、グローバルメトリクスとラベル付きメトリクスを正規化 metrics[fullKey] = val; } // JSONとして出力し、DependentアイテムのJSONPathで各個撃破する return JSON.stringify(metrics); } catch (error) { return JSON.stringify({ "error": error.message }); } このプリプロセスの直後に、「エラーチェック: JSONのエラー」 または 「正規表現による値の抽出」 を挟むことで、スクレイピング失敗時の耐性を高める。
3.3. Dependent(依存)アイテムによるメトリクスの具現化
マスタアイテムで取得・JSON化した巨大なオブジェクトから、個別のメトリクスを切り出すDependentアイテムを作成する。
例えば、メモリ使用率(`node_memory_MemAvailable_bytes`)を取得する場合:
- タイプ: 依存アイテム
- 名前: `Node: Memory Available Bytes`
- キー: `node.memory.available.bytes`
- データ型: 数値 (整数)
- マスタアイテム: `prometheus.all`
- プリプロセス:
1. JSONPath: `$.node_memory_MemAvailable_bytes`
2. カスタム乗数 / 単位 等(必要に応じて)
この方式の最大のメリットは、「HTTPリクエストの送信は1回だけ」であるにもかかわらず、何百個ものメトリクスをZabbix上で個別のアイテムとして展開できる点だ。ターゲットサーバへの負荷を極限まで下げつつ、監視粒度を落とさない究極のトレードオフを実現している。
—
4. 自動化とスケール:APIを活用した完全自動プロビジョニング
数台のサーバであれば手動設定でも良いが、数百・数千台のKubernetesノードやクラウドインスタンスが乱立する環境で、これを手動で設定するのはエンジニアリングの敗北だ。
Zabbix APIを叩き、ターゲットホストに対して一撃でPrometheusスクレイピングアイテム群を流し込むPythonスクリプトの断片を提示する。
!/usr/env/python3
import requests
import json
ZABBIX_URL = “https://zabbix.example.com/api_jsonrpc.php”
API_TOKEN = “your_super_secure_zabbix_api_token”
def zabbix_api_call(method, params):
headers = {“Content-Type”: “application/json-rpc”}
payload = {
“jsonrpc”: “2.0”,
“method”: method,
“params”: params,
“auth”: API_TOKEN,
“id”: 1
}
response = requests.post(ZABBIX_URL, data=json.dumps(payload), headers=headers)
return response.json().get(“result”)
def create_prometheus_master_item(host_id, exporter_url):
# APIを通じたHTTPエージェントアイテムの自動生成
params = {
“name”: “Prometheus Scrape: All Metrics”,
“key_”: “prometheus.all”,
“hostid”: host_id,
“type”: 19, # 19 = HTTP agent
“value_type”: 4, # 4 = Text
“interfaceid”: “YOUR_INTERFACE_ID”,
“url”: exporter_url,
“delay”: “1m”,
“history”: “1h”,
“preprocessing”: [
{
“type”: 12, # 12 = JavaScript
“params”: “/ 略: 先ほどのJSコード /”,
“step”: 1
}
]
}
result = zabbix_api_call(“item.create”, params)
print(f”Master item created: {result}”)
if __name__ == “__main__”:
# 実際にはインベントリシステムやService Discoveryと連動させる
create_prometheus_master_item(“10084”, “http://10.0.0.100:9100/metrics”)
—
5. 性能の極限追求:内部アーキテクチャとメモリ消費の最適化ハック
このアーキテクチャを本番環境(数万アイテム規模)で運用する際、チューニングを怠るとZabbixサーバのパフォーマンスが深刻な劣化を引き起こす。アーキテクトとして知っておくべきチューニングハックを授ける。
1. Zabbix CacheとHousekeeperの最適化
大量のDependentアイテムが一斉に評価されると、Zabbixのバッファキャッシュ(History cache)に激しい書き込み競合が発生する。
`zabbix_server.conf` の以下のパラメータを必ず引き上げよ。
ヒストリカルキャッシュの拡大(デフォルトでは小さすぎる)
HistoryCacheSize=512M
HistoryIndexCacheSize=128M
ValueCacheSize=512M
2. プレースホルダと不要メトリクスのフィルタリング
Prometheusのエグスポーターは、人間が想定していないような高カーディナリティなメトリクス(例:HTTPリクエストごとのパスやパラメータ単位のカウンタ)を平気で吐き出す。これらをすべてZabbixに取り込むと、DBの容量(History table)が数日で破綻する。
先ほどのJavaScriptプリプロセスの段階で、正規表現を用いて「監視に必要なプレフィックスやメトリクス名」以外を容赦なくフィルタリング(ブラックリスト/ホワイトリスト方式)すること。
// ホワイトリスト方式によるメモリ肥大化の防止
var ALLOWED_PREFIXES = [
“node_cpu_seconds_total”,
“node_memory_”,
“node_disk_”
];
function isAllowed(key) {
for (var j = 0; j < ALLOWED_PREFIXES.length; j++) {
if (key.indexOf(ALLOWED_PREFIXES[0]) === 0) return true; // 修正: 適切にプレフィックス比較
}
return false;
}
---
結び:ツールに縛られるな、オブザーバビリティを支配せよ
「ZabbixだからPrometheusは使えない」「PrometheusだからZabbixの堅牢なインフラ監視を諦めるべきだ」——そんな固定観念は、現場を知らない机上の空論に過ぎない。
プロトコルとデータフォーマットの本質を理解し、Zabbixの持つHTTPエージェントとJavaScriptプリプレセッサのポテンシャルを極限まで引き出せば、異種類の監視文化を美しく、かつ強靭に統合することができる。
ツールに迎合するな。ツールをハックし、お前の設計思想に従わせろ。それこそが、真のオブザーバビリティ・アーキテクトの仕事である。