1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ZabbixのデータをSplunkに取り込む方法あれこれ

Last updated at Posted at 2024-08-14

はじめに

ZabbixのデータをSplunkに取り込んで色々可視化をしたいと思ったことはあるはずです。
じゃあどうすればいいか?
なかなか情報が無かったのでまとめてみました。

以下方法を見てみます。

・リアルタイムエクスポート
・DBクエリ
・アラート(Media Type)

Zabbixデータの取込方法

リアルタイムエクスポートでZabbixデータを即時連携

Zabbix v4.0以降でトリガーイベント、アイテム値、トレンドデータをリアルタイムでJSON形式でエクスポートできます。
簡単にデータを出力しSplunkに取り込むことが可能なので最もおすすめです。

設定手順

  1. /etc/zabbix/zabbix_server.confのexportDirを設定します。このディレクトリにProblem、Item、Trendのデータが出力されます
  2. データサイズが大きくなりがちなので、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で出力データを取り込めばよいでしょう。

image.png

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に送信することができます。
※アイディア、スクリプトはとある方から頂いたものです。ありがとうございます!

image.png

設定手順

  1. SplunkでHECを作成してください

  2. 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は以下のようにします。

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を使用)
Script 5.4以前
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の追加も忘れずに。
デフォルトでよいでしょう。

image.png

そしてMediaを紐づけたユーザーにTrigger Actionを設定すれば完了です。

image.png

結果例

Splunkで受信できます。
タイムスタンプのフォーマットがなかなかユニークでうまく抽出できてない感があるので、パース用の設定はした方が良さそうですね。

image.png

後は同じアラートIDやホストでアラート集約したり、グラフ化したり、他のメトリクスと相関させたり、好きなようにしてください。

おわりに

Zabbixからのデータ取得方法についていくつかパターンをまとめてみました。
Zabbixのデータを活用したいけどどうやって出せばいいんだーとお悩みの方の参考になれば幸いです。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?