尝试使用OpenTelemetry在Node.js上进行指标收集
首先
由于之前已经使用Node.js(JavaScript)进行了OpenTelemetry的跟踪数据收集,所以这次我想总结一下关于收集计数器值等度量数据的情况。
有关OpenTelemetry的概述和跟踪数据收集的文章请参阅此处。
尝试一下
执行环境
-
- MacOS X
-
- node: v13.8.0
-
- npm: v7.5.3
-
- express: v4.17.1
- OpenTelemetry: v0.18
1. 创建样本配置
首先创建一个基本的示例应用程序。
示例的内容是,当访问URL时,会返回红色、蓝色或黄色中的一种,这是一个简单的逻辑。
1.1 创建样本
在项目中安装Express。
$ npm install express
创建应用程序(app.js)。
'use strict';
const express = require('express');
const app = express();
const PORT = process.env.PORT || '8080';
app.use(function(req, res, next) {
// ランダムで色を選ぶ
const color = ['red', 'blue', 'blue', 'yellow', 'yellow', 'yellow'];
res.locals.color = color[Math.floor(Math.random() * color.length)];
next();
});
app.get('/', (req, res, next) => {
res.send(res.locals.color);
next();
});
app.listen(parseInt(PORT, 10), () => {
console.log(`Listening for requests on http://localhost:${PORT}`);
});
1.2 确认样本的操作
运行样本后,会开始接受来自客户端的请求,并在localhost:8080上等待。
$ node app.js
Listening for requests on http://localhost:8080
从另一个终端访问示例的URL。
$ curl localhost:8080
red
如上所述,将返回红色、蓝色或黄色中的任一种颜色。
2. Prometheus的启动
作为度量收集的准备工作,我们将构建一个Prometheus来对度量数据进行图形化。这次我们将使用Docker容器版本。
在容器启动之前,首先创建prometheus.yml文件。
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'opentelemetry'
static_configs:
- targets:
- 'host.docker.internal:9464'
targets 是 Prometheus 中收集度量数据的地方。
本次将作为主机,但从容器的角度来看,主机不是 localhost,而是 host.docker.internal(localhost 是指容器)。
需要注意的是,host.docker.internal 在 Linux 上无法使用(但在 Mac 和 Windows 上可以),因此在 Linux 环境中,请将其替换为主机的 IP 地址。
docker run \
-d \
-p 9090:9090 \
-v /path/to/prometheus.yml:/etc/prometheus/prometheus.yml \
prom/prometheus
访问 localhost:9090,若出现 Prometheus 的图形界面,则表示启动成功。
3. OpenTelemetry的集成
现在,我们将在之前制作的示例中,集成OpenTelemetry进行指标数据收集。
3.1 安装软件包
$ npm install @opentelemetry/metrics @opentelemetry/exporter-prometheus
创建3.2 monitoring.js
我会创建一个将计数器逻辑嵌入样本中的方法。
'use strict';
const { MeterProvider } = require('@opentelemetry/metrics');
const { PrometheusExporter } = require('@opentelemetry/exporter-prometheus');
const prometheusPort = PrometheusExporter.DEFAULT_OPTIONS.port
const prometheusEndpoint = PrometheusExporter.DEFAULT_OPTIONS.endpoint
const exporter = new PrometheusExporter(
{
startServer: true,
},
() => {
console.log(
`prometheus scrape endpoint: http://localhost:${prometheusPort}${prometheusEndpoint}`,
);
},
);
const meter = new MeterProvider({
exporter,
interval: 1000,
}).getMeter('color-meter');
const colorCount = meter.createCounter('colors', {
description: 'Count each color'
});
// 色ごとにCounterを生成する
const redCounter = colorCount.bind({ color: 'red'});
const blueCounter = colorCount.bind({ color: 'blue'});
const yellowCounter = colorCount.bind({ color: 'yellow'});
module.exports.countColorRequests = () => {
return (req, res, next) => {
switch (res.locals.color) {
case 'red':
redCounter.add(1);
break;
case 'blue':
blueCounter.add(1);
break;
case 'yellow':
yellowCounter.add(1);
break;
}
next();
};
};
使用 `meter.createCounter()` 来创建计数器。
传入的字符串参数将会作为指标数据表的表名。
为了将每个已归还颜色的计数器值绘制成图表,我们将在以下示例中使用meter.createCounter()创建计数器,并将标签绑定到该计数器,从而创建三个颜色的计数器。
在这里指定的color: ‘red’相当于图表的系列名称。
const redCounter = colorCount.bind({ color: 'red'});
将样品集成
将刚刚创建的monitoring.js文件集成到示例中。
'use strict';
const express = require('express');
const app = express();
const PORT = process.env.PORT || '8080';
+ const { countColorRequests } = require("./monitoring");
app.use(function(req, res, next) {
// ランダムで色を選ぶ
const color = ['red', 'blue', 'blue', 'yellow', 'yellow', 'yellow'];
res.locals.color = color[Math.floor(Math.random() * color.length)];
next();
});
+ app.use(countColorRequests());
app.get('/', (req, res, next) => {
res.send(res.locals.color);
next();
});
app.listen(parseInt(PORT, 10), () => {
console.log(`Listening for requests on http://localhost:${PORT}`);
});
在使用Math.random()方法选择颜色后,调用countColorRequests()函数,并对选定的颜色计数器进行递增操作。
3.4 动作确认
和第一章类似,会启动示例。一旦启动,除了等待localhost:8080的请求外,还会等待来自Prometheus的指标数据获取(Pull)在localhost:9464/metrics上。
$ node app.js
Listening for requests on http://localhost:8080
prometheus scrape endpoint: http://localhost:9464/metrics
我将连续100次发送样本请求,并增加计数器的值。
$ for var in `seq 100`; do curl localhost:8080; done
您可以通过访问localhost:9464/metrics来查看计数器值。(Prometheus定期收集此信息)
$ curl http://localhost:9464/metrics
# HELP colors Count each color
# TYPE colors counter
colors{color="red"} 14 1615214799584
colors{color="blue"} 32 1615214799558
colors{color="yellow"} 54 1615214799597
那么,我将在Prometheus中尝试进行图表展示。
选择Graph选项卡,将“colors”输入到文本框中,点击执行按钮。
然后,将输出一个类似下图的图表,可以确认计数器值的增加情况。
最后
不使用OpenTelemetry也可以通过各种方法来实现度量收集,但如果要收集用户应用程序的自定义度量指标,OpenTelemetry似乎能够发挥其优势。
关于OpenTelemetry,如果还有其他有趣的功能,我想尝试一下。