在 Node.js 性能平臺的監控設置中,有兩項表達式需要用戶進行輸入,閾值表達式和報警表達式。
監控系統會根據閾值表達式來進行是否進行報警的判定。當判定完成,決定發送警報時,會使用報警表達式來描述警報的詳情。
閾值表達式
閾值表達式是由 Node.js 性能平臺定義的一個報警判定DSL,出于靈活性和安全的考慮,我們定義了有限的表達方式。
每個應用的開發者可以輸入一個閾值表達式,該表達式會被編譯為一個等價的JavaScript函數。當監控系統收到當前類型的監控數據時,會將監控數據作為上下文,代入閾值表達式,如果表達式結果為true
,則判定需要發送警報。
一個基本的表達式由三個部分組成:屬性、比較操作符、字面量。
屬性
屬性標識是指上下文對象的屬性表示方式,形式為:@xxx
,以@
開頭接一個屬性名。例如:@load1
、@cpu
、@freemem
。
比較操作符
比較操作符跟普通的編程語言里的符號完全相同:==
、>=
、>
、<=
、<
、!=
。
運算符
支持+
、-
、*
、/
、%
運算符,如:@heap_used / @heap_limit
。
字面量
字面量是指基本的數值類型和字符串類型。一個基本的表達式類似這樣:@load1 > 5
。
include
include關鍵字用于屬性值中是否包含某個字符串。如:@message include "TypeError"
。
其他
其他的操作符有&&
、||
以及()
。與普通編程語言表達意思相同。如:
@cpu > 0.10 || @load1 > 5
@cpu > 0.10 && @load1 > 5
@cpu > 0.10 && (@load1 > 5 && @load5 > 5)
報警表達式
報警表達式類似于閾值表達式,但是并不用來做判定,更類似于模板語言。以下為簡單例子:
I am ${@name}. I am ${@age} years old.
其格式主要由2個部分組成,${}
之外的字符串和${}
內部的表達式。假設有上下文:
{name: "Jackson Tian", age: 18}
那么最終的執行結果就是:
I am Jackson Tian. I am 18 years old.
如果有一個報警的上下文是:
{load1: 5, load5: 2, load15: 2.2}
報警表達式為:
Load1較高,高于3,為${load1},請排查。
那么結果就是:Load1較高,高于3,為5,請排查。
${}內部支持@xxx
屬性的方式、簡單的+-*%/
以及數值和字符串。
比如內存使用的占比表達如下:
內存占用過高,為${@freemem / @total * 100}%。
監控類型與屬性
每一種監控類型的上下文并不相同。
system
@load1,1分鐘的平均負載。
@load5,5分鐘的平均負載。
@load15,15分鐘內的平均負載。
@cpu,CPU使用率,為0-1之間的數字。
@uptime,操作系統的運行時間,單位為秒。
@freemem,空閑的內存,單位為byte。
@totalmem,總的內存,單位為byte。
@cpu_count,CPU個數。
disk_usage
@used_percent,磁盤空間占用百分比,值為0-100。
node_log
node_log類型的數據為某個進程的內核數據。
進程編號:
@pid,進程id。
內存部分:
@rss,進程所使用的內存總大小,單位為byte。
V8堆的數據:
@heap_limit,能申請的堆內存的上限值,單位為byte。
@heap_total,申請到的堆內存大小,單位為byte。
@heap_used,當前使用的堆內存大小,單位為byte。
V8堆中的詳細空間:
注:V8所申請的內存堆被分配為多個內存空間。
@new_space_used,新生代空間的內存使用大小,單位為byte。
@old_space_used,老生代空間的內存使用大小,單位為byte。
@map_space_used,隱藏類空間的內存使用大小,單位為byte。
@code_space_used,代碼空間的內存使用大小,單位為byte。
@lo_space_used,大對象空間的內存使用大小,單位為byte。
Node v4.0之前的版本還有以下四個空間:
@cell_space_used,老生代單元空間的內存使用大小,單位為byte。
@property_cell_space_used,老生代屬性單元空間的內存使用大小,單位為byte。
@old_data_space_used,老生代數據空間的內存使用大小,單位為byte。
@old_pointer_space_used,老生代指針空間的內存使用大小,單位為byte。
上述4個空間在v4.0之后合并為old_space。
例如判斷是否發生內存泄漏,可以配置表達式:@heap_used / @heap_limit > 0.8
。報警表達式為:夭壽啦,估計內存泄漏了,堆上限${@heap_limit},已使用${@heap_used}
。
GC的數據:
@gc_time_during_last_min,一分鐘內的GC時間,單位ms。
@total,總的GC時間,單位ms。
libuv句柄數據:
@active_handles,活躍的句柄數。
定時器數據:
@total_timer,定時器數量。
HTTP數據:
@live_http_request,一分鐘內當前正在處理的HTTP請求數。
@http_response_sent,一分鐘內的HTTP響應數。
@http_request_handled,一分鐘內處理的HTTP請求數。
CPU數據:
@now,Node進程當前CPU占用量。
@cpu_15,Node進程當前15s鐘的CPU平均占用量。
@cpu_30,Node進程當前30s鐘的CPU平均占用量。
@cpu_60,Node進程當前60s鐘的CPU平均占用量。
注意:上述4個數據的值的單位為core,表示占用幾個核的CPU。如:0.25。表示占用0.25個核。該數值除以CPU核數,即為占整體的CPU的百分比。
error_log
異常日志數據。
@type,異常類型。
@timestamp,發生時間,距離1970.1.1的毫秒時間。
@stack,錯誤堆棧。
@extra,額外數據。
例如判斷是否發生uncaughtException
,可以在Node中捕獲:
process.on('uncaughtException', function(err) {
err.name = "UncaughtExceptionError";
console.log('Caught exception: ' + err);
});
然后配置監控表達式:@type include 'UncaughtExceptionError'
。報警表達式為:夭壽啦,發生UncaughtExceptionError啦,堆棧是:${@stack}
。
processes_count
進程數量數據。
@node_count,Node進程數量。
如果進程數量平常為5個,那么低于5個進程數量就屬于不正常。所以可以這樣配置監控表達式:@node_count < 5
,報警表達式:Node進程數${@node_count}低于5,請注意
。
version
版本號數據。
@node,系統的Node版本號。為vx.x.x的格式。
最后
如果對表達式和屬性有不清楚的地方,可以咨詢釘釘群:11794270 來聯系我們。