[comment]: # ({c34725dc-f445d963})
# 予測トリガー関数

[comment]: # ({/c34725dc-f445d963})

[comment]: # ({9dac6d6d-9dac6d6d})
#### 概要

時には、問題が発生する前兆が現れることがあります。これらの兆候を見つけることで、問題の影響を防ぐ、あるいは少なくとも最小限に抑えるための対策を事前に講じることができます。

Zabbixには、過去のデータに基づいて監視対象システムの将来の動作を予測するためのツールがあります。これらのツールは、予測トリガー関数として実現されています。

[comment]: # ({/9dac6d6d-9dac6d6d})

[comment]: # ({827f1d5f-24b155a7})
#### 関数

トリガーを設定する前に、問題状態が何であるか、そしてアクションを実行するのにどれだけの時間が必要かを定義する必要があります。その後、潜在的な望ましくない状況を通知するトリガーを設定する方法は2つあります。1つ目は、「アクションを実行するまでの時間」後にシステムが問題状態になると予想される場合にトリガーを発火させる方法です。2つ目は、システムが「アクションを実行するまでの時間」未満で問題状態に到達しそうな場合にトリガーを発火させる方法です。対応するトリガー関数は**forecast**と**timeleft**です。両関数で使用される統計分析は基本的に同じであることに注意してください。どちらの方法でも、ほぼ同じ結果でトリガーを設定できます。

[comment]: # ({/827f1d5f-24b155a7})

[comment]: # ({9f0f6aee-c80922f6})
#### パラメータ

