[comment]: # ({c34725dc-f445d963})
# Funções preditivas de trigger

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

[comment]: # ({9dac6d6d-9dac6d6d})
#### Visão geral

Às vezes, há sinais de um problema iminente. Esses sinais podem ser
detectados para que ações possam ser tomadas com antecedência para evitar ou pelo menos
minimizar o impacto do problema.

O Zabbix possui ferramentas para prever o comportamento futuro do sistema monitorado
com base em dados históricos. Essas ferramentas são implementadas por meio de funções preditivas de trigger.

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

[comment]: # ({827f1d5f-24b155a7})
#### Funções

Antes de definir um trigger, é necessário definir o que é um estado de problema e quanto tempo é necessário para agir. Em seguida, existem duas maneiras de configurar um trigger que sinalize uma situação potencialmente indesejada. Primeiro: o trigger deve disparar quando se espera que o sistema esteja em um estado de problema após o "tempo para agir". Segundo: o trigger deve disparar quando o sistema estiver prestes a atingir o estado de problema em menos de "tempo para agir". As funções de trigger correspondentes a serem usadas são **forecast** e **timeleft**. Observe que a análise estatística subjacente é basicamente idêntica para ambas as funções. Você pode configurar um trigger de qualquer maneira que preferir, com resultados semelhantes.

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

[comment]: # ({9f0f6aee-c80922f6})
#### Parâmetros

