如何在Node.js中使用OpenTelemetry日志并对接Azure Monitor
Node.js 应用基于 OpenTelemetry 发送日志到 Azure Monitor 的最佳实践
一、关于 OpenTelemetry 日志 API/SDK 的定位
你提到的 JavaScript 日志 API/SDK 同时服务于两类使用者:
- 库作者:可直接使用 LogRecords API 构建 Appenders(即文档所说的插件/扩展),用来桥接 winston、pino 这类现有日志库与 OpenTelemetry 日志数据模型,让日志输出自动带上链路上下文。
- 应用开发者:应优先使用 Events API(它是 LogRecords API 的封装)直接生成业务事件日志,而非直接调用 LogRecords API——OpenTelemetry 本身并非要替代功能完备的专业日志库。
二、两种日志采集方式的说明与代码示例
OpenTelemetry 针对可控/不可控日志场景提供了两种采集方案,以下是对应的 Node.js 实现示例:
方式1:通过文件/标准输出中转(适合不可控日志)
这种方式先将日志输出到文件或 stdout,再由 OpenTelemetry Collector 读取并转发至 Azure Monitor,适合无法直接修改日志输出逻辑的应用或第三方依赖日志。
实现步骤:
- 配置日志库(以 winston 为例)输出结构化日志到文件:
const winston = require('winston'); const logger = winston.createLogger({ level: 'info', format: winston.format.json(), // 输出JSON格式,方便Collector解析 transports: [ new winston.transports.File({ filename: 'app.log' }) ] }); // 业务日志输出示例 logger.info('用户登录成功', { userId: '123', traceId: process.env.TRACE_ID });
- 配置 OpenTelemetry Collector(创建
config.yaml),读取日志文件并导出到 Azure Monitor:
receivers: filelog: include: [./app.log] start_at: beginning exporters: azuremonitor: connection_string: "YOUR_AZURE_MONITOR_CONNECTION_STRING" service: pipelines: logs: receivers: [filelog] exporters: [azuremonitor]
方式2:直接发送到 Collector(适合可控日志,推荐)
这种方式通过日志库的 Appender(插件/扩展),直接将日志转换为 OpenTelemetry 格式后发送到 Collector 或 Azure Monitor。这里的插件/扩展就是前文提到的 Appenders,它们负责将现有日志库的日志映射到 OpenTelemetry 的 LogRecords 模型,并自动带上链路追踪上下文。
以 winston + OpenTelemetry 为例的实现:
- 安装依赖:
npm install @opentelemetry/sdk-node @opentelemetry/exporter-logs-otlp-grpc @opentelemetry/instrumentation-winston winston
- 初始化 OpenTelemetry 并配置日志导出:
const { NodeSDK } = require('@opentelemetry/sdk-node'); const { WinstonInstrumentation } = require('@opentelemetry/instrumentation-winston'); const { OTLPGrpcExporter } = require('@opentelemetry/exporter-logs-otlp-grpc'); const { LoggerProvider, BatchLogRecordProcessor } = require('@opentelemetry/sdk-logs'); const winston = require('winston'); // 初始化日志导出器 const loggerProvider = new LoggerProvider(); const logExporter = new OTLPGrpcExporter({ url: 'http://localhost:4317/v1/logs', // 可替换为Azure Monitor的OTLP端点 }); loggerProvider.addLogRecordProcessor(new BatchLogRecordProcessor(logExporter)); // 初始化Node SDK,集成winston instrumentation const sdk = new NodeSDK({ loggerProvider, instrumentations: [ new WinstonInstrumentation({ logHook: (span, record) => { // 自动注入链路上下文到日志 record.traceId = span.spanContext().traceId; record.spanId = span.spanContext().spanId; } }) ] }); // 启动SDK sdk.start().then(() => console.log('OpenTelemetry SDK 启动成功')); // 配置winston logger const logger = winston.createLogger({ level: 'info', format: winston.format.json(), transports: [new winston.transports.Console()] }); // 业务代码中使用winston记录日志,自动携带链路上下文 logger.info('创建订单', { orderId: '456', userId: '123' });
如果要直接导出到 Azure Monitor,可替换为专属导出器:
const { AzureMonitorLogExporter } = require('@opentelemetry/exporter-azure-monitor'); const logExporter = new AzureMonitorLogExporter({ connectionString: "YOUR_AZURE_MONITOR_CONNECTION_STRING" });
三、总结
- 应用开发者优先选择「现有日志库 + OpenTelemetry 对应 instrumentation(Appender)」的方案,或直接调用 Events API 生成事件日志。
- 不可控日志建议用文件/stdout中转,由 Collector 统一采集。
- 直接发送到 Collector 的方式能更好地保留链路上下文,是可控日志场景的推荐方案。
内容的提问来源于stack exchange,提问作者bunny
相关产品推荐
相关产品推荐

