採用情報

お問い合わせ

BLOG

Zabbix テック・ラウンジ

2019 年 01 月 29 日

Zabbix 3.2以降の新機能解説(Zabbix 4.0を見据えて) その20 - MIRACLE ZBXの1.8エージェントのObsolete

こんにちは、MIRACLE ZBX サポートを担当している花島タケシです。今回は、MIRACLE ZBX では 1.8 エージェントは Obsolete とするのと、その理由について解説します。

MIRACLE ZBX では 1.8 エージェントは動作対象としません

今回は新機能というより、サポートする動作環境の話です。

以前から、Trapper プロセスが Zabbix エージェントやプロキシからデータを受け付けるときに、監視時刻の調整機能が実装されていました。

この機能ですが、あまり良くない振る舞いもしていたわけです。そもそも、エージェントやプロキシの時刻を NTP 等を用いて正しく合わせてさえおけば不要な機能であるわけですし。

では、なぜ 1.8 エージェントだけを対象外とするのか?ということを、ソースコードを用いて解説を行います。

時刻調節の機能は実はなくなっていない

既に 4.0.1 がリリース済みですので、こちらを用いて解説を行います。
エージェントのアクティブ監視データやアクティブプロキシからのデータの受付は、Trapper プロセスが請け負います。何度となく、受付からキャッシュへ入れるフローは説明してあるため、詳細は省きますが、src/libs/zbxdbhigh/proxy.c : process_client_history_data() がコールされます。

最初に従来のコード (3.4.15) を見ていきます。

