github地址:https://github.com/siimon/prom-client
(此文为尚不熟悉时所译,如有错误烦请指出修改)
Readme:
这是一个支持histogram, summaries, gauges and counters四种数值格式的prometheus nodejs客户端。
用法
在example文件夹中有用法示例。这个库不会绑定任何web框架,只会在registry中返回metrics()函数来显示metrics。
通过nodejs的cluster模式使用
nodejs的cluster模式产生了多进程并且不会干涉socket连接其他workers。从一个worker的本地registry返回metrics只会显示那个worker自己的metrics,这一般是不可取的。为了解决这点,你可以在主进程合并所有worker的metrics。查看example/cluster.js获取示例。
默认的metrics使用合理的聚合方法。自定义metrics默认会按照workers求和。要使用不同的合并方法,需要在metric配置中设置aggregator属性为'sum', 'first', 'min', 'max', 'average' or 'omit'的其中一个。(查看lib/metrics/version.js获取示例。)
如果你想要显示一个worker的metrics,可以包含一个只属于这个worker的值(比如worker ID或者进程ID)在标签中。(查看example/server.js获取使用worker_${cluster.worker.id}作为标签值的示例。)
metrics默认会通过全局registry来聚合。要使用不同的registry,就在worker进程中调用client.AggregatorRegistry.setRegistries(registryOrArrayOfRegistries)。
API
配置
所有的metrics类型都有两个强制的参数:name和help。
默认metrics
有一些Prometheus自身推荐的默认metrics。要采集这些,就调用collectDefaultMetrics
注意:有些metrics,关于文件描述符和内存的,只在Linux可获取。
此外,包含了一些node特有的metrics,比如事件循环滞后( event loop lag),active handles和nodejs版本。在 lib/metrics 查看有哪些metrics。
collectDefaultMetrics 获取一个有三个条目的选项对象,一个指定探测多久执行一次的timeout参数,一个表示metric名称的可选前缀和一个表示哪个metrics需要被注册的注册器。默认为每10秒探测一次,但这可以像这样修改:
const client = require('prom-client');
const collectDefaultMetrics = client.collectDefaultMetrics;
// Probe every 5th second.
collectDefaultMetrics({ timeout: 5000 });
注册metrics到其他注册器,传递一个注册器进来:
const client = require('prom-client');
const collectDefaultMetrics = client.collectDefaultMetrics;
const Registry = client.Registry;
const register = new Registry();
collectDefaultMetrics({ register });
传入一个前缀来以任意字符串作为metrics前缀名:
const client = require('prom-client');
const collectDefaultMetrics = client.collectDefaultMetrics;
// Probe every 5th second.
collectDefaultMetrics({ prefix: 'my_application_' });
你可以通过检查client.collectDefaultMetrics.metricsList来获取metrcis的所有条目。
collectDefaultMetrics 会在调用时返回一个身份标识,这是一个依赖于Timer的,用来保持探测进行。要停止所有的探测,可以传入clearInterval 。
注意:现有的间隔会在调用collectDefaultMetrics时自动清除。
const client = require('prom-client');
const collectDefaultMetrics = client.collectDefaultMetrics;
const interval = collectDefaultMetrics();
// ... some time later
clearInterval(interval);
注意:unref 会在interval 内部调用,所以它不会在作为唯一保持避免停止的程序时保持你的node进程运行。
停止轮询默认metrics
要停止采集默认metrics,你需要调用调用函数并传给clearInterval。
const client = require('prom-client');
clearInterval(client.collectDefaultMetrics());
// Clear the register
client.register.clear();
Counter数值
Counter会持续增长,并在进程重启时重置。
const client = require('prom-client');
const counter = new client.Counter({
name: 'metric_name',
help: 'metric_help'
});
counter.inc(); // Inc with 1
counter.inc(10); // Inc with 10
Gauge数值
Gauge类似Counter,但Gauge值可以减少。
const client = require('prom-client');
const gauge = new client.Gauge({ name: 'metric_name', help: 'metric_help' });
gauge.set(10); // Set to 10
gauge.inc(); // Inc with 1
gauge.inc(10); // Inc with 10
gauge.dec(); // Dec with 1
gauge.dec(10); // Dec with 10
有一些公用的工具案例:
gauge.setToCurrentTime(); // Sets value to current time
const end = gauge.startTimer();
xhrRequest(function(err, res) {
end(); // Sets value to xhrRequests duration in seconds
});
Histogram数值
Histogram追踪事件的尺寸和频率
配置
默认的桶用来覆盖常规的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');
new client.Histogram({
name: 'metric_name',
help: 'metric_help',
labelNames: ['status_code'],
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) {
end(); // Observes the value to xhrRequests duration in seconds
});
Summary数值
Summary用来计算观察值的百分数。
配置
默认百分数为0.01, 0.05, 0.5, 0.9, 0.95, 0.99, 0.999。但他们可以这样改写:
const client = require('prom-client');
new client.Summary({
name: 'metric_name',
help: 'metric_help',
percentiles: [0.01, 0.1, 0.9, 0.99]
});
为了确保summary的滑动窗口功能,你需要像这样在配置中添加maxAgeSeconds 和ageBuckets :
const client = require('prom-client');
new client.Summary({
name: 'metric_name',
help: 'metric_help',
maxAgeSeconds: 600,
ageBuckets: 5
});
maxAgeSeconds会指定一个bucket多久之后会重置,ageBuckets指定在我们的summary滑动窗口中有多少buckets。
使用示例:
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
});
Labels
所有的metrics都可以在配置对象中设置一个标签名属性。所有metric支持的标签名都需要在这申明。有两个方法来添加标签:
const client = require('prom-client');
const gauge = new client.Gauge({
name: 'metric_name',
help: 'metric_help',
labelNames: ['method', 'statusCode']
});
gauge.set({ method: 'GET', statusCode: '200' }, 100); // 1st version, Set value 100 with method set to GET and statusCode to 200
gauge.labels('GET', '200').set(100); // 2nd version, Same as above
也可能通过标签使用计时器,在即使前前后都会创建:
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
}
});
默认标签(按注册器分割)
静态的标签可能应用于一个注册器下的每个metric:
const client = require('prom-client');
const defaultLabels = { serviceName: 'api-v1' };
client.register.setDefaultLabels(defaultLabels);
这会按下面的方式输出所有metrics:
# 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()会清除默认标签。
时间戳
Counter和Gauge metrics可以在值参数后接收一个时间戳参数。这个参数必须是一个Date或者一个数字(milliseconds since Unix epoch, i.e. 1970-01-01 00:00:00 UTC,不计跳跃秒数)。
gauge.set(100, 1485531442231); // Set gauge value and timestamp as milliseconds since Unix epoch
gauge.set(100, Date.now()); // Set gauge value and timestamp as milliseconds since Unix epoch
gauge.set(100, new Date()); // Set gauge value and timestamp as Date
gauge.set({ method: 'GET', statusCode: '200' }, 100, new Date()); // Set gauge value and timestamp with labels
gauge.labels('GET', '200').set(100, new Date()); // Same as above
counter.inc(1, new Date()); // Increment counter with timestamp
多注册器
默认情况下,metrics是自动注册到全局注册器(require('prom-client').register)的。你可以在创建metric时通过设置最后一个参数为false(依赖于metric,这可能是第四或第五个参数)来避免这样做。
使用非全局注册器需要创建注册器实例并添加它到配置对象的registers中。或者你可以传入一个空registers数组并手动去注册它。
注册器有一个merge函数可以用来在同一个端点暴露多个注册器。如果同一个metric名在不同注册器中存在,会抛出一个错误。
const client = require('prom-client');
const registry = new client.Registry();
const counter = new client.Counter({
name: 'metric_name',
help: 'metric_help',
registers: [registry]
});
const histogram = new client.Histogram({
name: 'metric_name',
help: 'metric_help',
registers: []
});
registry.registerMetric(histogram);
counter.inc();
const mergedRegistries = client.Registry.merge([registry, client.register]);
如果你想要在nodejs cluster模式下使用多个或非默认注册器,需要设置注册器合并:
const AggregatorRegistry = client.AggregatorRegistry;
AggregatorRegistry.setRegistries(registry);
// or for multiple registries:
AggregatorRegistry.setRegistries([registry1, registry2]);
注册器
你可以通过运行register.metrics()获取所有的metrics,这会输出一个字符串给prometheus。
register.metrics()接受一个时间戳范围的可选对象。将之设为false会将字符串的时间戳去除。
获取单个metric供prometheus展示
如果你需要输出单个metric给prometheus,可以使用register.getSingleMetricAsString(name of metric),这会输出一个字符串给prometheus。
获取单个metric
如果你需要获取一个之前注册的metric,可以使用register.getSingleMetric(name of metric)。
移除metrics
你可以调用register.clear()移除所有metrics。还可以调用register.removeSingleMetric(name of metric)移除单个metric。
重置metrics
如果你需要重置所有metrics,可以使用register.resetMetrics()。这些metrics会保留在注册器中,并无需再次实例化它们就能使用,但在register.clear()之后你需要实例化。
Cluster metrics
你可以在nodejs cluster中通过register.clusterMetrics()获取所有workers的聚合metrics。该方法返回一个promise并接收一个callback,这两者都解决一个适合传给prometheus的metrics字符串。
register
.clusterMetrics()
.then(metrics => {
/* ... */
})
.catch(err => {
/* ... */
});
// - or -
register.clusterMetrics((err, metrics) => {
// ...
});
Pushgateway
可以通过Pushgateway来push metrics。
注意时间戳会在metrics被push前被剥夺,因为Pushgateway >= 0.4 将不接受时间戳。
const client = require('prom-client');
let gateway = new client.Pushgateway('http://127.0.0.1:9091');
gateway.pushAdd({ jobName: 'test' }, function(err, resp, body) {}); //Add metric and overwrite old ones
gateway.push({ jobName: 'test' }, function(err, resp, body) {}); //Overwrite all metrics (use PUT)
gateway.delete({ jobName: 'test' }, function(err, resp, body) {}); //Delete all metrics for jobName
//All gateway requests can have groupings on it
gateway.pushAdd({ jobName: 'test', groupings: { key: 'value' } }, function(
err,
resp,
body
) {});
//It's possible to extend the Pushgateway with request options from nodes core http/https library
gateway = new client.Pushgateway('http://127.0.0.1:9091', { timeout: 5000 }); //Set the request timeout to 5000ms
Utilites
为了方便,有两个桶生成器函数——线性和指数的。
const client = require('prom-client');
new client.Histogram({
name: 'metric_name',
help: 'metric_help',
buckets: client.linearBuckets(0, 10, 20) //Create 20 buckets, starting on 0 and a width of 10
});
new client.Histogram({
name: 'metric_name',
help: 'metric_help',
buckets: client.exponentialBuckets(1, 2, 5) //Create 5 buckets, starting on 1 and with a factor of 2
});
在注册器和本工程的主文件中,prometheus期待的内类类型都是作为常量输出的,称为contentType。