Node.js 的 Prometheus 用戶端,支援直方圖、摘要、儀表和計數器。
請參閱範例資料夾以取得範例用法。該庫不捆綁任何 Web 框架。若要公開指標,請使用await registry.metrics()
的結果回應Prometheus的抓取請求。
cluster
模組一起使用Node.js 的cluster
模組會產生多個進程,並將套接字連接交給這些工作人員。從工作人員的本地註冊表返回指標只會顯示單一工作人員的指標,這通常是不可取的。為了解決這個問題,您可以聚合主進程中所有工作執行緒的指標。有關範例,請參閱example/cluster.js
。
預設指標使用合理的聚合方法。 (但請注意,事件循環滯後平均值和百分位數是平均的,這並不完全準確。)預設情況下,自訂指標會在工作人員之間求和。若要使用不同的聚合方法,請將指標配置中的aggregator
屬性設為「sum」、「first」、「min」、「max」、「average」或「omit」之一。 (有關範例,請參閱lib/metrics/version.js
。)
如果您需要公開有關單一工作執行緒的指標,則可以在標籤中包含該工作執行緒唯一的值(例如工作執行緒 ID 或進程 ID)。 (有關使用worker_${cluster.worker.id}
作為標籤值的範例,請參閱example/server.js
。)
預設情況下,指標是從全域註冊表聚合的。若要使用不同的註冊表,請從工作進程中呼叫client.AggregatorRegistry.setRegistries(registryOrArrayOfRegistries)
。
Prometheus 本身推薦了一些預設指標。要收集這些,請呼叫collectDefaultMetrics
。此外,還包括一些特定於 Node.js 的指標,例如事件循環延遲、活動句柄、GC 和 Node.js 版本。有關所有指標的列表,請參閱 lib/metrics。
注意:一些有關檔案描述符和記憶體的指標僅在 Linux 上可用。
collectDefaultMetrics
可以選擇接受具有下列條目的配置物件:
prefix
度量標準名稱的可選前綴。預設值:無前綴。register
指標應註冊到哪個註冊表。預設值:全域預設註冊表。gcDurationBuckets
帶有用於 GC 持續時間直方圖的自訂儲存桶。 GC 持續時間直方圖的預設儲存桶為[0.001, 0.01, 0.1, 1, 2, 5]
(以秒為單位)。eventLoopMonitoringPrecision
採樣率以毫秒為單位。必須大於零。預設值:10。要將指標註冊到另一個註冊表,請將其作為register
傳入:
const client = require ( 'prom-client' ) ;
const collectDefaultMetrics = client . collectDefaultMetrics ;
const Registry = client . Registry ;
const register = new Registry ( ) ;
collectDefaultMetrics ( { register } ) ;
若要使用自訂儲存桶作為 GC 持續時間直方圖,請將其作為gcDurationBuckets
傳入:
const client = require ( 'prom-client' ) ;
const collectDefaultMetrics = client . collectDefaultMetrics ;
collectDefaultMetrics ( { gcDurationBuckets : [ 0.1 , 0.2 , 0.3 ] } ) ;
若要使用您自己的任意字串為指標名稱加上前綴,請傳入prefix
:
const client = require ( 'prom-client' ) ;
const collectDefaultMetrics = client . collectDefaultMetrics ;
const prefix = 'my_application_' ;
collectDefaultMetrics ( { prefix } ) ;
若要將通用標籤套用至所有預設指標,請將物件傳遞給labels
屬性(如果您在叢集環境中工作,則很有用):
const client = require ( 'prom-client' ) ;
const collectDefaultMetrics = client . collectDefaultMetrics ;
collectDefaultMetrics ( {
labels : { NODE_APP_INSTANCE : process . env . NODE_APP_INSTANCE } ,
} ) ;
您可以透過檢查client.collectDefaultMetrics.metricsList
來取得完整的指標清單。
預設指標是在指標端點上收集的,而不是按時間間隔收集的。
const client = require ( 'prom-client' ) ;
const collectDefaultMetrics = client . collectDefaultMetrics ;
collectDefaultMetrics ( ) ;
所有指標類型都有兩個強制參數: name
和help
。有關命名指標的指導,請參閱 https://prometheus.io/docs/practices/naming/。
對於基於時間點觀察的指標(例如當前記憶體使用情況,而不是在直方圖中連續觀察到的 HTTP 請求持續時間),您應該提供一個collect()
函數,當Prometheus 抓取您的指標端點時將調用該函數。 collect()
可以是同步的,也可以回傳一個承諾。請參閱下面的儀表範例。 (請注意,您不應在setInterval
回呼中更新指標值;而是在此collect
函數中執行此操作。)
有關如何為所有指標類型配置標籤的信息,請參閱標籤。
計數器上升,並在進程重新啟動時重置。
const client = require ( 'prom-client' ) ;
const counter = new client . Counter ( {
name : 'metric_name' ,
help : 'metric_help' ,
} ) ;
counter . inc ( ) ; // Increment by 1
counter . inc ( 10 ) ; // Increment by 10
儀表與計數器類似,但儀表的值可以減少。
const client = require ( 'prom-client' ) ;
const gauge = new client . Gauge ( { name : 'metric_name' , help : 'metric_help' } ) ;
gauge . set ( 10 ) ; // Set to 10
gauge . inc ( ) ; // Increment 1
gauge . inc ( 10 ) ; // Increment 10
gauge . dec ( ) ; // Decrement by 1
gauge . dec ( 10 ) ; // Decrement by 10
如果儀表用於時間點觀察,您應該提供一個collect
函數:
const client = require ( 'prom-client' ) ;
new client . Gauge ( {
name : 'metric_name' ,
help : 'metric_help' ,
collect ( ) {
// Invoked when the registry collects its metrics' values.
// This can be synchronous or it can return a promise/be an async function.
this . set ( /* the current value */ ) ;
} ,
} ) ;
// Async version:
const client = require ( 'prom-client' ) ;
new client . Gauge ( {
name : 'metric_name' ,
help : 'metric_help' ,
async collect ( ) {
// Invoked when the registry collects its metrics' values.
const currentValue = await somethingAsync ( ) ;
this . set ( currentValue ) ;
} ,
} ) ;
請注意,您不應使用箭頭函數來collect
,因為箭頭函數不會為this
提供正確的值。
// Set value to current time in seconds:
gauge . setToCurrentTime ( ) ;
// Record durations:
const end = gauge . startTimer ( ) ;
http . get ( 'url' , res => {
end ( ) ;
} ) ;
直方圖追蹤事件的大小和頻率。
預設儲存桶旨在涵蓋常見的 Web/RPC 請求,但它們可以被覆蓋。 (另請參閱桶生成器。)
const client = require ( 'prom-client' ) ;
new client . Histogram ( {
name : 'metric_name' ,
help : 'metric_help' ,
buckets : [ 0.1 , 5 , 15 , 50 , 100 , 500 ] ,
} ) ;
const client = require ( 'prom-client' ) ;
const histogram = new client . Histogram ( {
name : 'metric_name' ,
help : 'metric_help' ,
} ) ;
histogram . observe ( 10 ) ; // Observe value in histogram
const end = histogram . startTimer ( ) ;
xhrRequest ( function ( err , res ) {
const seconds = end ( ) ; // Observes and returns the value to xhrRequests duration in seconds
} ) ;
摘要計算觀察值的百分位數。
預設百分位數為:0.01、0.05、0.5、0.9、0.95、0.99、0.999。但可以透過指定percentiles
數組來覆寫它們。 (另請參閱桶生成器。)
const client = require ( 'prom-client' ) ;
new client . Summary ( {
name : 'metric_name' ,
help : 'metric_help' ,
percentiles : [ 0.01 , 0.1 , 0.9 , 0.99 ] ,
} ) ;
若要啟用摘要的滑動視窗功能,您需要將maxAgeSeconds
和ageBuckets
新增至設定中,如下所示:
const client = require ( 'prom-client' ) ;
new client . Summary ( {
name : 'metric_name' ,
help : 'metric_help' ,
maxAgeSeconds : 600 ,
ageBuckets : 5 ,
pruneAgedBuckets : false ,
} ) ;
maxAgeSeconds
將告訴儲存桶在重置之前可以有多久,而ageBuckets
配置我們在滑動視窗中將有多少個儲存桶用於摘要。如果pruneAgedBuckets
為false
(預設),則指標值將始終存在,即使為空(其百分位值為0
)。如果您不想在它為空時導出它,請將pruneAgedBuckets
設為true
。
const client = require ( 'prom-client' ) ;
const summary = new client . Summary ( {
name : 'metric_name' ,
help : 'metric_help' ,
} ) ;
summary . observe ( 10 ) ;
const end = summary . startTimer ( ) ;
xhrRequest ( function ( err , res ) {
end ( ) ; // Observes the value to xhrRequests duration in seconds
} ) ;
所有指標都可以採用配置物件中的labelNames
屬性。指標支援的所有標籤名稱都需要在此聲明。有兩種方法可以為標籤新增值:
const client = require ( 'prom-client' ) ;
const gauge = new client . Gauge ( {
name : 'metric_name' ,
help : 'metric_help' ,
labelNames : [ 'method' , 'statusCode' ] ,
} ) ;
// 1st version: Set value to 100 with "method" set to "GET" and "statusCode" to "200"
gauge . set ( { method : 'GET' , statusCode : '200' } , 100 ) ;
// 2nd version: Same effect as above
gauge . labels ( { method : 'GET' , statusCode : '200' } ) . set ( 100 ) ;
// 3rd version: And again the same effect as above
gauge . labels ( 'GET' , '200' ) . set ( 100 ) ;
還可以在創建計時器之前和之後使用帶標籤的計時器:
const end = startTimer ( { method : 'GET' } ) ; // Set method to GET, we don't know statusCode yet
xhrRequest ( function ( err , res ) {
if ( err ) {
end ( { statusCode : '500' } ) ; // Sets value to xhrRequest duration in seconds with statusCode 500
} else {
end ( { statusCode : '200' } ) ; // Sets value to xhrRequest duration in seconds with statusCode 200
}
} ) ;
帶標籤的指標在至少被觀察一次之前無法導出,因為在觀察之前可能不知道可能的標籤值。
對於直方圖,可以透過明確地將所有預期標籤值歸零來解決:
const histogram = new client . Histogram ( {
name : 'metric_name' ,
help : 'metric_help' ,
buckets : [ 0.1 , 5 , 15 , 50 , 100 , 500 ] ,
labels : [ 'method' ] ,
} ) ;
histogram . zero ( { method : 'GET' } ) ;
histogram . zero ( { method : 'POST' } ) ;
Typescript 也可以使用as const
強制標籤名稱
import * as client from 'prom-client' ;
const counter = new client . Counter ( {
name : 'metric_name' ,
help : 'metric_help' ,
// add `as const` here to enforce label names
labelNames : [ 'method' ] as const ,
} ) ;
// Ok
counter . inc ( { method : 1 } ) ;
// this is an error since `'methods'` is not a valid `labelName`
// @ts-expect-error
counter . inc ( { methods : 1 } ) ;
靜態標籤可以應用於註冊表發出的每個指標:
const client = require ( 'prom-client' ) ;
const defaultLabels = { serviceName : 'api-v1' } ;
client . register . setDefaultLabels ( defaultLabels ) ;
這將以下列方式輸出指標:
# HELP process_resident_memory_bytes Resident memory size in bytes.
# TYPE process_resident_memory_bytes gauge
process_resident_memory_bytes{serviceName="api-v1"} 33853440 1498510040309
如果存在名稱衝突,預設標籤將被覆蓋。
register.clear()
將清除預設標籤。
OpenMetrics 規格中定義的範例可以在計數器和直方圖指標類型上啟用。預設指標支援 OpenTelemetry,它們將使用標籤{traceId, spanId}
及其對應值填充範例。
如果啟用了範例,則inc()
和observe()
呼叫的格式會有所不同。他們獲得格式為{labels, value, exemplarLabels}
的單一物件。
使用範例時,用於指標的註冊表應設定為 OpenMetrics 類型(如果未指定註冊表,則包括全域或預設註冊表)。
該程式庫支援舊的 Prometheus 格式和 OpenMetrics 格式。可根據註冊表設定格式。對於預設指標:
const Prometheus = require ( 'prom-client' ) ;
Prometheus . register . setContentType (
Prometheus . Registry . OPENMETRICS_CONTENT_TYPE ,
) ;
目前可用的註冊表類型由內容類型定義:
PROMETHEUS_CONTENT_TYPE - 原始 Prometheus 指標的版本 0.0.4,這是目前預設的登錄類型。
OPENMETRICS_CONTENT_TYPE - 預設為 OpenMetrics 標準版本 1.0.0。
每個登錄類型的 HTTP Content-Type 字串都在模組層級( prometheusContentType
和openMetricsContentType
)公開,並作為Registry
物件上的靜態屬性公開。
模組暴露的contentType
常數傳回建立新註冊表時的預設內容類型,目前預設為 Prometheus 類型。
預設情況下,指標會自動註冊到全域註冊表(位於require('prom-client').register
)。您可以透過在度量建構函式配置中指定registers: []
來防止這種情況。
使用非全域註冊表需要建立一個登錄實例並將其傳遞到指標配置物件的registers
內。或者,您可以傳遞一個空registers
數組並手動註冊它。
註冊表具有merge
功能,可讓您在同一端點上公開多個註冊表。如果兩個註冊表中存在相同的指標名稱,則會引發錯誤。
不同類型的合併註冊表是未定義的。使用者需要確保所有使用的註冊表具有相同的類型(Prometheus 或 OpenMetrics 版本)。
const client = require ( 'prom-client' ) ;
const registry = new client . Registry ( ) ;
const counter = new client . Counter ( {
name : 'metric_name' ,
help : 'metric_help' ,
registers : [ registry ] , // specify a non-default registry
} ) ;
const histogram = new client . Histogram ( {
name : 'metric_name' ,
help : 'metric_help' ,
registers : [ ] , // don't automatically register this metric
} ) ;
registry . registerMetric ( histogram ) ; // register metric manually
counter . inc ( ) ;
const mergedRegistries = client . Registry . merge ( [ registry , client . register ] ) ;
如果您想要在 Node.js cluster
模組中使用多個或非預設註冊表,則需要將登錄機碼設定為從下列位置聚合:
const AggregatorRegistry = client . AggregatorRegistry ;
AggregatorRegistry . setRegistries ( registry ) ;
// or for multiple registries:
AggregatorRegistry . setRegistries ( [ registry1 , registry2 ] ) ;
您可以透過執行await register.metrics()
來取得所有指標,這將傳回Prometheus exposition格式的字串。
如果需要以 Prometheus 展示格式輸出單一指標,可以使用await register.getSingleMetricAsString(*name of metric*)
,它將傳回一個字串供 Prometheus 使用。
如果您需要取得先前註冊的指標的引用,可以使用register.getSingleMetric(*name of metric*)
。
您可以透過呼叫register.clear()
刪除所有指標。您也可以透過呼叫register.removeSingleMetric(*name of metric*)
來刪除單一指標。
如果需要重置所有指標,可以使用register.resetMetrics()
。這些指標將保留在暫存器中,並且無需再次實例化即可使用,就像您在register.clear()
之後需要做的那樣。
您可以使用await register.clusterMetrics()
來取得 Node.js 叢集中所有工作執行緒的聚合指標。此方法傳回一個承諾,該承諾使用適合 Prometheus 使用的指標字串進行解析。
const metrics = await register . clusterMetrics ( ) ;
// - or -
register
. clusterMetrics ( )
. then ( metrics => {
/* ... */
} )
. catch ( err => {
/* ... */
} ) ;
可以透過 Pushgateway 推送指標。
const client = require ( 'prom-client' ) ;
let gateway = new client . Pushgateway ( 'http://127.0.0.1:9091' ) ;
gateway . pushAdd ( { jobName : 'test' } )
. then ( ( { resp , body } ) => {
/* ... */
} )
. catch ( err => {
/* ... */
} ) ) ; //Add metric and overwrite old ones
gateway . push ( { jobName : 'test' } )
. then ( ( { resp , body } ) => {
/* ... */
} )
. catch ( err => {
/* ... */
} ) ) ; //Overwrite all metrics (use PUT)
gateway . delete ( { jobName : 'test' } )
. then ( ( { resp , body } ) => {
/* ... */
} )
. catch ( err => {
/* ... */
} ) ) ; //Delete all metrics for jobName
//All gateway requests can have groupings on it
gateway . pushAdd ( { jobName : 'test' , groupings : { key : 'value' } } )
. then ( ( { resp , body } ) => {
/* ... */
} )
. catch ( err => {
/* ... */
} ) )