5 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値を返すと、入力値が破棄されます。これは「失敗時にカスタム処理」で「値を破棄」と同様の動作です。

エラーは値やオブジェクト(通常は文字列またはErrorオブジェクト)をthrowすることで返すことができます。

例:

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

各スクリプトの実行タイムアウトは10秒です(スクリプトによってはタイムアウトが発生するまでにさらに時間がかかる場合があります)。これを超えるとエラーが返されます。 512メガバイトのヒープ制限が適用されます。

JavaScriptの事前処理ステップのバイトコードはキャッシュされ、次回ステップが適用される際に再利用されます。 アイテムの事前処理ステップに変更があると、キャッシュされたスクリプトはリセットされ、後で再コンパイルされます。

実行時エラーが連続して発生した場合(3回連続)、1つのスクリプトが次のスクリプトの実行環境を壊す可能性を軽減するためにエンジンが再初期化されます(このアクションはDebugLevel 4以上でログに記録されます)。

JavaScriptの事前処理はDuktape JavaScriptエンジンで実装されています。

参考: 追加のJavaScriptオブジェクトとグローバル関数

スクリプトでのマクロの使用

JavaScriptコードでユーザーマクロ(および低レベルディスカバリのコンテキストでLLDマクロ)を使用することができます。 スクリプトにユーザーマクロが含まれている場合、これらのマクロは特定の前処理ステップを実行する前にサーバー/プロキシによって解決されます。 Webインターフェースで前処理ステップをテストする場合、マクロ値は取得されず、手動で入力する必要があることに注意してください。

マクロが値に置き換えられる際、コンテキストは無視されます。 マクロ値はそのままコードに挿入され、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エージェントアイテム(例: 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"プロパティを解析してワーカー数を取得
if (typeof output.Scoreboard === 'string') {
    for (var i = 0; i < output.Scoreboard.length; i++) {
        var char = output.Scoreboard[i];

        workers[char]++;
    }
}

// ワーカーデータを"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
    }
}