JavaScript 전처리
개요
이 섹션에서는 JavaScript를 이용한 전처리에 대해 자세히 설명합니다.
전처리 JavaScript에서는 선언되지 않은 할당을 사용하지 마세요.
지역 변수 선언에는 var를 사용하세요.
JavaScript 전처리
JavaScript 전처리는 단일 파라미터 'value'와 사용자가 제공한 함수 본문을 가진 JavaScript 함수를 호출하여 수행됩니다. 전처리 단계의 결과는 이 함수가 반환하는 값이며, 예를 들어 화씨를 섭씨로 변환하려면 다음과 같이 입력합니다:
return (value - 32) * 5 / 9
JavaScript 전처리 파라미터에 입력하면, 서버는 이를 다음과 같은 JavaScript 함수로 감쌉니다:
function (value)
{
return (value - 32) * 5 / 9
}
입력 파라미터 'value'는 항상 문자열로 전달됩니다. 반환 값은 toString() 메서드를 통해 자동으로 문자열로 강제 변환되며(실패할 경우 오류가 문자열 값으로 반환됩니다), 몇 가지 예외가 있습니다:
- undefined 값을 반환하면 오류가 발생합니다;
- null 값을 반환하면 'Custom on fail' 작업의 'Discard value' 전처리와 마찬가지로 입력 값이 폐기됩니다.
값/객체(보통 문자열 또는 Error 객체)를 throw하여 오류를 반환할 수 있습니다.
예를 들면:
if (value == 0)
throw "Zero input value"
return 1/value
각 스크립트에는 10초의 실행 제한 시간이 있습니다(스크립트에 따라 제한 시간 초과가 발생하기까지 더 오래 걸릴 수 있습니다). 이를 초과하면 오류가 반환됩니다. 512메가바이트의 힙 제한이 적용됩니다.
JavaScript 전처리 단계의 바이트코드는 캐시되어 해당 단계가 다음에 적용될 때 재사용됩니다. 항목의 전처리 단계에 변경이 발생하면 캐시된 스크립트는 초기화되고 이후 다시 컴파일됩니다.
연속적인 런타임 실패(3회 연속)가 발생하면 하나의 스크립트가 다음 스크립트의 실행 환경을 손상시킬 가능성을 완화하기 위해 엔진이 재초기화됩니다(이 동작은 DebugLevel 4 이상에서 로그로 기록됩니다).
JavaScript 전처리는 Duktape JavaScript 엔진으로 구현됩니다.
내장 JavaScript 객체 메서드 정의는 항목 전처리 스크립트에서 재정의할 수 없습니다.
스크립트에서 매크로 사용하기
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: 숫자 변환 (2진수를 10진수로)
2진수 "11010010"을 10진수로 변환합니다.
return(parseInt(value,2))
함수가 반환하는 값: 210.
예제 3: 숫자 반올림
숫자 "18.2345"를 소수점 2자리로 반올림합니다.
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 속성 제거
키가 "data_size" 또는 "index_size"인 모든 속성을 제거하여 JSON 데이터 구조를 수정합니다.
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으로 변환
web.page.get Zabbix agent 항목(예: web.page.get[http://127.0.0.1:80/server-status?auto])에서 수신된 값을 JSON 객체로 변환합니다.
// 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);
함수가 받는 값:
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
}
}