Ambas as funções usam quase o mesmo conjunto de parâmetros. Use a lista de
[funções suportadas](/manual/config/triggers/expression#functions) como referência.

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

[comment]: # ({33e199b9-a93b071e})
##### Intervalo de tempo

Primeiramente, você deve especificar o período histórico que o Zabbix deve analisar para gerar a previsão. Você faz isso de uma maneira familiar, por meio do parâmetro `período de tempo` e de um deslocamento de tempo opcional, assim como faz com as funções **avg**, **count**, **delta**, **max**, **min** e **sum**.

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

[comment]: # ({55d83c24-b922d0f2})
##### Horizonte de previsão

(**forecast** apenas)<br>
O parâmetro `time` especifica até onde no futuro o Zabbix deve extrapolar as dependências encontradas nos dados históricos. Não importa se você usa `time_shift` ou não, `time` é sempre contado a partir do momento atual.

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

[comment]: # ({1ccaacd1-625c0c85})
##### Limite a ser atingido

(**timeleft** apenas)<br>
O parâmetro `threshold` especifica um valor que o item analisado deve atingir,
não importa se de cima para baixo ou de baixo para cima. Uma vez que determinamos f(t)
(veja abaixo), devemos resolver a equação f(t) = `threshold` e retornar a
raiz que está mais próxima de agora e à direita de agora ou
1.7976931348623158E+308 se não houver tal raiz.

::: notetip
Quando os valores do item se aproximam do limite e depois o cruzam,
**timeleft** assume que a interseção já está no passado e,
portanto, muda para a próxima interseção com o nível `threshold`, se
houver. A melhor prática deve ser usar previsões como complemento ao
diagnóstico de problemas comum, não como substituição.^[1](#footnotes)^
:::

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

[comment]: # ({4d1deb86-976bd98e})
##### Funções de ajuste

O `fit` padrão é a função *linear*. Mas se o seu sistema monitorado for
mais complicado, você tem mais opções para escolher.

|`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})
##### Modos

(**forecast** apenas)<br>
Toda vez que uma função de trigger é avaliada, ela obtém dados do
período de histórico especificado e ajusta uma função especificada aos dados. Assim,
se os dados forem ligeiramente diferentes, a função ajustada será ligeiramente
diferente. Se simplesmente calcularmos o valor da função ajustada em um
momento especificado no futuro, você não saberá nada sobre como o
item analisado deve se comportar entre agora e aquele momento no
futuro. Para algumas opções de `fit` (como *polynomial*) um valor simples do
futuro pode ser enganoso.

|`mode`|**forecast** resultado|
|------|----------------------|
|*value*|f(agora + `time`)|
|*max*|max~agora\ <=\ t\ <=\ agora\ +\ `time`~ f(t)|
|*min*|min~agora\ <=\ t\ <=\ agora\ +\ `time`~ f(t)|
|*delta*|*max* - *min*|
|*avg*|média de f(t) (agora <= t <= agora + `time`) de acordo com a [definição](https://en.wikipedia.org/wiki/Mean_of_a_function)|

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

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

Para evitar cálculos com números muito grandes, consideramos o timestamp do primeiro valor no período especificado mais 1 ns como um novo tempo zero (o tempo de época atual está na ordem de 10^9^, a época ao quadrado é 10^18^, a precisão dupla é cerca de 10^-16^). 1 ns é adicionado para fornecer todos os valores de tempo positivos para os ajustes *logarítmico* e *potência*, que envolvem o cálculo de log(t). O deslocamento de tempo não afeta os ajustes *linear*, *polinomial*, *exponencial* (além de cálculos mais fáceis e precisos), mas altera a forma das funções *logarítmica* e *potência*.

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

[comment]: # ({d180bad2-660cda6b})
#### Possíveis erros

As funções retornam -1 nas seguintes situações:

-   o período de avaliação especificado não contém dados;
-   o resultado da operação matemática não está definido^[3](#footnotes)^;
-   complicações numéricas (infelizmente, para alguns conjuntos de dados de entrada,
    o intervalo e a precisão do formato de ponto flutuante de dupla precisão tornam-se
    insuficientes)^[4](#footnotes)^.

::: notetip
Nenhum aviso ou erro é sinalizado se o ajuste escolhido descrever
mal os dados fornecidos ou se houver poucos dados para uma previsão
precisa.
:::

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

[comment]: # ({e57d3e18-06e0a230})
#### Exemplos e tratamento de erros

Para receber um aviso quando você estiver prestes a ficar sem espaço livre em disco no
seu host, você pode usar uma expressão de trigger como esta:

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

No entanto, o código de erro -1 pode entrar em ação e colocar seu trigger em um
estado de problema. Geralmente isso é bom porque você recebe um aviso de que suas
previsões não estão funcionando corretamente e deve analisá-las mais
cuidadosamente para descobrir o motivo. Mas às vezes isso é ruim porque -1 pode simplesmente
significar que não houve dados sobre o espaço livre em disco do host obtidos na
última hora. Se você estiver recebendo muitos alertas falsos positivos,
considere usar uma expressão de trigger mais complicada ^[5](#footnotes)^:

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

A situação é um pouco mais difícil com **forecast**. Antes de tudo,
-1 pode ou não colocar o trigger em estado de problema, dependendo de
você ter uma expressão como `forecast(/host/item,(...))<...` ou
como `forecast(/host/item,(...))>...`

Além disso, -1 pode ser uma previsão válida se for normal para o valor do item
ser negativo. Mas a probabilidade dessa situação no mundo real é insignificante (veja
[como](/manual/config/triggers/expression) o operador **=** funciona). Portanto,
adicione `... or forecast(/host/item,(...))=-1` ou
`... and forecast(/host/item,(...))<>-1` se você quiser ou não quiser
tratar -1 como um problema, respectivamente.

#### Notas de rodapé

^**1**^ Por exemplo, um trigger simples como
    `timeleft(/host/item,1h,X) < 1h` pode entrar em estado de problema quando o
    valor do item se aproxima de X e, em seguida, se recuperar repentinamente assim que o valor X for
    atingido. Se o problema for o valor do item estar abaixo de X, use:
    `last(/host/item) < X or timeleft(/host/item,1h,X) < 1h` Se o
    problema for o valor do item estar acima de X, use:
    `last(/host/item) > X or timeleft(/host/item,1h,X) < 1h`

^**2**^ O grau do polinômio pode ser de 1 a 6, *polynomial1* é equivalente
    a *linear*. No entanto, use polinômios de grau mais alto [com
    cautela](https://en.wikipedia.org/wiki/Runge's_phenomenon). Se o
    período de avaliação contiver menos pontos do que o necessário para determinar
    os coeficientes do polinômio, o grau do polinômio será reduzido (por exemplo,
    *polynomial5* é solicitado, mas há apenas 4 pontos, portanto
    *polynomial3* será ajustado).

^**3**^ Por exemplo, ajustar funções *exponential* ou *power* envolve
    calcular log() dos valores do item. Se os dados contiverem zeros ou números negativos,
    você receberá um erro, pois log() é definido apenas para valores positivos.

^**4**^ Para ajustes *linear*, *exponential*, *logarithmic* e *power* todos os
    cálculos necessários podem ser escritos explicitamente. Para *polynomial*
    apenas *value* pode ser calculado sem etapas adicionais.
    Calcular *avg* envolve computar a antiderivada do polinômio
    (analiticamente). Calcular *max*, *min* e *delta* envolve
    computar a derivada do polinômio (analiticamente) e encontrar suas raízes
    (numericamente). Resolver f(t) = 0 envolve encontrar as raízes do polinômio
    (numericamente).

^**5**^ Mas, neste caso, -1 pode fazer com que seu trigger se recupere do
    estado de problema. Para estar totalmente protegido, use:
    `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})
