[comment]: # ({42979355-213e862c})
# 5 Pré-processamento JavaScript

[comment]: # ({/42979355-213e862c})

[comment]: # ({85dbf118-57d3be9d})
### Visão geral

Esta seção fornece detalhes do pré-processamento por JavaScript.

:::noteimportant
Não use atribuições não declaradas em JavaScript de pré-processamento.
Use `var` para declarar variáveis locais.
:::

[comment]: # ({/85dbf118-57d3be9d})

[comment]: # ({1a912b43-076d2285})
### Pré-processamento JavaScript

O pré-processamento JavaScript é feito invocando uma função JavaScript com um único parâmetro 'value' e o corpo da função fornecido pelo usuário.
O resultado da etapa de pré-processamento é o valor retornado por essa função, por exemplo, para realizar a conversão de Fahrenheit para Celsius, insira:

```javascript
return (value - 32)  * 5 / 9
```

nos parâmetros de pré-processamento JavaScript, que serão encapsulados em uma função JavaScript pelo server:

```javascript
function (value)
{
   return (value - 32) * 5 / 9
}
```

O parâmetro de entrada 'value' é sempre passado como uma string.
O valor de retorno é automaticamente convertido para string via método toString() (se falhar, o erro é retornado como valor string), com algumas exceções:

-   retornar um valor undefined resultará em erro;
-   retornar um valor null fará com que o valor de entrada seja descartado, assim como o pré-processamento 'Descartar valor' na ação 'Personalizado em caso de falha'.

Erros podem ser retornados lançando valores/objetos (normalmente strings ou objetos Error).

Por exemplo:

```javascript
if (value == 0)
    throw "Zero input value"
return 1/value
```

Cada script tem um tempo limite de execução de 10 segundos (dependendo do script, pode levar mais tempo para o tempo limite ser acionado); excedê-lo retornará erro.
Um limite de heap de 512 megabytes é imposto.

O bytecode da etapa de pré-processamento JavaScript é armazenado em cache e reutilizado quando a etapa é aplicada na próxima vez.
Quaisquer alterações nas etapas de pré-processamento do item farão com que o script em cache seja redefinido e recompilado posteriormente.

Falhas consecutivas em tempo de execução (3 seguidas) farão com que o mecanismo seja reinicializado para mitigar a possibilidade de um script quebrar o ambiente de execução para os próximos scripts (essa ação é registrada com DebugLevel 4 ou superior).

