ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

NocoBase 服务端 Telemetry 遥测开发指南:基于 OpenTelemetry 的指标采集与链路追踪

NocoBase 服务端 Telemetry 遥测开发指南:基于 OpenTelemetry 的指标采集与链路追踪 NocoBase 服务端 Telemetry 遥测开发指南基于 OpenTelemetry 的指标采集与链路追踪【免费下载链接】nocobaseNocoBase is an open-source AI no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobaseNocoBase 的遥测Telemetry模块基于 OpenTelemetry 封装为插件开发者提供了一套统一、可插拔的可观测性 API用于收集监控指标Metric和链路追踪Trace数据。本文将围绕 docs/docs/cn/plugin-development/server/telemetry.md 展开结合 packages/core/telemetry 的源码实现讲解如何在插件中完成指标插桩、链路插桩、插桩工具库注册以及如何对接采集器MetricReader / SpanProcessor帮助你为 NocoBase 服务端构建完整的可观测性方案。注意该功能目前为实验性功能API 与行为可能随版本演进调整。Telemetry 模块架构概览NocoBase 的遥测模块独立存在于 packages/core/telemetry/src/index.ts对外导出Telemetry、Metric、Trace三个核心类并透传 OpenTelemetry 生态的类型与工具如PeriodicExportingMetricReader、Meter。三者职责分明类职责对应 OpenTelemetry 概念Telemetry顶层入口持有trace与metric两个子模块负责插桩库注册与全局资源Resource构建Instrumentation、ResourceTrace管理NodeTracerProvider与SpanProcessor注册提供getTracer()Tracer、SpanProcessorMetric管理MeterProvider与MetricReader注册提供getMeter()Meter、MetricReader在 packages/core/server/src/application.ts#L1300-L1304 中Application构造时会创建Telemetry实例并自动注入appName应用名与version当前 NocoBase 版本号之后暴露为app.telemetry。也就是说在插件中可以通过app.telemetry直接访问metric与trace两个子模块。遥测模块的生命周期与Application紧密绑定application.ts#L617-L618、application.ts#L711-L715app.beforeLoad阶段telemetry.init()被调用注册所有插桩库构建 Service Resourceapp.beforeLoad之后若配置telemetry.enabled为真则调用telemetry.start()启动数据导出应用关闭时调用telemetry.shutdown()优雅停止所有 Processor 与 Reader。从源码结构看telemetry.tsinit()内部通过registerInstrumentations注册插桩库并用resourceFromAttributes构建包含service.name、service.version与app.name三个属性的 Resource随后依次初始化Trace与Metric。指标Metric插桩获取 Meter 并创建计数器指标插桩的第一步是从app.telemetry.metric获取Meter再通过Meter创建各类指标仪器Counter、Histogram、UpDownCounter 等const meter app.telemetry.metric.getMeter(); const counter meter.createCounter(event_counter, {}); counter.add(1);getMeter()的默认标识为nocobase-meter版本为当前 NocoBase 版本见 metric.tscreateCounter(event_counter, {})创建一个名为event_counter的单调递增计数器业务代码每次发生对应事件时调用counter.add(1)累加。Metric 的底层实现细节从 metric.ts 的源码可以看到几个关键行为默认 Reader 已内置Metric构造时自动注册了名为console的PeriodicExportingMetricReader其 exporter 为ConsoleMetricExporter并指定AggregationTemporality.DELTA增量聚合。也就是说不做任何配置时指标会周期性打印到控制台环境变量过滤指标start()时会读取TELEMETRY_METRICS环境变量逗号分隔的指标名列表通过 OpenTelemetry 的 Metric View 机制仅保留列表中出现的指标其余全部用AggregationType.DROP丢弃metric.ts#L75-L94。该机制可用于在生产环境控制指标上报的开销多 Reader 支持readerName既可以是单个字符串也可以是逗号分隔的多个名称start()时会逐个实例化并挂载到MeterProvidermetric.ts#L96-L114。指标数据采集导出到控制台采集器Reader决定指标最终流向何处。注册自定义 Reader 同样通过registerReader完成下面示例将指标导出到控制台import { Plugin } from nocobase/server; import { PeriodicExportingMetricReader, ConsoleMetricExporter, } from opentelemetry/sdk-metrics; class MetricReaderPlugin extends Plugin { afterAdd() { this.app.on(beforeLoad, (app) { app.telemetry.metric.registerReader( console, () new PeriodicExportingMetricReader({ exporter: new ConsoleMetricExporter(), }), ); }); } }要点说明registerReader(name, getReader)的第一个参数是 Reader 的唯一标识第二个参数是返回MetricReader实例的工厂函数见 metric.ts#L62-L64PeriodicExportingMetricReader会按固定时间间隔拉取指标并交给 exporter 导出ConsoleMetricExporter将数据以 JSON 形式打印到标准输出适合本地调试若要切换实际生效的 Reader可通过MetricOptions.readerName例如应用配置中的TELEMETRY_METRIC_READER环境变量指定start()时会按名称从注册表中取出对应的工厂并实例化。未找到对应名称时会被安全跳过continue。链路Trace插桩获取 Tracer 并创建 Span链路追踪用于记录一次请求或任务在分布式系统中的完整调用链。NocoBase 中通过app.telemetry.trace获取Tracer然后开启 Spanconst tracer app.telemetry.trace.getTracer(); tracer.startActiveSpan(); tracer.startSpan();getTracer()默认返回名为nocobase-trace的 Tracer见 trace.ts#L86-L91startActiveSpan()会创建 Span 并将其设为当前活动上下文需配合回调使用适合在一个函数/请求的作用域内追踪startSpan()则仅创建 Span不自动设置活动上下文适合手动管理 span 生命周期与父子关系。Trace 的底层实现细节从 trace.ts 源码可知默认 Processor 已内置Trace构造时自动注册名为console的BatchSpanProcessorexporter 为ConsoleSpanExporterSpan 会批量导出到控制台NodeTracerProvider 注册为全局start()中创建NodeTracerProvider并调用provider.register()trace.ts#L82-L83使整个 Node.js 进程包括未显式获取 Tracer 的第三方库都能接入同一链路上下文多 Processor 支持processorName支持逗号分隔的多个名称start()时逐个实例化并传入NodeTracerConfigtrace.ts#L58-L80。链路数据采集导出到控制台Span 的导出由SpanProcessor决定。注册自定义 Processor 的完整示例import { Plugin } from nocobase/server; import { BatchSpanProcessor, ConsoleSpanExporter, } from opentelemetry/sdk-trace-base; class TraceSpanProcessorPlugin extends Plugin { afterAdd() { this.app.on(beforeLoad, (app) { app.telemetry.trace.registerProcessor( console, () new BatchSpanProcessor(new ConsoleSpanExporter()), ); }); } }要点说明registerProcessor(name, getProcessor)注册后可通过TraceOptions.processorName或环境变量TELEMETRY_TRACE_PROCESSOR指定启用哪个 Processor见 trace.ts#L45-L51BatchSpanProcessor会将 Span 缓存后批量发送避免每条 Span 都产生一次 I/OConsoleSpanExporter则把 Span 打印到控制台便于开发期观察链路结构实际生产环境中可在此处替换为 OTLP、Jaeger 等 exporter并分别通过registerReader/registerProcessor以「注册 名称启用」的方式接入。插桩工具库Instrumentation注册OpenTelemetry 生态提供了大量自动化插桩库如 HTTP、数据库客户端、消息队列等NocoBase 通过app.telemetry.addInstrumentation()批量注册import { Plugin } from nocobase/server; import { getNodeAutoInstrumentations } from opentelemetry/auto-instrumentations-node; class InstrumentationPlugin extends Plugin { afterAdd() { this.app.on(beforeLoad, (app) { app.telemetry.addInstrumentation(getNodeAutoInstrumentations()); }); } }getNodeAutoInstrumentations()会返回一组 Node.js 常用插桩库的集合一次性覆盖常见 I/O 场景addInstrumentation(...)在内部将这些插桩库推入Telemetry.instrumentations数组见 telemetry.ts#L70-L72并在init()时通过registerInstrumentations统一生效。插桩库的适用边界重要限制:::warning 注意NocoBase 中遥测模块的初始化位置为app.beforeLoad因此并不是所有插桩库都适用于 NocoBase。比如 instrumentation-koa 需要在Koa实例化之前引入而 NocoBase 的Application虽然基于Koa但遥测模块是在Application实例化之后才初始化的所以无法使用。:::这一限制的根源在于遥测模块的生命周期设计Telemetry实例在Application构造函数中创建application.ts#L1300-L1304而插桩库的注册发生在beforeLoad钩子中。凡是在「模块加载期」就必须对目标库进行 monkey-patch 的插桩典型的如 Koa、Express 等 Web 框架插桩都因错过实例化时机而无法生效。因此建议优先选择在运行时按调用点进行拦截的插桩库并始终以目标插桩库的文档说明其初始化时机要求为准。应用级配置与环境变量在 packages/core/app/src/config/telemetry.ts 中NocoBase 通过环境变量提供了一套开箱即用的遥测配置环境变量作用默认值 / 示例TELEMETRY_ENABLED是否启用遥测数据导出值为on时启用未设置时不启动导出TELEMETRY_SERVICE_NAME遥测服务名对应 Resource 的service.namenocobaseTELEMETRY_METRIC_READER指定启用的MetricReader名称对应metric.readerNameconsoleTELEMETRY_TRACE_PROCESSOR指定启用的SpanProcessor名称对应trace.processorNameconsoleTELEMETRY_METRICS逗号分隔的指标名白名单仅这些指标会被收集空收集全部对应的AppTelemetryOptions结构见 application.ts 中telemetry配置类型export interface TelemetryOptions { serviceName?: string; // 服务名默认 nocobase appName?: string; // 应用名由 Application 自动注入 version?: string; // 版本号由 Application 自动注入 trace?: TraceOptions; // tracerName / version / processorName metric?: MetricOptions; // meterName / version / readerName }部署时可据此在启动脚本中组合使用例如TELEMETRY_ENABLEDon \ TELEMETRY_SERVICE_NAMEnocobase-prod \ TELEMETRY_METRIC_READERconsole \ TELEMETRY_TRACE_PROCESSORconsole \ TELEMETRY_METRICSevent_counter,http_request_duration \ yarn start插件开发中的推荐实践综合文档与源码在 NocoBase 插件中接入遥测的推荐模式如下在afterAdd()中挂载beforeLoad监听因为遥测模块在app.beforeLoad阶段初始化插桩与采集器的注册都应放在this.app.on(beforeLoad, ...)回调中执行确保注册先于init()注册命名工厂而非实例registerReader/registerProcessor的第二个参数是工厂函数每次启动时调用这样同一个名称可以按启动配置动态创建不同实例用环境变量控制采集目标通过TELEMETRY_METRIC_READER、TELEMETRY_TRACE_PROCESSOR、TELEMETRY_METRICS实现「同一套代码、不同环境不同采集策略」避免在代码中写死导出目标与 Logger 配合遥测负责结构性数据指标、链路日志负责事件详情二者结合才能构成完整的可观测性方案可参考 Logger 日志 与 服务端开发概述善用事件机制beforeLoad属于 NocoBase 应用生命周期事件更多事件用法见 Event 事件若需要在中间件中追踪请求链路可参考 Middleware 中间件 并在中间件内通过app.telemetry.trace开启 Span。相关文档导航Logger 日志 — 日志与遥测配合使用完善可观测性方案Plugin 插件 — 在插件中注册遥测插桩和采集器服务端开发概述 — 遥测模块在服务端架构中的位置Event 事件 — 通过事件机制在beforeLoad中初始化遥测Middleware 中间件 — 在中间件中结合遥测追踪请求链路Telemetry API 参考 —Telemetry类方法完整签名与默认值Trace API 参考 —Trace类方法完整签名与默认值Metric API 参考 —Metric类方法完整签名与默认值核心源码packages/core/telemetry/src/telemetry.ts、packages/core/telemetry/src/trace.ts、packages/core/telemetry/src/metric.ts【免费下载链接】nocobaseNocoBase is an open-source AI no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表