Предварительная обработка JavaScript
Обзор
В этом разделе приведены сведения о предварительной обработке при помощи JavaScript.
Не используйте необъявленные присваивания в предварительной обработке JavaScript.
Используйте var для объявления локальных переменных.
Предобработка JavaScript
Предобработка JavaScript выполняется путем вызова функции JavaScript с одним параметром 'value' и телом функции, заданным пользователем. Результатом шага предобработки является значение, возвращаемое этой функцией. Например, чтобы выполнить преобразование из градусов Фаренгейта в градусы Цельсия, введите:
return (value - 32) * 5 / 9
в параметрах предобработки JavaScript, которые будут обернуты сервером в функцию JavaScript:
function (value)
{
return (value - 32) * 5 / 9
}
Входной параметр 'value' всегда передается как строка. Возвращаемое значение автоматически приводится к строке с помощью метода toString() (если это не удается, то ошибка возвращается как строковое значение), за несколькими исключениями:
- возврат значения undefined приведет к ошибке;
- возврат значения null приведет к тому, что входное значение будет отброшено, аналогично предобработке 'Discard value' при действии 'Custom on fail'.
Ошибки можно возвращать, выбрасывая значения/объекты (обычно либо строки, либо объекты Error).
Например:
if (value == 0)
throw "Zero input value"
return 1/value
Для каждого скрипта установлен 10-секундный тайм-аут выполнения (в зависимости от скрипта срабатывание тайм-аута может занять больше времени); при его превышении будет возвращена ошибка. Также действует ограничение на объем heap в 512 мегабайт.
Байт-код шага предобработки JavaScript кэшируется и повторно используется при следующем применении шага. Любые изменения в шагах предобработки элемента данных приведут к сбросу кэшированного скрипта и его последующей повторной компиляции.
Последовательные сбои выполнения (3 подряд) приведут к повторной инициализации движка, чтобы снизить вероятность того, что один скрипт нарушит среду выполнения для следующих скриптов (это действие регистрируется с DebugLevel 4 и выше).
Предобработка JavaScript реализована с использованием движка JavaScript Duktape.
Встроенные определения методов объектов JavaScript нельзя переопределять в скриптах предобработки элемента данных.
См. также: Additional JavaScript objects and global functions
Использование макросов в скриптах
В JavaScript-коде можно использовать пользовательские макросы (а также LLD-макросы в контексте низкоуровневого обнаружения). Если скрипт содержит пользовательские макросы, эти макросы разрешаются сервером/прокси перед выполнением определенных шагов предварительной обработки. Обратите внимание, что при тестировании шагов предварительной обработки во веб-интерфейсе значения макросов не будут подставлены и их нужно будет ввести вручную.
Контекст игнорируется при замене макроса его значением. Значение макроса вставляется в код как есть; невозможно добавить дополнительное экранирование перед помещением значения в JavaScript-код. Имейте в виду, что в некоторых случаях это может привести к ошибкам JavaScript.
В примере ниже, если полученное значение превышает значение макроса {$THRESHOLD}, вместо него будет возвращено значение порога (если оно задано):
var threshold = '{$THRESHOLD}';
return (!isNaN(threshold) && value > threshold) ? threshold : value;
Примеры
Следующие примеры иллюстрируют, как можно использовать предобработку JavaScript.
Каждый пример содержит краткое описание, тело функции для параметров предварительной обработки JavaScript и результат шага предварительной обработки — значение, возвращаемое функцией.
Пример 1: Преобразование числа (из научной нотации в целое число)
Преобразовать число «2.62128e+07» из научной нотации в целое число.
return (Number(value))
Значение, возвращаемое функцией: 26212800.
Пример 2: Преобразование числа (двоичного в десятичное)
Преобразовать двоичное число «11010010» в десятичное.
return(parseInt(value,2))
Значение, возвращаемое функцией: 210.
Пример 3: Округление числа
Округлить число «18.2345» до двух цифр.
return(Math.round(value* 100) / 100)
Значение, возвращаемое функцией: 18.23.
Пример 4: Подсчёт букв в строке
Подсчитать количество букв в строке «Zabbix».
return (value.length)
Значение, возвращаемое функцией: 6.
Пример 5: Получить оставшееся время
Получить время (в секундах), оставшееся до момента истечения срока действия сертификата (Feb 12 12:33:56 2022 GMT).
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);
Значение, возвращаемое функцией: 44380233.
Пример 6: Удаление свойств JSON
Изменить структуру данных JSON, удалив все свойства с ключом "data_size" или "index_size".
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)
Значение, принимаемое функцией:
[
{
"table_name":"history",
"data_size":"326.05",
"index_size":"174.34"
},
{
"table_name":"history_log",
"data_size":"6.02",
"index_size":"3.45"
}
]
Значение, возвращаемое функцией:
[
{
"table_name":"history"
},
{
"table_name":"history_log"
}
]
Пример 7: Преобразование статуса Apache в JSON
Преобразовать значение, полученное от элемента данных агента Zabbix web.page.get (например, web.page.get[http://127.0.0.1:80/server-status?auto]), в объект JSON.
// Преобразовать статус Apache в JSON
// Разбить значение на подстроки и поместить их в массив
var lines = value.split('\n');
// Создать пустой объект «output»
var output = {};
// Создать объект «workers» с предопределёнными свойствами
var workers = {
'_': 0, 'S': 0, 'R': 0, 'W': 0,
'K': 0, 'D': 0, 'C': 0, 'L': 0,
'G': 0, 'I': 0, '.': 0
};
// Добавить подстроки из массива «lines» в объект «output» как свойства (пары ключ-значение)
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]);
}
}
// Метрики мультиверсии
output.ServerUptimeSeconds = output.ServerUptimeSeconds || output.Uptime;
output.ServerVersion = output.ServerVersion || output.Server;
// Парсинг свойства «Scoreboard» для получения количества worker-ов
if (typeof output.Scoreboard === 'string') {
for (var i = 0; i < output.Scoreboard.length; i++) {
var char = output.Scoreboard[i];
workers[char]++;
}
}
// Добавить данные о worker-ах к объекту «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['.']
};
// Вернуть строку JSON
return JSON.stringify(output);
Значение, принятое функцией:
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__..............................................................................................................................................
Значение, возвращаемое функцией:
{
"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
}
}