はじめに
ZabbixのデータをSplunkに取り込んで色々可視化をしたいと思ったことはあるはずです。
じゃあどうすればいいか?
なかなか情報が無かったのでまとめてみました。
以下方法を見てみます。
・リアルタイムエクスポート
・DBクエリ
・アラート(Media Type)
Zabbixデータの取込方法
リアルタイムエクスポートでZabbixデータを即時連携
Zabbix v4.0以降でトリガーイベント、アイテム値、トレンドデータをリアルタイムでJSON形式でエクスポートできます。
簡単にデータを出力しSplunkに取り込むことが可能なので最もおすすめです。
設定手順
- /etc/zabbix/zabbix_server.confのexportDirを設定します。このディレクトリにProblem、Item、Trendのデータが出力されます
- データサイズが大きくなりがちなので、ExportFileSizeを適切に設定しましょう(デフォルトは1GB)
サンプルデータ
・Problem
{"clock":1723538464,"ns":968235755,"value":1,"eventid":39,"name":"Memory pressure","severity":4,"hosts":[{"host":"Zabbix server","name":"Zabbix server"}],"groups":["Zabbix servers"],"tags":[{"tag":"component","value":"memory"},{"tag":"class","value":"os"},{"tag":"target","value":"linux"}]}
・Item
{"host":{"host":"Zabbix server","name":"Zabbix server"},"groups":["Zabbix servers"],"item_tags":[{"tag":"component","value":"cpu"}],"itemid":42264,"name":"Linux: CPU idle time","clock":1723531764,"ns":665879785,"value":99.566269,"type":0}
・Trend(1時間あたりの統計値。不要かもしれません。)
{"host":{"host":"Zabbix server","name":"Zabbix server"},"groups":["Zabbix servers"],"item_tags":[{"tag":"component","value":"cpu"}],"itemid":42264,"name":"Linux: CPU idle time","clock":1723528800,"count":1,"min":99.566269,"avg":99.566269,"max":99.566269,"type":0}
素直なJSON形式なので単にUFで出力データを取り込めばよいでしょう。
DBクエリで詳細データを取得
Problem、Item、TrendデータをDBから直接クエリすることができます。
リアルタイムエクスポートが使えない場合の代替策や詳細データを取りたい場合に使用できます。
SplunkではSplunk DB Connectを使いクエリすればOKです。
※DB ConnectではInput typeをRisingにし、WHERE time > ?
みたいに入れれば差分が取れます。
クエリ例
以下はクエリ例です。適宜変更してください。
Databaseはzabbix
です。
テーブルスキーマとリレーションに関する公式情報はないので気合いとGoogle先生でなんとかするしかありません。
・Event
SELECT FROM_UNIXTIME(events.clock) AS time, hosts.host, events.eventid, events.name, events.severity, triggers.triggerid, events.acknowledged
FROM events
JOIN triggers ON events.objectid = triggers.triggerid
JOIN functions ON functions.triggerid = triggers.triggerid
JOIN items ON items.itemid = functions.itemid
JOIN hosts ON items.hostid = hosts.hostid
ORDER BY time;
+---------------------+---------------+---------+-------------------------------------+----------+-----------+--------------+
| time | host | eventid | name | severity | triggerid | acknowledged |
+---------------------+---------------+---------+-------------------------------------+----------+-----------+--------------+
| 2024-08-13 06:50:04 | Zabbix server | 2 | Memory pressure | 3 | 23708 | 0 |
| 2024-08-13 07:33:50 | Zabbix server | 4 | CPU Alerts | 4 | 23707 | 0 |
| 2024-08-13 07:36:50 | Zabbix server | 5 | CPU Alerts | 0 | 23707 | 0 |
・Item
SELECT FROM_UNIXTIME(history.clock) AS time, hosts.host, items.name, history.value
FROM history
JOIN items ON history.itemid = items.itemid
JOIN hosts ON items.hostid = hosts.hostid
ORDER BY time;
+---------------------+---------------+---------------------------------------------------------------------------+---------------------+
| time | host | name | value |
+---------------------+---------------+---------------------------------------------------------------------------+---------------------+
| 2024-08-13 06:17:43 | Zabbix server | Zabbix server: Utilization of ODBC poller data collector processes, in % | 0 |
| 2024-08-13 06:17:44 | Zabbix server | Zabbix server: Utilization of poller data collector processes, in % | 0.19933554817275748 |
| 2024-08-13 06:17:45 | Zabbix server | Zabbix server: Utilization of proxy poller data collector processes, in % | 0 |
・Trend
SELECT FROM_UNIXTIME(trends.clock) AS time, hosts.host, items.name, trends.value_min, trends.value_avg, trends.value_max
FROM trends
JOIN items ON trends.itemid = items.itemid
JOIN hosts ON items.hostid = hosts.hostid
ORDER BY time;
+---------------------+---------------+----------------------------------------------------------------------+--------------------+-----------------------+---------------------+
| time | host | name | value_min | value_avg | value_max |
+---------------------+---------------+----------------------------------------------------------------------+--------------------+-----------------------+---------------------+
| 2024-08-13 06:00:00 | Zabbix server | Zabbix server: Number of processed numeric (float) values per second | 0.8655759063842902 | 1.040058365006189 | 1.0665503618891081 |
| 2024-08-13 06:00:00 | Zabbix server | Zabbix server: Number of processed character values per second | 0 | 0.0031214101236932907 | 0.03329858264057206 |
| 2024-08-13 06:00:00 | Zabbix server | Zabbix server: Number of processed log values per second | 0 | 0 | 0 |
アラート連携(Media Type設定)
Splunk HEC用のMedia typeを作成すればアラートをSplunkに送信することができます。
※アイディア、スクリプトはとある方から頂いたものです。ありがとうございます!
設定手順
-
SplunkでHECを作成してください
-
Zabbixで以下のようにMedia Typeを作成してください
Name | Value |
---|---|
URL | https://<Splunk HEC URL※>/services/collector/event |
HTTPProxy | (PROXYを通す場合はプロキシサーバーを設定) |
To | {ALERT.SENDTO} |
SUBJECT | {ALERT.SUBJECT} |
MESSAGE | {ALERT.MESSAGE} |
TOKEN | <HECトークン> |
ALERT_SEVERITY | {EVENT.SEVERITY} |
HOST | {HOST.NAME} |
ID | {EVENT.ID} |
OPDATA | {EVENT.OPDATA} |
EVENT_DATE | {EVENT.DATE} |
EVENT_TIME | {EVENT.TIME} |
TRIGGER_URL | {TRIGGER.URL} |
※HEC URLについてはこちら
https://docs.splunk.com/Documentation/Splunk/latest/Data/UsetheHTTPEventCollector#Send_data_to_HTTP_Event_Collector
Scriptは以下のようにします。
try {
var params = JSON.parse(value);
// Validate required parameters
if (!params.URL || !params.TOKEN) {
throw 'Missing required parameters URL or TOKEN';
}
// Create the HTTP request
var req = new HttpRequest();
req.addHeader('Authorization: Splunk ' + params.TOKEN);
req.addHeader('Content-Type: application/json');
// Add Proxy
if(params.HTTPProxy){
req.setProxy(params.HTTPProxy);
}
// Create the data to send to Splunk HEC
var data = JSON.stringify({
event: {
_time: params.EVENT_DATE + ' ' + params.EVENT_TIME,
subject: params.SUBJECT,
severity: params.ALERT_SEVERITY,
hostname: params.HOST,
event_id: params.ID,
opdata: params.OPDATA,
url: params.TRIGGER_URL
},
sourcetype: 'zabbix:alert'
});
// Send the HTTP POST request
var response = req.post(params.URL, data);
if (req.getStatus() != 200) {
throw 'Failed to send data to Splunk HEC: ' + req.getStatus();
}
return 'OK';
} catch (error) {
Zabbix.log(4, '[ Splunk HEC Webhook ] Error: ' + error);
throw 'Splunk HEC Webhook failed: ' + error;
}
5.4以前はこちら(CurlHttpRequestを使用)
try {
var params = JSON.parse(value);
// Validate required parameters
if (!params.URL || !params.TOKEN) {
throw 'Missing required parameters URL or TOKEN';
}
// Create the HTTP request
var req = new CurlHttpRequest();
req.AddHeader('Authorization: Splunk ' + params.TOKEN);
req.AddHeader('Content-Type: application/json');
// Add Proxy
if(params.HTTPProxy){
req.SetProxy(params.HTTPProxy);
}
// Create the data to send to Splunk HEC
var data = JSON.stringify({
event: {
_time: params.EVENT_DATE + ' ' + params.EVENT_TIME,
subject: params.SUBJECT,
severity: params.ALERT_SEVERITY,
hostname: params.HOST,
event_id: params.ID,
opdata: params.OPDATA,
url: params.TRIGGER_URL
},
sourcetype: 'zabbix:alert'
});
// Send the HTTP POST request
var response = req.Post(params.URL, data);
if (req.Status() != 200) {
throw 'Failed to send data to Splunk HEC: ' + req.Status();
}
return 'OK';
} catch (error) {
Zabbix.log(4, '[ Splunk HEC Webhook ] Error: ' + error);
throw 'Splunk HEC Webhook failed: ' + error;
}
Message templateの追加も忘れずに。
デフォルトでよいでしょう。
そしてMediaを紐づけたユーザーにTrigger Actionを設定すれば完了です。
結果例
Splunkで受信できます。
タイムスタンプのフォーマットがなかなかユニークでうまく抽出できてない感があるので、パース用の設定はした方が良さそうですね。
後は同じアラートIDやホストでアラート集約したり、グラフ化したり、他のメトリクスと相関させたり、好きなようにしてください。
おわりに
Zabbixからのデータ取得方法についていくつかパターンをまとめてみました。
Zabbixのデータを活用したいけどどうやって出せばいいんだーとお悩みの方の参考になれば幸いです。