PML 2 外掛開發指南
內建函式
本文將介紹 PML 2 外掛系統中條件與動作樣板可用的內建函式與算術運算子。
一、內建函式概述
函式庫是 PML 2 外掛系統的重要組成部分。在撰寫外掛時, 你可以在條件表達式與動作參數樣板中直接呼叫內建函式, 對 ctx.data、ctx.variables 等情境資料進行加工、計算與判斷, 而無需撰寫任何程式碼。
內建函式由表達式求值器統一提供, 涵蓋字串與集合處理、數學運算、三角函式、日期時間操作等方面。函式名請統一使用小寫書寫, 參數按需取值, 支援字串、數值與集合型別。
以下介紹中, 函式旁的版本標記表示該函式自對應版本及以上的 PML 2 中可用。請根據實際使用的 PML 2 版本選擇合適的函式。
呼叫位置
內建函式可以出現在兩類位置:
| 位置 | 寫法 | 範例 |
|---|---|---|
條件表達式 (condition) | 直接書寫表達式, 不使用 {{ }} | len(ctx.data.proxyName) > 0 -and upper(ctx.data.proxyName) -eq 'WEB' |
動作參數樣板 (params) | 使用 {{ 表達式 }} 包裹, 一個字串內可嵌入多個樣板 | msg: "隧道 {{ctx.data.proxyName}} 已啟動 (長度 {{len(ctx.data.proxyName)}})" |
若函式名未知, 或參數個數 / 型別不合法, 表達式求值會擲出例外。外掛引擎會將其記錄為日誌, 不會導致應用程式崩潰, 但該筆觸發器的本次執行會失敗。請務必核對函式名與參數個數。
二、內建函式分類
| 分類 | 函式 |
|---|---|
| 字串與集合函式 | len、lower、upper、coalesce |
| 數學函式 | abs、round、floor、ceil、sqrt、pow、min、max、ln、log10、log2、log |
| 三角函式 | sin、cos、tan、cot、sec、csc |
| 日期時間函式 | now、datetime.now.strftime |
三、內建函式詳細介紹
1. 字串與集合函式 26.3.1
| 函式名 | 參數 | 說明 | 用例 |
|---|---|---|---|
len(x) | x: 任意 | 傳回長度或元素個數。null 傳回 0; 字串傳回字元數; 集合傳回元素個數; 其他型別傳回其字串表示的長度。 | len("abcd") 傳回 4len(ctx.variables.list) 傳回集合元素個數 |
lower(s) | s: 任意 | 轉為字串並轉換為小寫。null 傳回空字串。 | lower("Web") 傳回 "web" |
upper(s) | s: 任意 | 轉為字串並轉換為大寫。null 傳回空字串。 | upper("Web") 傳回 "WEB" |
coalesce(a, b, ...) | 1 個及以上 | 傳回第一個既不為 null 也不為空字串的參數; 若全部為空則傳回 null。常用於為缺少的欄位提供預設值。 | coalesce(ctx.data.errorCategory, "timeout") 在欄位缺少時傳回 "timeout" |
len 對字串與集合都有效, 因此可以用同一個函式判斷隧道名稱長度或清單元素個數。2. 數學函式
min、max 自 26.3.1 起可用, 其餘數學函式自 26.5 起可用。所有數學函式都要求參數能解析為數值, 否則會擲出例外。
| 函式名 | 參數 | 說明 | 用例 |
|---|---|---|---|
abs(x) | x: 數值 | 傳回 x 的絕對值。 | abs(-5) 傳回 5 |
round(x) | x: 數值 | 傳回四捨六入五成雙的結果 (銀行家捨入, 即 .NET 預設的 MidpointRounding.ToEven)。 | round(4.5) 傳回 4round(5.5) 傳回 6 |
floor(x) | x: 數值 | 傳回小於或等於 x 的最大整數。 | floor(4.9) 傳回 4 |
ceil(x) | x: 數值 | 傳回大於或等於 x 的最小整數。 | ceil(4.2) 傳回 5 |
sqrt(x) | x: 數值 | 傳回 x 的平方根。 | sqrt(9) 傳回 3 |
pow(x, y) | x、y: 數值 | 傳回 x 的 y 次方。 | pow(2, 10) 傳回 1024 |
min(a, b, ...) | 2 個及以上數值 | 傳回最小值。 | min(3, 5) 傳回 3 |
max(a, b, ...) | 2 個及以上數值 | 傳回最大值。 | max(3, 5) 傳回 5 |
ln(x) | x: 數值 | 傳回自然對數 (底數為 e)。 | ln(1) 傳回 0 |
log10(x) | x: 數值 | 傳回常用對數 (底數為 10)。 | log10(100) 傳回 2 |
log2(x) | x: 數值 | 傳回底數為 2 的對數。 | log2(8) 傳回 3 |
log(x, base) | x、base: 數值 | 傳回指定底數的對數, base 必須大於 0。 | log(8, 2) 傳回 3 |
3. 三角函式 26.5
| 函式名 | 參數 | 說明 | 用例 |
|---|---|---|---|
sin(x) | x: 數值 | 傳回正弦值。 | sin(0) 傳回 0 |
cos(x) | x: 數值 | 傳回餘弦值。 | cos(0) 傳回 1 |
tan(x) | x: 數值 | 傳回正切值。 | tan(0) 傳回 0 |
cot(x) | x: 數值 | 傳回餘切值, 即 1 / tan(x)。 | cot(1) |
sec(x) | x: 數值 | 傳回正割值, 即 1 / cos(x)。 | sec(1) |
csc(x) | x: 數值 | 傳回餘割值, 即 1 / sin(x)。 | csc(1) |
三角函數參數預設採用角度制。若第二個參數傳入
"true",則會以弧度制進行計算。求值前會先將參數中的 \pi 替換為圓周率 π 的數值,以便書寫含 π 的常數。4. 日期時間函式
now 自 26.3.1 起可用, datetime.now.strftime 自 26.5 起可用。
| 函式名 | 參數 | 說明 | 用例 |
|---|---|---|---|
now | 無 | 傳回目前 UTC 時間的 Unix 時間戳記 (秒)。 | now 傳回 1759456000 |
datetime.now.strftime(format) | format (選填): 字串 | 傳回目前本機時間的格式化字串; 省略 format 時使用 yyyy-MM-dd HH:mm:ss。 | datetime.now.strftime("yyyy/MM/dd") 傳回 2026/10/03 |
四、算術運算子
除了函式呼叫, PML 2 的表達式還支援算術運算, 並可用括號 () 改變優先順序。算術運算子自 26.3.1 起可用。
| 運算子 | 說明 | 範例 |
|---|---|---|
+ | 加法, 計算左右兩邊的和。 | ctx.variables.count + 5 |
- | 減法, 計算左右兩邊的差。 | ctx.variables.count - 5 |
* | 乘法, 計算左右兩邊的積。 | ctx.variables.count * 5 |
/ | 除法, 計算左右兩邊的商 (浮點除法)。 | 5 / 2 傳回 2.5 |
% | 取模, 計算左右兩邊的餘數。 | 7 % 3 傳回 1 |
** 或 ^ | 冪運算, 計算左邊的值的右邊的値次方。 | 2 ** 10 傳回 1024 |
// | 整數除法, 計算左右兩邊的商的向下取整。 | 7 // 2 傳回 3 |
算術運算子要求數值運算元; 若運算元為字串, 會先嘗試將其解析為數值, 解析失敗則擲出例外。算術運算子與內建函式可以自由組合, 例如
max(len(ctx.data.proxyName), 3) * 2。五、完整範例
以下範例摘自官方範例外掛 tech.rycb.plugin.demo-functions.yaml, 示範內建函式與算術運算在條件表達式與動作參數樣板中的用法:
triggers:
# 隧道名稱長度大於 0 且忽略大小寫等於 web 時記錄日誌
- on: proxy.start
condition: "len(ctx.data.proxyName) > 0 -and upper(ctx.data.proxyName) -eq 'WEB'"
actions:
- name: log
params:
msg: "隧道 {{ctx.data.proxyName}} 已啟動 (名稱長度 {{len(ctx.data.proxyName)}})"
# 失敗分類缺少時視為 timeout, 且重試次數不超過 3 次才通知
- on: proxy.failed
condition: "coalesce(ctx.data.errorCategory, 'timeout') -eq 'timeout' -and min(ctx.variables.retryCount, 3) -le 3"
actions:
- name: notify
params:
msg: "隧道 {{ctx.data.proxyName}} 失敗: {{ctx.data.errorMessage}}"