[comment]: # ({213e862c-213e862c})
# 4 Preprocesamiento con JavaScript

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

[comment]: # ({f3c5a895-57d3be9d})
### Descripción general

Esta sección proporciona detalles del preprocesamiento mediante JavaScript.

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

[comment]: # ({afdc7ca9-076d2285})
### Preprocesamiento con JavaScript

El preprocesamiento con JavaScript se realiza invocando la función de JavaScript con un
'valor' de parámetro único y cuerpo de función proporcionado por el usuario.
El resultado del paso de preprocesamiento es el valor devuelto por esta función, 
por ejemplo, para realizar la conversión de Fahrenheit a Celsius, el usuario debe ingresar:

    return (value - 32) * 5 / 9

en los parámetros de preprocesamiento de JavaScript, que se incluirán en una
función JavaScript por el servidor:

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

El parámetro de entrada 'valor' siempre se pasa como una cadena. El valor de retorno
se convierte automáticamente en cadena mediante el método ToString() (si
falla, el error se devuelve como valor de cadena), con algunas
excepciones:

- devolver un valor indefinido generará un error;
- devolver un valor nulo hará que se descarte el valor de entrada,
    muy parecido al preprocesamiento 'Descartar valor' en la acción 'Personalizado en caso de error'.

Los errores se pueden devolver arrojando valores/objetos (normalmente ya sea
cadenas u objetos de error).

Por ejemplo:

```javascript
if (value == 0)
    throw "valor de entrada cero"
return 1/value
```

Cada script tiene un tiempo de espera de ejecución de 10 segundos (dependiendo del script
el tiempo de espera puede tardar más en activarse); si se supera, se
devolverá un error. Se aplica un límite de almacenamiento dinámico de 512 megabytes (64 megabytes antes de Zabbix 6.4.4).

El código de bytes del paso de preprocesamiento de JavaScript se almacena en caché y se reutiliza cuando
el paso se aplique la próxima vez. Cualquier cambio en los pasos de preprocesamiento de la métrica.
hará que el script almacenado en caché se restablezca y se vuelva a compilar más tarde.

Errores consecutivos en el tiempo de ejecución (3 seguidos) causarán que el motor se 
reinicie para mitigar la posibilidad de que un script rompa el
entorno de ejecución para los siguientes scripts (esta acción se registra con
nivel de depuración 4 y superior).

El preprocesamiento de JavaScript se implementa con el
Motor JavaScript de Duktape (<https://duktape.org/>) .

Ver también: [Objetos JavaScript adicionales y funciones
globales](/manual/config/items/preprocessing/javascript/javascript_objects)

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

[comment]: # ({a89f6d69-c932b901})
##### Uso de macros en scripts

Es posible utilizar macros de usuario en el código JavaScript. Si un guión
contiene macros de usuario, estas macros son resueltas por el servidor/proxy antes de
ejecutar los pasos de preprocesamiento específicos. Tenga en cuenta que al realizar pruebas
de pasos de preprocesamiento en la interfaz, los valores macro no se extraerán y
deben ingresarse manualmente.

::: noteclassic
 El contexto se ignora cuando una macro se reemplaza con su valor.
El valor de la macro se inserta en el código tal cual, no es posible agregar
escapes adicionales antes de colocar el valor en el código JavaScript.
Tenga en cuenta que esto puede provocar errores de JavaScript en algunos casos.
:::

En el siguiente ejemplo, si el valor recibido excede el valor de una macro {$THRESHOLD},
en su lugar se devolverá el valor del umbral (si está presente):

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

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

[comment]: # ({023bc14f-29d0516e})
### Ejemplos

Los siguientes ejemplos ilustran cómo puede utilizar el preprocesamiento de JavaScript.

Cada ejemplo contiene una breve descripción, un cuerpo de función para los parámetros de preprocesamiento de JavaScript y el resultado del paso de preprocesamiento: valor devuelto por la función.

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

[comment]: # ({565e57c6-85fe10ec})
##### Ejemplo 1: convertir un número (notación científica a entero)

Convierte el número "2.62128e+07" de notación científica a un número entero.

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

Valor devuelto por la función: 26212800.

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

[comment]: # ({5a30e4ee-cb346f3f})
##### Ejemplo 2: convertir un número (binario a decimal)

Convierta el número binario "11010010" a un número decimal.

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

Valor devuelto por la función: 210.

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

[comment]: # ({35ba7ead-b90c2a4e})
##### Ejemplo 3: redondear un número

Redondea el número "18.2345" a 2 dígitos.

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

Valor devuelto por la función: 18.23.

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

[comment]: # ({d27ba472-3ccbf334})
##### Ejemplo 4: contar letras en una cadena

Cuente el número de letras en la cadena "Zabbix".

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

Valor devuelto por la función: 6.

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

[comment]: # ({a521a081-1a7f5b1b})
##### Ejemplo 5: Obtener el tiempo restante

Obtenga el tiempo restante (en segundos) hasta la fecha de vencimiento de un certificado (12 de febrero a las 12:33:56 2022 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 devuelto por la función: 44380233.

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

[comment]: # ({f91807bf-04fc1390})
##### Ejemplo 6: eliminar propiedades JSON

Modifique la estructura de datos JSON eliminando cualquier propiedad con la clave `"data_size"` o `"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 aceptado por la función:

```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 devuelto por la función:

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

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

[comment]: # ({ef57e195-7fbf2a11})
##### Ejemplo 7: convertir el estado de Apache a JSON

Convierta el valor recibido de un elemento del agente Zabbix [web.page.get](/manual/config/items/itemtypes/zabbix_agent#web.page.gethostpathport) (por ejemplo, web.page.get[http://127.0.0.1 :80/server-status?auto]) a un objeto JSON.

```javascript
// Convertir el estado de Apache a JSON

// Divide el valor en subcadenas y coloca estas subcadenas en una matriz
var lines = value.split('\n');

// Crea un objeto vacío "salida"
var output = {};

// Crea un objeto "trabajadores" con propiedades predefinidas
var workers = {
    '_': 0, 'S': 0, 'R': 0, 'W': 0,
    'K': 0, 'D': 0, 'C': 0, 'L': 0,
    'G': 0, 'I': 0, '.': 0
};

// Agrega las subcadenas de la matriz "líneas" al objeto "salida" como propiedades (pares clave-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 multiversión
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]++;
    }
}

// Agrega datos del trabajador al objeto "salida"
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['.']
};

// Devuelve cadena JSON
return JSON.stringify(output);
```

Valor aceptado por la función:

    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 devuelto por la función:

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