- 后端
- 微服务
【免费下载链接】loopback-next
LoopBack makes it easy to build modern API applications that require complex integrations.
@loopback/metrics是 LoopBack 4 官方仓库(loopback-next)中的扩展组件,负责将Node.js 运行时、LoopBack 框架本身以及应用业务代码三方面的指标(Metrics)以 Prometheus 文本格式暴露出来,供 Prometheus 服务器抓取(pull)或主动推送到 Pushgateway(push)。读完本文,你将掌握该组件的安装接入、MetricsBindings.COMPONENT配置项的完整含义、四种 LoopBack 方法调用指标的底层采集原理,以及如何通过仓库自带的metrics-prometheus示例一键跑通“应用 → Prometheus → 查询面板”的完整链路。
本文以 extensions/metrics/README.md 为核心文档,并结合其源码(metrics.component.ts、types.ts、metrics.interceptor.ts 等)与验收测试进行深度展开。
组件概览:它会采集什么
该组件官方定位为:向 Prometheus 报告Node.js、LoopBack 框架与你的应用三者的运行指标。从文档与源码可以确认,指标来源分为三类:
- Node.js 运行时指标—— 由依赖库
prom-client的内置默认采集器(collectDefaultMetrics)提供,例如 CPU 时间、内存占用、事件循环延迟、libuv 句柄/请求、堆(heap)空间等; - LoopBack 方法调用指标—— 由本组件自带的全局拦截器(Interceptor)在每次 Controller 方法被调用时记录,包括调用次数、耗时等;
- 应用自定义指标—— 应用代码或其他模块需要自行埋点(instrumentation)来定义和上报。
需要特别说明的是,该组件当前处于实验性(Experimental)阶段:它使用0.x.y版本号发布(本仓库中版本为0.15.16,见 package.json),API 与功能在未来版本中可能发生破坏性变更,生产环境接入前请评估升级成本。
依赖与运行环境
根据 package.json:
- 运行时依赖:
prom-client@^14.2.0、tslib@^2.8.1; - 对等依赖(peerDependencies):
@loopback/core@^7.0.0与@loopback/rest@^15.0.1,意味着它面向基于 REST 服务的 LoopBack 4 应用; - 支持的 Node.js 版本为
22 || 24 || 26。
安装与快速接入
安装
npm install --save @loopback/metrics在自定义 Application 构造函数中注册组件
组件应在你的应用类构造函数中加载。先导入组件类:
import {MetricsComponent} from '@loopback/metrics';然后在构造函数中把组件添加到应用:
this.component(MetricsComponent);在默认配置下,指标路由会挂载在/metrics,以纯文本(text/plain)形式返回当前进程的全部指标。组件底层会做四件事(对应 metrics.component.ts 的构造逻辑):
- 若
defaultMetrics未禁用,注册MetricsObserver生命周期观察者,用于启动 Node.js 默认指标采集; - 若
pushGateway配置存在且未禁用,注册MetricsPushObserver观察者,用于周期性地向 Pushgateway 推送指标; - 注册全局拦截器
MetricsInterceptor,为所有方法调用采集指标; - 若
endpoint未禁用,注册一个指标 Controller(工厂函数metricsControllerFactory动态生成),对外暴露GET {basePath}路由。
配置详解:MetricsBindings.COMPONENT
组件的全部配置都通过MetricsBindings.COMPONENT这个绑定键注入。配置类型MetricsOptions定义在 types.ts,包含endpoint、defaultMetrics、defaultLabels、pushGateway、openApiSpec五个字段,下面逐一说明。
基础配置示例(来自官方 README)
this.configure(MetricsBindings.COMPONENT).to({ endpoint: { basePath: '/metrics', }, defaultMetrics: { timeout: 5000, }, defaultLabels: { service: 'api', version: '1.0.0', }, });⚠️ 官方文档特别提示:
this.configure()必须在this.component()之前调用,否则配置不会生效。
组件在构造函数中会把用户配置与DEFAULT_METRICS_OPTIONS做浅合并(...DEFAULT_METRICS_OPTIONS, ...metricsConfig)。默认值定义在 types.ts:
export const DEFAULT_METRICS_OPTIONS: MetricsOptions = { endpoint: { basePath: '/metrics', }, defaultMetrics: {}, openApiSpec: false, };即:默认端点路径为/metrics、默认开启 Node.js 默认指标、默认关闭 OpenAPI 暴露。
endpoint:指标端点
endpoint?: { disabled?: boolean; // 设为 true 则完全不挂载 /metrics 路由 basePath?: string; // 端点路径,默认 '/metrics' };- 修改
basePath可把指标端点放到内网或独立路径,例如/internal/metrics; - 若
disabled: true,组件不会注册指标 Controller,访问任何指标路径都会得到 404; - 该行为有验收测试覆盖:metrics.acceptance.ts 中验证了自定义
basePath后原/metrics返回 404、新路径返回 200,以及disabled时不绑定 Controller。
defaultMetrics:Node.js 默认指标采集
defaultMetrics?: { disabled?: boolean; // 设为 true 则关闭 Node.js 默认指标 } & DefaultMetricsCollectorConfiguration;这里透传了prom-client的DefaultMetricsCollectorConfiguration全部字段,常用的有:
| 字段 | 说明 |
|---|---|
timeout | 默认指标采样间隔(毫秒),README 示例中设为 5000 |
prefix | 指标名前缀,例如'myapp_',注意 Prometheus 指标名不允许包含- |
labels | 附加到默认指标上的静态标签 |
其实现位于 metrics.observer.ts:MetricsObserver在应用启动(start())时调用prom-client的collectDefaultMetrics(config),在停止(stop())时执行register.clear()清空注册表。验收测试验证了prefix: 'myapp_'生效,以及disabled: true时/metrics响应中不再出现process_cpu_user_seconds_total之类的默认指标。
defaultLabels:全局静态标签
defaultLabels?: { [labelName: string]: string; };用于给所有指标附加固定的业务标签,例如服务名、版本号、环境等。源码中通过register.setDefaultLabels(options.defaultLabels)设置(见 metrics.component.ts)。验收测试确认:配置{service: 'api', version: '1.0.0'}后,无论是默认指标还是方法调用指标,标签都会追加到序列末尾,例如:
process_cpu_user_seconds_total{service="api",version="1.0.0"} ... loopback_invocation_total{targetName="...",method="GET",path="/success",statusCode="204",service="api",version="1.0.0"} 1pushGateway:主动推送模式(push)
pushGateway?: { disabled?: boolean; url: string; // Pushgateway 地址(必填) interval?: number; // 推送间隔毫秒,默认 5000 jobName?: string; // 作业名,默认 'loopback' groupingKey?: {[key: string]: string}; // 分组键,例如 {env: 'test'} replaceAll?: boolean; // true 用 PUT 覆盖,false(默认)用 POST 追加 };实现位于 metrics.push.observer.ts:MetricsPushObserver在启动时创建prom-client的Pushgateway实例,并以setInterval周期性推送;replaceAll: false时调用gateway.pushAdd()(POST,追加指标),replaceAll: true时调用gateway.push()(PUT,整体覆盖)。这一行为被 metrics-push.acceptance.ts 用内置的 mock Pushgateway 验证:默认推送使用 POST 且puts === 0,而replaceAll: true时使用 PUT 且posts === 0。
openApiSpec:控制 OpenAPI 可见性
openApiSpec?: boolean; // 默认 false默认情况下指标端点在 OpenAPI 规范中是被隐藏的,因此在 API Explorer 中看不到/metrics。开启方式:
this.configure(MetricsBindings.COMPONENT).to({ openApiSpec: true, });从 metrics.controller.ts 可以看到实现细节:当openApiSpec为false时,路由使用隐藏 spec(responses: {}加'x-visibility': 'undocumented');为true时使用正式的200 text/plain响应定义。验收测试验证:默认情况下spec.paths为空,开启后spec.paths中出现/metrics。
收集的指标类型与底层实现
1. Node.js 默认指标(prom-client 内置)
由collectDefaultMetrics产生,涵盖进程 CPU 时间、驻留内存、事件循环延迟、libuv 句柄/请求、堆空间等,均注册到 prom-client 的全局默认注册表(global registry)中。
2. LoopBack 方法调用指标(全局拦截器)
这是本组件最有价值的自研部分。MetricsInterceptor(metrics.interceptor.ts)被注册为全局拦截器metrics(asGlobalInterceptor('metrics'),单例作用域),每次 Controller 方法被调用时都会记录四类指标:
| 指标名 | 类型 | 含义 |
|---|---|---|
loopback_invocation_duration_seconds | Gauge | 最近一次方法调用耗时(秒) |
loopback_invocation_duration_histogram | Histogram | 调用耗时直方图,bucket 边界覆盖 0.005 到 10 秒 |
loopback_invocation_total | Counter | 方法调用总次数 |
loopback_invocation_duration_summary | Summary | 调用耗时分位数摘要(quantile 0.01~0.999) |
每个指标都带四个标签:
targetName:被调用方法的目标名,形如MockController.prototype.success;method:HTTP 方法(统一大写,如GET、POST),仅当调用源是路由(route)时存在;path:路由的路径模式而非原始路径。这一点很关键——拦截器通过source.value.path取到带参数占位符的模式(如/path/{param}),避免每个真实 ID 值都生成一条新的时间序列,防止基数爆炸(见 metrics.interceptor.ts 中getPathPattern的注释与 metrics.acceptance.ts 的专门测试);statusCode:响应状态码,按以下规则推断(因为拦截器在结果写回响应之前执行):- 成功时:若响应状态为 200 且方法没有返回值,则记为 204(no content),否则取响应实际状态码;
- 出错时:取
err.statusCode或err.status;若错误码为ENTITY_NOT_FOUND则记为 404,否则 500。
验收测试覆盖了完整状态码矩阵(200/204/302/400/404/500),以及仅通过createProxyWithInterceptors调用的非路由场景下只带targetName标签。
需要留意的是,该拦截器只统计方法调用,序列中的 sequence actions 与中间件(middleware)不在统计范围内,拦截器源码的注释也明确说明了这一点;如需覆盖更广的范围,应在其他位置自行埋点。
3. 应用自定义指标
组件入口 index.ts 直接export * from 'prom-client',因此你可以从@loopback/metrics直接导入 prom-client 的 API(register、Counter、Histogram、Gauge、Summary等)来定义自己的业务指标,它们会自动进入同一个全局注册表,与内置指标一起在/metrics端点输出:
import {Counter, register} from '@loopback/metrics'; const orderCounter = new Counter({ name: 'app_orders_total', help: 'Total number of orders placed', }); orderCounter.inc();Pull 与 Push:两种采集模式
Prometheus 支持两种指标采集模式,README 对此有专门说明:
- Pull(拉取):Prometheus 定期从被监控系统暴露的 HTTP 指标端点抓取数据。这是最常见的运行模式,也是
@loopback/metrics的默认工作方式(应用暴露/metrics,Prometheus 按scrape_configs去抓取); - Push(推送):被监控系统主动把指标推送到 Pushgateway,通常用于短期任务(ephemeral jobs),例如批处理、定时任务这类生命周期短暂、Prometheus 来不及抓取的作业。
两种模式组件都支持:pull 模式开箱即用;push 模式只需配置pushGateway(见上文配置表)。官方文档引用的 Prometheus 术语可以参考其 FAQ(Why do you pull rather than push)与 Pushgateway 使用实践,这里不再赘述。
动手实践:跑通 metrics-prometheus 示例
仓库自带完整示例 examples/metrics-prometheus,官方 README 给出了端到端运行步骤:
git clone https://github.com/loopbackio/loopback-next npm install npm run build cd examples/metrics-prometheus npm run demo若当前环境不需要 Docker 启动 Prometheus,也可在示例目录直接
npm start,此时 LoopBack 应用与/metrics端点依然可用。
npm run demo实际执行的是 bin/demo.sh:它先以 Docker 启动prom/prometheus(映射宿主机 9090 端口),把 bin/prometheus.yml 挂载为 Prometheus 配置,随后构建并启动 LoopBack 应用。示例应用GreetingApplication(src/application.ts)在构造函数中注册了MetricsComponent,默认监听 3000 端口(src/index.ts)。
启动后:
- 访问 Prometheus Web UI:http://localhost:9090
- 访问应用指标端点:http://localhost:3000/metrics
- 生成一些流量以便看到方法调用指标,例如:http://127.0.0.1:3000/greet/world?count=50
Prometheus 的抓取配置(bin/prometheus.yml)中定义了名为prometheus的抓取任务,目标为host.docker.internal:3000(容器内访问宿主机的 3000 端口),scrape_interval为 15 秒。下图是该示例运行后 Prometheus Web UI 中查询 LoopBack 调用耗时指标的演示效果:
/metrics 端点输出解读
GET http://localhost:3000/metrics返回 Prometheus 文本格式(text/plain)的指标,内容同时包含 Node.js 进程指标与 LoopBack 方法调用指标。以下是从官方 README 中摘取的典型输出片段(数值为示例运行时的快照,供格式参考):
# HELP process_cpu_user_seconds_total Total user CPU time spent in seconds. # TYPE process_cpu_user_seconds_total counter process_cpu_user_seconds_total 0.132181 1564508354524 # HELP process_resident_memory_bytes Resident memory size in bytes. # TYPE process_resident_memory_bytes gauge process_resident_memory_bytes 61800448 1564508354524 # HELP nodejs_eventloop_lag_seconds Lag of event loop in seconds. # TYPE nodejs_eventloop_lag_seconds gauge nodejs_eventloop_lag_seconds 0.002172946 1564508354526 # HELP nodejs_heap_size_total_bytes Process heap size from node.js in bytes. # TYPE nodejs_heap_size_total_bytes gauge nodejs_heap_size_total_bytes 27545600 1564508354526 # HELP nodejs_version_info Node.js version info. # TYPE nodejs_version_info gauge nodejs_version_info{version="v12.4.0",major="12",minor="4",patch="0"} 1方法调用指标部分(同一请求会同时产出四种指标,标签完全一致):
# HELP loopback_invocation_duration_seconds method invocation # TYPE loopback_invocation_duration_seconds gauge loopback_invocation_duration_seconds{targetName="MockController.prototype.success",method="GET",path="/success",statusCode="204"} 0.0002056 # HELP loopback_invocation_duration_histogram method invocation histogram # TYPE loopback_invocation_duration_histogram histogram loopback_invocation_duration_histogram_bucket{le="0.005",targetName="MockController.prototype.success",method="GET",path="/success",statusCode="204"} 1 loopback_invocation_duration_histogram_bucket{le="0.01",targetName="MockController.prototype.success",method="GET",path="/success",statusCode="204"} 1 loopback_invocation_duration_histogram_sum{targetName="MockController.prototype.success",method="GET",path="/success",statusCode="204"} 0.0002112 loopback_invocation_duration_histogram_count{targetName="MockController.prototype.success",method="GET",path="/success",statusCode="204"} 1 # HELP loopback_invocation_total method invocation count # TYPE loopback_invocation_total counter loopback_invocation_total{targetName="MockController.prototype.success",method="GET",path="/success",statusCode="204"} 1 # HELP loopback_invocation_duration_summary method invocation summary # TYPE loopback_invocation_duration_summary summary loopback_invocation_duration_summary{quantile="0.5",targetName="MockController.prototype.success",method="GET",path="/success",statusCode="204"} 0.0002363 loopback_invocation_duration_summary_sum{targetName="MockController.prototype.success",method="GET",path="/success",statusCode="204"} 0.0002363 loopback_invocation_duration_summary_count{targetName="MockController.prototype.success",method="GET",path="/success",statusCode="204"} 1输出结构说明:每行以# HELP或# TYPE开头的是指标元信息(名称、帮助文本、类型),其后每行是一条样本;带{...}的是标签(label),_bucket{le="..."}是直方图的桶边界,_sum/_count分别是总和与计数,summary 的quantile是分位数。注意示例中的MockController来自组件测试夹具 mock.controller.ts,它覆盖了 GET/POST/PUT/PATCH/DELETE、重定向(302)、BadRequest(400)、ENTITY_NOT_FOUND(404)、服务器错误(500)以及带路径参数的多种路由形态。
从 metrics.controller.ts 可以看到端点实现:Controller 注入 REST 响应对象,设置register.contentType作为Content-Type,再通过register.metrics()生成上述文本并发送。也就是说,输出完全由 prom-client 全局注册表驱动,任何注册到该注册表的指标都会出现在这里。
测试与验证
组件自带的验收测试覆盖了全部核心行为,是理解配置语义的最佳参考:
- metrics.acceptance.ts:默认配置下
/metrics返回 200 且内容含# TYPE/# HELP;默认从 OpenAPI spec 隐藏端点;自定义basePath、disabled开关、defaultMetrics.prefix、defaultLabels、openApiSpec;方法调用指标的各标签与路径模式替换、状态码矩阵等; - metrics-push.acceptance.ts:借助内置的 mock Pushgateway(mock-pushgateway.ts)验证推送间隔、
jobName、groupingKey与replaceAll行为。
官方 README 给出的测试方式是:在仓库根目录执行npm test。就本包而言,其 package.json 中的test脚本为lb-mocha "dist/__tests__/**/*.js"(需先npm run build编译)。
小结
@loopback/metrics用极小的接入成本(一行this.component(MetricsComponent))为 LoopBack 4 应用补齐了 Prometheus 可观测性能力:
- 开箱即用:自动暴露
/metrics端点并采集 Node.js 默认指标; - 框架级洞察:全局拦截器自动为每个 Controller 方法调用生成计数与耗时指标,且通过“路径模式 + 状态码”标签设计避免了高基数问题;
- 灵活可配:端点路径、默认指标、静态标签、OpenAPI 可见性、Pushgateway 推送等均可通过
MetricsBindings.COMPONENT配置; - 示例可跑:仓库内的
metrics-prometheus示例连同 Docker 化的 Prometheus 配置,可以在一分钟内验证从“业务请求”到“监控面板”的全链路。
如果你正在为 LoopBack 4 应用搭建云原生监控体系,这个实验性组件是快速接入 Prometheus 生态的稳妥起点——只需注意其0.x版本带来的 API 变动风险,并为业务关键指标按需补充自定义埋点。
- 后端
- 微服务
【免费下载链接】loopback-next
LoopBack makes it easy to build modern API applications that require complex integrations.
相关推荐
LoopBack 4 集成 Prometheus 指标采集:@loopback/metrics 组件实战指南
LoopBack 4 集成 Prometheus 指标采集:@loopback/metrics 组件实战指南 @loopback/metrics 是 LoopB
后端微服务LoopBack 4 应用接入 Prometheus 监控:基于 @loopback/metrics 的完整实战示例
LoopBack 4 应用接入 Prometheus 监控:基于 @loopback/metrics 的完整实战示例 导读 本文基于 LoopBack 4 官方
后端微服务CubeFS 集成 Prometheus 监控指标采集与配置实战指南
CubeFS 集成 Prometheus 监控指标采集与配置实战指南 CubeFS 内置了 Prometheus 监控指标采集能力,各核心模块(Master、M
存储分布式文件系统对象存储云原生
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考