metric - 健康检测
zenweb 健康检测模块,用于生产环境的实例运行信息收集
依赖模块
无
快速使用
npm install @zenweb/metric
src/index.ts
import modMetric from '@zenweb/metric';
// ...
.setup(modMetric())
// ...
配置项
| 配置项 | 类型 | 默认值 | 功能 |
|---|---|---|---|
| dir | string | env.LOG_DIR 或 /tmp | 日志输出目录 |
| filename | string | zenweb-metric.{yyyy}-{mm}-{dd}.log | 日志文件名模板 |
| sampleInterval | number | env.ZENWEB_METRIC_SAMPLE_INTERVAL 或 10000 | 采样间隔(毫秒) |
| slowTime | number | env.ZENWEB_METRIC_SLOW_TIME 或 100 | 慢请求阈值(毫秒) |
采集指标列表
每个采样周期内,metric 模块会采集以下指标并写入日志文件:
| 指标名 | 类型 | 说明 |
|---|---|---|
timestamp | number | 本次记录的时间戳(秒) |
interval | number | 本次采样的时间范围(毫秒) |
cpu_time | number | 本次采样周期内的 CPU 用时(毫秒),包含 user + system |
mem_rss | number | 进程常驻内存 RSS(字节) |
mem_heap_total | number | V8 堆内存总大小(字节) |
mem_heap_used | number | V8 堆内存已使用(字节) |
mem_os_free | number | 操作系统空闲内存(字节) |
os_load | number | 操作系统 1 分钟平均负载 / CPU 核心数 |
requests | number | 本次采样周期内的请求总数 |
requests_slow | number | 本次采样周期内的慢请求数(超过 slowTime 阈值) |
requests_time | number | 本次采样周期内所有请求的总耗时(毫秒) |
通过 metricRegister 注册的自定义采集器还可以向 MetricData 对象追加额外的字段。
日志输出格式
metric 模块使用 zenlog.js 输出日志,每条日志为一个 JSON 对象,包含以下结构:
{
"name": "my-app",
"instance": "hostname-12345",
"level": "INFO",
"timestamp": "2025-01-15T08:30:00.000Z",
"record": {
"timestamp": 1705296600,
"interval": 10000,
"cpu_time": 156,
"mem_rss": 67108864,
"mem_heap_total": 44728320,
"mem_heap_used": 32456789,
"mem_os_free": 2147483648,
"os_load": 0.245,
"requests": 1523,
"requests_slow": 12,
"requests_time": 45890
}
}
通过 name 和 instance 字段可以区分不同的应用和实例,便于在日志聚合系统中进行分析。
慢请求与 Apdex
慢请求
当请求耗时超过配置的 slowTime(默认 100 毫秒)时,该请求会被统计为慢请求。每个采样周期内的慢请求数量记录在 requests_slow 字段中。
可以通过环境变量调整慢请求阈值:
# 设置慢请求阈值为 200 毫秒
ZENWEB_METRIC_SLOW_TIME=200 node dist/index.js
Apdex(Application Performance Index)
Apdex 是衡量应用性能满意度的标准指标,取值范围为 0 到 1。计算公式为:
Apdex = (满意数 + 0.5 × 可容忍数) / 总请求数
其中:
- 满意(Satisfied):响应时间 <= T(阈值)
- 可容忍(Tolerating):响应时间在 T 到 4T 之间
- 不满意(Frustrated):响应时间 > 4T
通过 requests、requests_slow、requests_time 三个指标,可以在日志分析系统中计算出 Apdex 值。调整 slowTime 参数会影响满意与可容忍的判定边界,建议根据业务 SLA 设置合理的阈值。
一般建议:
- API 接口:
slowTime设为 100-200 毫秒 - 页面渲染:
slowTime设为 200-500 毫秒 - 后台任务:
slowTime设为 1000 毫秒或更高
metricRegister 自定义指标注册
metricRegister 允许注册自定义的数据采集回调函数,在每个采样周期触发时会传递 MetricData 对象。可以在回调中向 MetricData 追加自定义字段,用于监控业务特定的指标。
使用示例
src/index.ts
import { create } from 'zenweb';
import modMetric from '@zenweb/metric';
const app = create();
app.setup(modMetric());
// 注册自定义指标采集器
app.setup(async (setup) => {
setup.core.metricRegister.register((data) => {
// 追加自定义指标
data.active_connections = getActiveConnectionCount();
data.queue_length = getMessageQueueLength();
});
});
与 @zenweb/mysql 集成采集连接池指标
@zenweb/mysql 模块会自动注册 metric 采集器,将 MySQL 连接池的状态信息写入指标中。如果同时安装了 @zenweb/metric 和 @zenweb/mysql,日志中会额外包含以下字段:
| 字段名 | 说明 |
|---|---|
mysql_pool_total | 连接池总连接数 |
mysql_pool_free | 连接池空闲连接数 |
mysql_pool_waiting | 等待连接的请求数 |
这些指标可以帮助监控数据库连接池的健康状态,及时发现连接泄漏或连接不足的问题。
自定义业务指标示例
import { create } from 'zenweb';
import modMetric from '@zenweb/metric';
import modMysql from '@zenweb/mysql';
const app = create();
app.setup(modMetric());
app.setup(modMysql());
// 注册业务指标
app.setup(async (setup) => {
setup.core.metricRegister.register(async (data) => {
// 统计今日订单数
const result = await setup.core.mysql.query(
'SELECT COUNT(*) as count FROM orders WHERE created_at >= CURDATE()'
);
data.orders_today = result[0].count;
// 统计待处理任务
data.pending_tasks = await getPendingTaskCount();
});
});
环境变量
| 环境变量 | 默认值 | 说明 |
|---|---|---|
LOG_DIR | /tmp | 日志文件输出目录 |
ZENWEB_METRIC_SAMPLE_INTERVAL | 10000 | 采样间隔(毫秒) |
ZENWEB_METRIC_SLOW_TIME | 100 | 慢请求阈值(毫秒) |