Zabbix3.4の「依存アイテム」機能でZabbixあるあるなアレを解消する


# 概要

Zabbixでディスクの容量をグラフにした時に、 「急激に使用容量が増減したファイルシステムの積算グラフの形状が崩れる」といった経験はありませんか？
![chart2.png](https://qiita-image-store.s3.amazonaws.com/0/20934/36a7d789-5797-3699-710b-463a97db7958.png)
あるファイルシステムの空き容量と使用容量の値を積み上げたグラフであれば合計値が常に一定となることが期待されますが、これまでのZabbixでは(上掲の画像は若干大げさな例ではあるものの)このようにグラフ形状が崩れる場面がありました。

Zabbix3.4で導入された新機能「依存アイテム」を活用すると、これを解決することができます。

# 急激に使用容量が増減したファイルシステムのグラフの形状が崩れる原因
結論から言うと、この現象は空き容量と使用容量の値の取得タイミングの微妙な"ずれ"が原因です。
Zabbixで対象のファイルシステムの空き容量と使用容量の値を取得する際、通常それぞれ別のアイテムとして値の取得が実行され、取得タイミングにはタイムラグが生じます。
この微妙なタイムラグの間にも使用容量が変化しているようなケースでは、二つの値の合計値が一定とならないことが、積算グラフに描画した際に形状が崩れたように見える原因となります。

# 「依存アイテム」について
Zabbix3.4で追加された機能「依存アイテム」を利用すると、サーバーからエージェントに対する複数の値の取得を1個のアイテムによる1回のリクエストで行うことができます。
この複数の値を一度にサーバーに返すことができるアイテムが「マスターアイテム」で、マスターアイテムが取得した結果として複数の値が含まれた値をサーバーに返し、それを元に依存アイテムが「保存前処理」で必要な値を取り出すといった動作になります。
(マスターアイテムの取得値に依存するので「依存アイテム」)

また、従来は個別のアイテム毎に「サーバーからエージェントに対してネットワーク接続を確立しリクエストを送信、エージェント内部で諸処理を実行して値を取得・算出、サーバーに返送」といった処理を必要な値の種類ごとに毎回行っていた所を、依存アイテムを活用すると1回の取得リクエスト、1回の内部処理で必要な値がすべて取得できるようになり、Zabbixエージェントの動作の負荷低減にもつながります。

# 実際にやってみた
しかし、現在のところ、Zabbixエージェントにはこの依存アイテムを利用するためのマスターアイテムに相当する処理が実装されていないので、
ここでは従来の方法によるアイテムキー`dev.fs.size`と同様の値を取得するマスターアイテムを、ローダブルモジュール機能を使って実装してみました
作成したプログラム、テンプレートは  https://github.com/mutz0623/zabbix_dependent-fssize にあります。

ソースコードなどの詳細についてはリンク先を見ていただくとして、今回作成したアイテムの動作は下記のようになります。

- サーバーからマスターアイテムに対するリクエストを受け取ったエージェントプロセスが、内部でstatvfs関数を実行し、Total,Free,Used,Free(%),Used(%)の値を取得・計算し、JSONにデータを格納してまとめてサーバーに返送
- サーバー側では、JSON形式のテキストデータとして受け取った値を元に、個別の依存アイテムで「保存前処理」の「JSON Path」で値を取り出す
    - 依存アイテムで処理されたアイテムはマスターアイテムのタイムスタンプを継承してすべて同じタイムスタンプとして記録される
    - 1回のシステムコール呼び出し等で取得された値を元に算出するので、合計値も一定
    - よって使用容量が急激に増減しても積算グラフでそれぞれの値を積み重ねた結果も一定となり、グラフの形状も一定となる


ここではマスターアイテムが複数の値を保持する方法としてJSON形式としましたが、保存前処理で必要な値が取り出せればJSONである必要はなく、XML pathや正規表現などでも同様の処理が可能です。

## 動作の様子
実際にテスト環境で今回作成したローダブルモジュールをZabbixエージェントにロードさせた状態で、`zabbix_get`コマンドで値を取得してみるとこのようになります。(`jq`コマンドでフォーマットを見やすくしています)

```shell-session
$ zabbix_get -s 127.0.0.1 -k  vfs.fs.size.master[/testdata] |jq .
{
  "FS_NAME": "/testdata",
  "FS_TOTAL": 8271605760,
  "FS_FREE": 8271605760,
  "FS_USED": 0,
  "FS_PFREE": 100,
  "FS_PUSED": 0
}
```

このマスターアイテムと、マスターアイテムの取得結果を利用する依存アイテム、それらの結果をもとにしたグラフを設定し、ディスクの空き容量を急激に増減させてみた結果得られたグラフが下記の通りです。

- tmpfsで`/testdata`ディレクトリにマウントしたファイルシステムに対して、ddコマンドでのファイル作成、削除を繰り返し実行



![chart2_1.png](https://qiita-image-store.s3.amazonaws.com/0/20934/2ef924af-0164-000f-f702-67b38cb47b98.png)
![chart2_2.png](https://qiita-image-store.s3.amazonaws.com/0/20934/dd533724-b47d-959b-8dbd-284b5e3fe66c.png)


グラフ上段が従来のアイテム(`vfs.fs.size[]`)、下段が今回作成したマスターアイテムに対する依存アイテムで取得・収集した結果を積算グラフにしたものです。
ディスクの使用割合が急激に増減した際のグラフ形状に明らかな差が見られます。

# まとめ
Zabbix3.4の新機能「依存アイテム」は、これまでのZabbixが抱えていた問題を解決することができます。
また、依存アイテム機能の重要な利点として、Zabbixエージェントの負荷の低減が挙げられます。
今回はディスクの使用量に絞って説明しましたが、「複数の値を一度に取得すること」による諸々のメリットは様々な値の取得で享受出来るものです。

# 参考
- 公式マニュアル
    - 
 https://www.zabbix.com/documentation/3.4/manual/config/items/itemtypes/dependent_items
    - https://www.zabbix.com/documentation/3.4/manual/config/items/item#item_value_preprocessing
- 依存アイテムの活用事例
    - http://blog.zabbix.com/zabbix-3-4-mass-data-collection-using-mercury-and-smartmontools-as-an-example/5784/