[comment]: # translation:outdated

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

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

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

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

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

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

O pré-processamento JavaScript é feito pela invocação da função JavaScript
com um único parâmetro 'valor' e um corpo de função fornecido pelo usuário.
O resultado da etapa de pré-processamento é o valor retornado desta função,
por exemplo, para executar a conversão de Fahrenheit para Celsius o usuário
deve informar:

    return (valor - 32)  * 5 / 9

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

``` {.java}
function (valor)
{
   return (valor - 32) * 5 / 9
}
```

O parâmetro de entrada 'valor' é sempre passado como um string. O valor
de retorno é automaticamente forçado para um string através do método
ToString() (se ele falhar então o erro é retornado como um valor string),
com algumas poucas exceções:

-   retornando valor indefinido resultará em um erro
-   retornando valor null fará com que o valor de entrada seja descartado,
    muito semelhante ao pré-processamento 'Descartar valor' em uma ação
    'Customizado em caso de falha'.

Erros podem ser retornados pelo lançamento de valores/objetos (normalmente
strings ou objetos Erro).

Por exemplo:

``` {.java}
if (valor == 0)
    throw "Valor de entrada zero"
return 1/valor
```

Cada script tem um tempo limite de execução de 10 segundos (dependendo
do script pode ser levado mais tempo que o limite para engatilhar);
excedê-lo retornará um erro. Um limite de heap de 64 megabyte é imposto.

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

Falhas em tempo de execução consecutivas (3 em sequência) farão com que o
mecanismo seja reiniciado para mitigar a possibilidade de um script quebrar
a execução dos próximos scripts (esta ação é registrada em log com DebugLevel 4
e maior).

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]: # ({/783e7369-076d2285})

[comment]: # ({ca818da5-c932b901})
##### Utilização de macros nos scripts

É possível usar macros de usuário no código JavaScript. Se um script
contém macros de usuário, estas macros são resolvidas pelo Server/Proxy
antes da execução das etapas de pré-processamento específicas. Note que
quando testando etapas de pré-processamento no Frontend, os valores de
macro não serão puxados e precisam ser informados manualmente.

::: noteclassic
 O contexto é ignorado quando uma macro é substituída com seu valor.
O valor da macro é inserido no código como está, não é possível adicionar
escapes adicionais antes de colocar o valor no código JavaScript. Por
favor, esteja ciente que isto pode causar erros de JavaScript em alguns casos.
:::

Em um exemplo abaixo, se o valor recebido excede um valor de {$THRESHOLD} de
macro, o valor de threshold (se presente) será retornado em vez disso:

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

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

[comment]: # ({new-29d0516e})
### Examples

The following examples illustrate how you can use JavaScript preprocessing.
Each example contains a brief description, a function body for JavaScript preprocessing parameters, and the preprocessing step result (value accepted by the function → value returned by the function).

[comment]: # ({/new-29d0516e})

[comment]: # ({new-85fe10ec})
##### Example 1: Convert number (scientific notation to integer)

Convert a number from scientific notation to an integer.

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

Result: 2.62128e+07 → 26212800

[comment]: # ({/new-85fe10ec})

[comment]: # ({new-cb346f3f})
##### Example 2: Convert number (binary to decimal)

Convert a binary number to a decimal number.

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

Result: 11010010 → 210

[comment]: # ({/new-cb346f3f})

[comment]: # ({new-b90c2a4e})
##### Example 3: Round a number

Round a number to 2 digits.

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

Result: 18.2345 → 18.23

[comment]: # ({/new-b90c2a4e})

[comment]: # ({new-3ccbf334})
##### Example 4: Count letters in a string

Count the number of letters in a string.

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

Result: "zabbix" → 6

[comment]: # ({/new-3ccbf334})

[comment]: # ({new-1a7f5b1b})
##### Example 5: Get time remaining

Get the remaining time (in seconds) until the expiration date of a certificate.

```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);
```

Result: Feb 12 12:33:56 2022 GMT → 44380233

[comment]: # ({/new-1a7f5b1b})

[comment]: # ({new-04fc1390})
##### Example 6: Modify JSON (remove properties)

Modify a JSON data structure by removing any properties with the key `"data_size"` or `"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)
```

Value accepted by the function:

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

Value returned by the function:

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

[comment]: # ({/new-04fc1390})

[comment]: # ({new-7fbf2a11})
##### Example 7: Convert Apache status to JSON

Convert the value received from a [web.page.get](/manual/config/items/itemtypes/zabbix_agent#web.page.gethostpathport) Zabbix agent item (e.g., web.page.get[http://127.0.0.1:80/server-status?auto]) to a JSON object.

```javascript
// Convert Apache status to JSON

// Split the value into substrings and put these substrings into an array
var lines = value.split('\n');

// Create an empty object "output"
var output = {};

// Create an object "workers" with predefined properties
var workers = {
    '_': 0, 'S': 0, 'R': 0, 'W': 0,
    'K': 0, 'D': 0, 'C': 0, 'L': 0,
    'G': 0, 'I': 0, '.': 0
};

// Add the substrings from the "lines" array to the "output" object as properties (key-value pairs)
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]);
    }
}

// Multiversion metrics
output.ServerUptimeSeconds = output.ServerUptimeSeconds || output.Uptime;
output.ServerVersion = output.ServerVersion || output.Server;

// Parse "Scoreboard" property to get the worker count
if (typeof output.Scoreboard === 'string') {
    for (var i = 0; i < output.Scoreboard.length; i++) {
        var char = output.Scoreboard[i];

        workers[char]++;
    }
}

// Add worker data to the "output" object
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['.']
};

// Return JSON string
return JSON.stringify(output);
```

Value accepted by the function:

    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__..............................................................................................................................................

Value returned by the function:

```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]: # ({/new-7fbf2a11})