両方の関数はほぼ同じパラメータセットを使用します。参照用に[サポートされている関数](/manual/config/triggers/expression#functions)のリストを使用してください。

[comment]: # ({/9f0f6aee-c80922f6})

[comment]: # ({33e199b9-a93b071e})
##### 時間間隔

まず、Zabbixが予測を行うために分析する履歴期間を指定する必要があります。これは、**avg**、**count**、**delta**、**max**、**min**、**sum**関数と同様に、`時間間隔`パラメータとオプションの時間シフトを使用して指定します。

[comment]: # ({/33e199b9-a93b071e})

[comment]: # ({55d83c24-b922d0f2})
##### 予測期間

（**forecast** のみ）<br>
パラメータ `time` は、履歴データ内で見つかった依存関係を、Zabbix が将来のどこまで外挿するかを指定します。`time_shift` を使用するかどうかにかかわらず、`time` は常に現在時刻を起点としてカウントされます。

[comment]: # ({/55d83c24-b922d0f2})

[comment]: # ({1ccaacd1-625c0c85})
##### 到達すべきしきい値

（**timeleft** のみ）<br>
パラメータ `threshold` は、解析対象のアイテムが到達しなければならない値を指定します。上側から到達するか下側から到達するかの違いはありません。f(t) が決定されたら
（以下を参照）、方程式 f(t) = `threshold` を解き、現在に最も近く、かつ現在より右側にある根を返す必要があります。そのような根が存在しない場合は
1.7976931348623158E+308 を返します。

::: notetip
アイテムの値がしきい値に近づいた後にそれを横切る場合、
**timeleft** はその交点はすでに過去にあるとみなし、
そのため、存在する場合は `threshold` レベルとの次の交点に切り替えます。
ベストプラクティスとして、予測は通常の障害診断の代替ではなく、補完として使用する必要があります。^[1](#footnotes)^
:::

[comment]: # ({/1ccaacd1-625c0c85})

[comment]: # ({4d1deb86-976bd98e})
##### フィット関数

デフォルトの`fit`は*linear*関数です。しかし、監視対象のシステムがより複雑な場合は、他のオプションを選択することもできます。

|`fit`|x = f(t)|
|-----|--------|
|*linear*|x = a + b\*t|
|*polynomialN*^[2](#footnotes)^|x = a~0~ + a~1~\*t + a~2~\*t^2^ + ... + a~n~\*t^n^|
|*exponential*|x = a\*exp(b\*t)|
|*logarithmic*|x = a + b\*log(t)|
|*power*|x = a\*t^b^|

[comment]: # ({/4d1deb86-976bd98e})

[comment]: # ({3c1c1442-add67840})
##### モード

(**forecast** のみ)<br>
トリガー関数が評価されるたびに、指定された履歴期間のデータを取得し、そのデータに指定された関数を当てはめます。したがって、データがわずかに異なれば、当てはめられる関数もわずかに異なります。単純に将来の指定時刻における当てはめ関数の値を計算するだけでは、現在からその将来時点までの間に、分析対象のアイテムがどのように振る舞うと予想されるかは分かりません。`fit` の一部のオプション（*polynomial* など）では、将来の単純な値は誤解を招く可能性があります。

|`mode`|**forecast** の結果|
|------|-------------------|
|*value*|f(now + `time`)|
|*max*|max~now\ <=\ t\ <=\ now\ +\ `time`~ f(t)|
|*min*|min~now\ <=\ t\ <=\ now\ +\ `time`~ f(t)|
|*delta*|*max* - *min*|
|*avg*|[定義](https://en.wikipedia.org/wiki/Mean_of_a_function) に従った f(t) の平均値（now <= t <= now + `time`）|

[comment]: # ({/3c1c1442-add67840})

[comment]: # ({3f946ebf-5ff2285e})
#### 詳細

巨大な数値での計算を避けるために、指定された期間の最初の値のタイムスタンプに1nsを加えたものを新しいゼロタイム（現在のエポックタイムは10^9^オーダー、エポックの2乗は10^18^、倍精度は約10^-16^）とみなします。*対数*や*べき乗*近似ではlog(t)の計算が含まれるため、すべての時間値を正にするために1nsを加えます。時間のシフトは*線形*、*多項式*、*指数*（より簡単で正確な計算を除く）には影響しませんが、*対数*や*べき乗*関数の形状を変化させます。

[comment]: # ({/3f946ebf-5ff2285e})

[comment]: # ({d180bad2-660cda6b})
#### 起こりうるエラー

関数は以下のような場合に-1を返します:

-   指定した評価期間にデータが存在しない場合
-   数学的な演算の結果が定義されていない場合^[3](#footnotes)^
-   数値的な問題（残念ながら、入力データの組み合わせによっては、倍精度浮動小数点形式の範囲や精度が不十分になる場合があります）^[4](#footnotes)^

::: notetip
選択したフィットが提供されたデータをうまく表現できない場合や、正確な予測に十分なデータがない場合でも、警告やエラーは表示されません。
:::

[comment]: # ({/d180bad2-660cda6b})

[comment]: # ({e57d3e18-06e0a230})
#### 例とエラーへの対処

ホストのディスク空き容量が不足しそうな場合に警告を受け取るには、次のようなトリガー式を使用できます。

    timeleft(/host/vfs.fs.size[/,free],1h,0)<1h

ただし、エラーコード-1が発生し、トリガーが障害状態になる場合があります。一般的には、予測が正しく機能していないことを警告してくれるので良いことですが、なぜそうなったのかを詳しく調べる必要があります。しかし、-1は単に過去1時間以内にホストのディスク空き容量のデータが取得できなかったことを意味する場合もあります。誤検知のアラートが多すぎる場合は、より複雑なトリガー式の使用を検討してください ^[5](#footnotes)^:

    timeleft(/host/vfs.fs.size[/,free],1h,0)<1h and timeleft(/host/vfs.fs.size[/,free],1h,0)<>-1

**forecast**の場合は少し状況が複雑です。まず、-1がトリガーを障害状態にするかどうかは、`forecast(/host/item,(...))<...`のような式か、`forecast(/host/item,(...))>...`のような式かによって異なります。

さらに、アイテム値が負になることが通常であれば、-1は有効な予測値となる場合もあります。しかし、現実の運用ではこのような状況はほとんどありません（演算子**=**の動作については[こちら](/manual/config/triggers/expression)を参照）。したがって、-1を障害とみなしたい場合は`... or forecast(/host/item,(...))=-1`を、みなしたくない場合は`... and forecast(/host/item,(...))<>-1`を追加してください。

#### 脚注

^**1**^ 例えば、`timeleft(/host/item,1h,X) < 1h`のような単純なトリガーは、アイテム値がXに近づくと障害状態になり、値がXに達すると突然復旧する場合があります。問題がアイテム値がX未満である場合は、`last(/host/item) < X or timeleft(/host/item,1h,X) < 1h`を、アイテム値がXより大きい場合は`last(/host/item) > X or timeleft(/host/item,1h,X) < 1h`を使用してください。

^**2**^ 多項式の次数は1から6まで指定でき、*polynomial1*は*linear*と同じです。ただし、高次の多項式は[注意して](https://en.wikipedia.org/wiki/Runge's_phenomenon)使用してください。評価期間内のポイント数が多項式係数の決定に必要な数より少ない場合は、多項式の次数が下げられます（例：*polynomial5*が指定されているがポイントが4つしかない場合、*polynomial3*が適用されます）。

^**3**^ 例えば、*exponential*や*power*関数のフィッティングでは、アイテム値のlog()計算が必要です。データにゼロや負の値が含まれている場合、log()は正の値にしか定義されていないためエラーになります。

^**4**^ *linear*、*exponential*、*logarithmic*、*power*の各フィットでは、必要な計算をすべて明示的に記述できます。*polynomial*では*value*のみ追加の手順なしで計算できます。*avg*の計算には多項式の不定積分（解析的）が必要です。*max*、*min*、*delta*の計算には多項式の導関数（解析的）とその根の探索（数値的）が必要です。f(t) = 0の解法には多項式の根の探索（数値的）が必要です。

^**5**^ ただし、この場合-1によってトリガーが障害状態から復旧することがあります。完全に保護したい場合は、`timeleft(/host/vfs.fs.size[/,free],1h,0)<1h and ({TRIGGER.VALUE}=0 and timeleft(/host/vfs.fs.size[/,free],1h,0)<>-1 or {TRIGGER.VALUE}=1)`を使用してください。

[comment]: # ({/e57d3e18-06e0a230})