3043 static int process_client_history_data(zbx_socket_t *sock, struct zbx_json_parse *jp, zbx_timespec_t *ts,
3044 zbx_client_item_validator_t validator_func, void *validator_args, char **info)
3045 {
...
3061 if (SUCCEED != get_client_timediff(jp, ts, &client_timediff))
3062 {
3063 client_timediff.sec = 0;
3064 client_timediff.ns = 0;
3065 }
...
3079 while (SUCCEED == parse_history_data(&jp_data, &pnext, values, hostkeys, &values_num, &read_num,
3080 &client_timediff, &error) && 0 != values_num)
3081 {

処理開始直後に、get_client_timediff() をコールして、受け取ったデータのタイムスタンプと受け取った時刻から時間差 (client_timediff) を計算しています。
そして、parse_history_data() にてその時間差を渡し、最終的には parse_history_data_row_value() にて監視時刻の調節が行われます。

次に、最新のコード (4.0.1) となります。

3061 static int process_client_history_data(zbx_socket_t *sock, struct zbx_json_parse *jp, zbx_timespec_t *ts,
3062 zbx_client_item_validator_t validator_func, void *validator_args, char **info)
3063 {
...
3082 log_client_timediff(LOG_LEVEL_DEBUG, jp, ts);
...
3109 while (SUCCEED == parse_history_data(&jp_data, &pnext, values, hostkeys, &values_num, &read_num,
3110 &unique_shift, &error) && 0 != values_num)
3111 {

get_client_timediff() の呼び出しはなくなり、log_client_timediff() が現れています。この関数は上記の時間差をログに出力するだけで、監視データには全く影響はありません。DebugLevel=4 以上で出力されます。

次に、従来時刻調節が行われていた parse_history_data_row_value() を見てみます。

2598 static int parse_history_data_row_value(const struct zbx_json_parse *jp_row, zbx_timespec_t *unique_shift,
2599 zbx_agent_value_t *av)
2600 {
...
2607 if (SUCCEED == zbx_json_value_by_name_dyn(jp_row, ZBX_PROTO_TAG_CLOCK, &tmp, &tmp_alloc))
2608 {
2609 if (FAIL == is_uint31(tmp, &av->ts.sec))
2610 goto out;
2611
2612 if (SUCCEED == zbx_json_value_by_name_dyn(jp_row, ZBX_PROTO_TAG_NS, &tmp, &tmp_alloc))
2613 {
2614 if (FAIL == is_uint_n_range(tmp, tmp_alloc, &av->ts.ns, sizeof(av->ts.ns),
2615 0LL, 999999999LL))
2616 {
2617 goto out;
2618 }
2619 }
2620 else
2621 {
2622 /* ensure unique value timestamp (clock, ns) if only clock is available */
2623
2624 av->ts.sec += unique_shift->sec;
2625 av->ts.ns = unique_shift->ns++;
2626
2627 if (unique_shift->ns > 999999999)
2628 {
2629 unique_shift->sec++;
2630 unique_shift->ns = 0;
2631 }
2632 }
2633 }
2634 else
2635 zbx_timespec(&av->ts);

送られてきたデータに ZBX_PROTO_TAG_CLOCK タグが存在し、ZBX_PROTO_TAG_NS タグも存在する場合は何もせずにブロックから抜けます。
そうでなく、ZBX_PROTO_TAG_CLOCK タグは存在するが、ZBX_PROTO_TAG_NS タグは存在しない場合は、監視時刻に調節がされています。

ZBX_PROTO_TAG_NS タグがないデータって ?

Zabbix 2.0 から監視時刻がナノ秒レベルで取得できるようになりました。
つまり、1.8 までは秒レベルということになります。1.8 のエージェントがアクティブ監視データを送ってくるときには、ZBX_PROTO_TAG_NS タグが付与されていないデータとなります。

もう少し、上記のコードを読み進めていきましょう。
そもそも時間調節のための変数 unique_shift は、下記のように呼び出し元で宣言されます。

3061 static int process_client_history_data(zbx_socket_t *sock, struct zbx_json_parse *jp, zbx_timespec_t *ts,
3062 zbx_client_item_validator_t validator_func, void *validator_args, char **info)
3063 {
3064 const char *__function_name = "process_client_history_data";
3065
3066 int ret, values_num, read_num, processed_num = 0, total_num = 0, i;
3067 struct zbx_json_parse jp_data;
3068 zbx_timespec_t unique_shift = {0, 0};

初期値は調節なしです。

そして、エージェントからのデータはある程度のブロックで送られてきます。
ログ・イベントログの監視データに関しては、それらだけを監視しているなら、SendBuffer パラメータの半分がまとめて送られてきます。

このある程度まとまって受け取り、それを上記の調節ルーチンで処理されると、受け取るデータは下記のように 1ns ずつずれたものとなります。

0 データ 0 xx 秒 + 0ns
1 データ 1 xx 秒 + 1ns
2 データ 2 xx 秒 + 2ns
...

これだけでは何ら問題ありません。

ただし、ログ監視において 1 秒以内に SendBuffer の半分を越えて出力された場合を考えましょう。SendBuffer を 100 とすると下記のようになります。

0 データ 0 xx 秒 + 0ns
1 データ 1 xx 秒 + 1ns
2 データ 2 xx 秒 + 2ns
...

以下別ブロック
50 データ 50 xx 秒 + 0ns
51 データ 51 xx 秒 + 1ns
52 データ 52 xx 秒 + 2ns
...

ns レベルまで監視時刻が同じデータを取得することとなります。
これは、トリガー判定やイベント表示で誤ったデータを用いてしまうことになります。

こういった理由から、MIRACLE ZBX では 1.8 エージェントを動作対象としないこととしました。上記は 1.8 プロキシでも同じことが発生します。

なお、既に ZBX-14715 にて修正パッチと共に報告を行いましたが、Zabbix LLC も対応しないとのことです。

関連記事

Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 1
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 2
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 3
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 4
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 5
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 6
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 7
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 8
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 9
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 10
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 11
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 12
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 13
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 14
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 15
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 16
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 17
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 18
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 19
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 20
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 21

注意事項

  • 本ドキュメントの内容は、予告なしに変更される場合があります。
  • 本ドキュメントは、限られた評価環境における検証結果をもとに作成しており、全ての環境での動作を保証するものではありません。
  • 本ドキュメントの内容に基づき、導入、設定、運用を行なったことにより損害が生じた場合でも、当社はその損害についての責任を負いません。あくまでお客さまのご判断にてご使用ください。
CentOS 7 延長サポートサービス
デジタルトランスフォーメーションのための電子認証基盤 iTrust
SSL/TLS サーバー証明書 SureServer Prime