O pré-processamento JavaScript é implementado com o mecanismo JavaScript [Duktape](https://duktape.org/).

Veja também: [Objetos JavaScript adicionais e funções globais](/manual/config/items/preprocessing/javascript/javascript_objects)

[comment]: # ({/1a912b43-076d2285})

[comment]: # ({252e5496-c932b901})
##### Usando macros em scripts

É possível usar macros de usuário (assim como [macros LLD](/manual/config/macros/lld_macros) no contexto de descoberta de baixo nível) no código JavaScript.
Se um script contiver macros de usuário, essas macros são resolvidas pelo server/proxy antes de executar etapas específicas de pré-processamento.
Observe que, ao testar etapas de pré-processamento no frontend, os valores das macros não serão buscados e precisarão ser inseridos manualmente.

::: noteclassic
O contexto é ignorado quando uma macro é substituída por seu valor.
O valor da macro é inserido no código como está, não é possível adicionar escape adicional antes de colocar o valor no código JavaScript.
Esteja ciente de que isso pode causar erros de JavaScript em alguns casos.
:::

No exemplo abaixo, se o valor recebido exceder o valor da macro {$THRESHOLD}, o valor do limite (se presente) será retornado:

```javascript
var threshold = '{$THRESHOLD}';
return (!isNaN(threshold) && value > threshold) ? threshold : value;
```

[comment]: # ({/252e5496-c932b901})

[comment]: # ({023bc14f-6a424b72})
### Exemplos

Os exemplos a seguir ilustram como você pode usar o pré-processamento em JavaScript.

Cada exemplo contém uma breve descrição, um corpo de função para os parâmetros de pré-processamento em JavaScript e o resultado da etapa de pré-processamento - valor retornado pela função.

[comment]: # ({/023bc14f-6a424b72})

[comment]: # ({565e57c6-ae8e02fb})
##### Exemplo 1: Converter um número (notação científica para inteiro)

Converta o número "2.62128e+07" da notação científica para um inteiro.

```javascript
return (Number(value))
```

Valor retornado pela função: 26212800.

[comment]: # ({/565e57c6-ae8e02fb})

[comment]: # ({5a30e4ee-f6e6bf55})
##### Exemplo 2: Converter um número (binário para decimal)

Converta o número binário "11010010" para um número decimal.

```javascript
return(parseInt(value,2))
```

Valor retornado pela função: 210.

[comment]: # ({/5a30e4ee-f6e6bf55})

[comment]: # ({35ba7ead-6ca17bad})
##### Exemplo 3: Arredondar um número

Arredonde o número "18.2345" para 2 dígitos.

```javascript
return(Math.round(value* 100) / 100)
```

Valor retornado pela função: 18.23.

[comment]: # ({/35ba7ead-6ca17bad})

[comment]: # ({d27ba472-7385d4e0})
##### Exemplo 4: Contar letras em uma string

Conta o número de letras na string "Zabbix".

```javascript
return (value.length)
```

Valor retornado pela função: 6.

[comment]: # ({/d27ba472-7385d4e0})

[comment]: # ({a521a081-47caadc8})
##### Exemplo 5: Obter o tempo restante

Obtenha o tempo restante (em segundos) até a data de expiração de um certificado (12 de fevereiro de 2022 12:33:56 GMT).

```javascript
var split = value.split(' '),
    MONTHS_LIST = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
    month_index = ('0' + (MONTHS_LIST.indexOf(split[0]) + 1)).slice(-2),
    ISOdate = split[3] + '-' + month_index + '-' + split[1] + 'T' + split[2],
    now = Date.now();

return parseInt((Date.parse(ISOdate) - now) / 1000);
```

Valor retornado pela função: 44380233.

[comment]: # ({/a521a081-47caadc8})

[comment]: # ({f91807bf-fef95b5b})
##### Exemplo 6: Remover propriedades JSON

Modifique a estrutura de dados JSON removendo quaisquer propriedades com a chave `"data_size"` ou `"index_size"`.

```javascript
var obj=JSON.parse(value);

for (i = 0; i < Object.keys(obj).length; i++) {
    delete obj[i]["data_size"];
    delete obj[i]["index_size"];
}

return JSON.stringify(obj)
```

Valor aceito pela função:

```json
[
    {
        "table_name":"history",
        "data_size":"326.05",
        "index_size":"174.34"
    },
    {
        "table_name":"history_log",
        "data_size":"6.02",
        "index_size":"3.45"
    }
]
```

Valor retornado pela função:

```json
[
    {
        "table_name":"history"
    },
    {
        "table_name":"history_log"
    }
]
```

[comment]: # ({/f91807bf-fef95b5b})

[comment]: # ({da55e341-f6f7d5a8})
##### Exemplo 7: Converter o status do Apache em JSON

Converta o valor recebido de um item Zabbix agent [web.page.get](/manual/config/items/itemtypes/zabbix_agent#web.page.get) (por exemplo, web.page.get[http://127.0.0.1:80/server-status?auto]) em um objeto JSON.

```javascript
// Converter o status do Apache em JSON

// Dividir o valor em substrings e colocar essas substrings em um array
var lines = value.split('\n');

// Criar um objeto vazio "output"
var output = {};

// Criar um objeto "workers" com propriedades predefinidas
var workers = {
    '_': 0, 'S': 0, 'R': 0, 'W': 0,
    'K': 0, 'D': 0, 'C': 0, 'L': 0,
    'G': 0, 'I': 0, '.': 0
};

// Adicionar as substrings do array "lines" ao objeto "output" como propriedades (pares chave-valor)
for (var i = 0; i < lines.length; i++) {
    var line = lines[i].match(/([A-z0-9 ]+): (.*)/);

    if (line !== null) {
        output[line[1]] = isNaN(line[2]) ? line[2] : Number(line[2]);
    }
}

// Métricas multiversão
output.ServerUptimeSeconds = output.ServerUptimeSeconds || output.Uptime;
output.ServerVersion = output.ServerVersion || output.Server;

// Analisar a propriedade "Scoreboard" para obter a contagem de workers
if (typeof output.Scoreboard === 'string') {
    for (var i = 0; i < output.Scoreboard.length; i++) {
        var char = output.Scoreboard[i];

        workers[char]++;
    }
}

// Adicionar dados dos workers ao objeto "output"
output.Workers = {
    waiting: workers['_'], starting: workers['S'], reading: workers['R'],
    sending: workers['W'], keepalive: workers['K'], dnslookup: workers['D'],
    closing: workers['C'], logging: workers['L'], finishing: workers['G'],
    cleanup: workers['I'], slot: workers['.']
};

// Retornar a string JSON
return JSON.stringify(output);
```

Valor aceito pela função:

```default
HTTP/1.1 200 OK
Date: Mon, 27 Mar 2023 11:08:39 GMT
Server: Apache/2.4.52 (Ubuntu)
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 405
Content-Type: text/plain; charset=ISO-8859-1

127.0.0.1
ServerVersion: Apache/2.4.52 (Ubuntu)
ServerMPM: prefork
Server Built: 2023-03-08T17:32:01
CurrentTime: Monday, 27-Mar-2023 14:08:39 EEST
RestartTime: Monday, 27-Mar-2023 12:19:59 EEST
ParentServerConfigGeneration: 1
ParentServerMPMGeneration: 0
ServerUptimeSeconds: 6520
ServerUptime: 1 hour 48 minutes 40 seconds
Load1: 0.56
Load5: 0.33
Load15: 0.28
Total Accesses: 2476
Total kBytes: 8370
Total Duration: 52718
CPUUser: 8.16
CPUSystem: 3.44
CPUChildrenUser: 0
CPUChildrenSystem: 0
CPULoad: .177914
Uptime: 6520
ReqPerSec: .379755
BytesPerSec: 3461.58
BytesPerReq: 3461.58
DurationPerReq: 21.2916
BusyWorkers: 2
IdleWorkers: 6
Scoreboard: ____KW__..............................................................................................................................................
```

Valor retornado pela função:

```json
{
    "Date": "Mon, 27 Mar 2023 11:08:39 GMT",
    "Server": "Apache/2.4.52 (Ubuntu)",
    "Vary": "Accept-Encoding",
    "Encoding": "gzip",
    "Length": 405,
    "Type": "text/plain; charset=ISO-8859-1",
    "ServerVersion": "Apache/2.4.52 (Ubuntu)",
    "ServerMPM": "prefork",
    "Server Built": "2023-03-08T17:32:01",
    "CurrentTime": "Monday, 27-Mar-2023 14:08:39 EEST",
    "RestartTime": "Monday, 27-Mar-2023 12:19:59 EEST",
    "ParentServerConfigGeneration": 1,
    "ParentServerMPMGeneration": 0,
    "ServerUptimeSeconds": 6520,
    "ServerUptime": "1 hour 48 minutes 40 seconds",
    "Load1": 0.56,
    "Load5": 0.33,
    "Load15": 0.28,
    "Total Accesses": 2476,
    "Total kBytes": 8370,
    "Total Duration": 52718,
    "CPUUser": 8.16,
    "CPUSystem": 3.44,
    "CPUChildrenUser": 0,
    "CPUChildrenSystem": 0,
    "CPULoad": 0.177914,
    "Uptime": 6520,
    "ReqPerSec": 0.379755,
    "BytesPerSec": 1314.55,
    "BytesPerReq": 3461.58,
    "DurationPerReq": 21.2916,
    "BusyWorkers": 2,
    "IdleWorkers": 6,
    "Scoreboard": "____KW__..............................................................................................................................................",
    "Workers": {
        "waiting": 6,
        "starting": 0,
        "reading": 0,
        "sending": 1,
        "keepalive": 1,
        "dnslookup": 0,
        "closing": 0,
        "logging": 0,
        "finishing": 0,
        "cleanup": 0,
        "slot": 142
    }
}
```

[comment]: # ({/da55e341-f6f7d5a8})
