عميل بروميثيوس لـ Node.js الذي يدعم الرسم البياني والملخصات والمقاييس والعدادات.
راجع مجلد المثال للحصول على عينة من الاستخدام. لا تحتوي المكتبة على أي إطار ويب. لكشف المقاييس، قم بالاستجابة لطلبات Prometheus الخاصة بالتخلص من البيانات مع نتيجة await registry.metrics()
.
cluster
Node.js تولد وحدة cluster
Node.js عمليات متعددة وتسلم اتصالات المقبس لهؤلاء العاملين. لن يؤدي إرجاع المقاييس من السجل المحلي للعامل إلا إلى الكشف عن مقاييس ذلك العامل الفردي، وهو أمر غير مرغوب فيه بشكل عام. لحل هذه المشكلة، يمكنك تجميع كافة مقاييس العاملين في العملية الرئيسية. راجع example/cluster.js
للحصول على مثال.
تستخدم المقاييس الافتراضية طرق تجميع معقولة. (لاحظ، مع ذلك، أنه يتم حساب متوسط تأخر حلقة الحدث والنسب المئوية، وهو أمر غير دقيق تمامًا.) يتم جمع المقاييس المخصصة عبر العاملين بشكل افتراضي. لاستخدام طريقة تجميع مختلفة، قم بتعيين خاصية aggregator
في تكوين المقياس على واحدة من "sum" أو "first" أو "min" أو "max" أو "average" أو "omit". (راجع lib/metrics/version.js
للحصول على مثال.)
إذا كنت بحاجة إلى الكشف عن مقاييس حول عامل فردي، فيمكنك تضمين قيمة فريدة للعامل (مثل معرف العامل أو معرف العملية) في التسمية. (راجع example/server.js
للحصول على مثال باستخدام worker_${cluster.worker.id}
كقيمة تسمية.)
يتم تجميع المقاييس من السجل العالمي بشكل افتراضي. لاستخدام تسجيل مختلف، اتصل client.AggregatorRegistry.setRegistries(registryOrArrayOfRegistries)
من العمليات المنفذة.
هناك بعض المقاييس الافتراضية التي أوصت بها شركة بروميثيوس نفسها. لجمعها، اتصل بـ 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 ( ) ;
} ) ;
الرسوم البيانية تتبع أحجام وتواتر الأحداث.
تهدف مجموعات الإعدادات الافتراضية إلى تغطية طلبات الويب/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 - الإصدار 0.0.4 من مقاييس Prometheus الأصلية، وهذا هو نوع التسجيل الافتراضي حاليًا.
OPENMETRICS_CONTENT_TYPE - الإعداد الافتراضي هو الإصدار 1.0.0 من معيار OpenMetrics.
يتم عرض سلسلة نوع محتوى HTTP لكل نوع تسجيل على مستوى الوحدة النمطية ( 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 ] ) ;
إذا كنت تريد استخدام سجلات متعددة أو غير افتراضية مع وحدة cluster
Node.js، فستحتاج إلى تعيين السجل/السجلات للتجميع من:
const AggregatorRegistry = client . AggregatorRegistry ;
AggregatorRegistry . setRegistries ( registry ) ;
// or for multiple registries:
AggregatorRegistry . setRegistries ( [ registry1 , registry2 ] ) ;
يمكنك الحصول على جميع المقاييس عن طريق تشغيل await register.metrics()
، والذي سيعيد سلسلة بتنسيق عرض Prometheus.
إذا كنت بحاجة إلى إخراج مقياس واحد بتنسيق عرض Prometheus، فيمكنك استخدام await register.getSingleMetricAsString(*name of metric*)
، والذي سيعيد سلسلة ليستهلكها Prometheus.
إذا كنت تريد الحصول على مرجع لمقياس تم تسجيله مسبقًا، فيمكنك استخدام register.getSingleMetric(*name of metric*)
.
يمكنك إزالة كافة المقاييس عن طريق استدعاء register.clear()
. يمكنك أيضًا إزالة مقياس واحد عن طريق استدعاء register.removeSingleMetric(*name of metric*)
.
إذا كنت بحاجة إلى إعادة تعيين جميع المقاييس، فيمكنك استخدام register.resetMetrics()
. ستبقى المقاييس موجودة في السجل ويمكن استخدامها دون الحاجة إلى إنشاء مثيل لها مرة أخرى، كما ستحتاج إلى القيام به بعد register.clear()
.
يمكنك الحصول على مقاييس مجمعة لجميع العاملين في مجموعة Node.js باستخدام await register.clusterMetrics()
. تُرجع هذه الطريقة وعدًا يتم حله باستخدام سلسلة مقاييس مناسبة لاستهلاك 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 => {
/* ... */
} ) )