大家好!今天,我们将探讨如何将我们开发的应用程序中收集到的海量数据(跟踪、指标、日志)发送到我们想要的分析系统,包括其整个旅程和核心方法。🧐
许多人专注于“如何创建”数据,但如果不知道“如何发送”,数据就会被困在应用程序内部。理解从数据生成到最终目的地的整个流程至关重要!

🗺️ 数据的漫长旅程:它从何而来,又将去往何方?
应用程序中生成的遥测数据到达分析工具的旅程大致可分为4个阶段。
- 仪表化 (Instrumentation) 💻: 这是开发人员在代码中使用特定库(API Package)生成诸如“此操作耗时50毫秒”、“此处开始DB调用”等数据的阶段。
- 标准化 (Standardization) 🏷️: 在此阶段,为生成的数据附加人人都能理解的标准化标签(Semantic Conventions),例如 http.method = “GET”。这是统一数据“含义”的过程。
- 处理 (Processing) ⚙️: 收集到的数据会经过采样或过滤等中间处理。
- 导出 (Exporting) 🚀: 最后,这是将所有这些数据发送到Jaeger、Prometheus、Datadog等最终目的地的阶段。这是今天的主角!
理解这个整体图景比单独了解每个部分要重要得多。那么,我们首先来明确一下每个阶段的主要参与者API和Semantic Conventions与“导出”有何不同。
🤔 等等,API和Semantic Conventions不是负责发送数据的吗?
简单来说,不是!它们在“创建”和“描述”数据方面扮演着重要角色,但与向外部“传输”数据的功能相去甚远。
API Package: “创建”数据的架构师 🏗️
API包是我们代码中“创建”遥测数据的工具,例如启动跟踪数据(Span)和传播上下文。它提供了开发人员通过代码直接进行仪表化的接口。
主要作用:
- 启动和结束新的Span
- 向Span添加事件或属性(Attribute)
- 在服务之间传播上下文
也就是说,它负责数据“生产”的第一个阶段。但是,它完全不涉及如何将这些数据配置发送到特定系统。
Semantic Conventions: 为数据“贴标签”的图书管理员 🏷️
语义约定是标准化数据“内容”的约定。例如,如果一个开发人员将HTTP方法记录为http_method,而另一个开发人员记录为http.req.method,那么整合和分析数据将非常困难,对吗?
语义约定定义了数据字段的标准名称,如http.method、db.system、rpc.service,确保无论数据是从哪种语言或框架收集的,都具有一致的含义。
主要作用:
- 定义跟踪、指标、日志数据的标准命名规则
- 确保数据的一致性和互操作性
因此,它们只标准化数据的内容,而不决定将这些数据“导出”到哪里。
🚀 真正的主角登场:Exporter Package!
那么,收集到的数据到底是谁导出的呢?正是Exporter承担了这一角色!
Exporter是一个插件,它将OpenTelemetry SDK收集和处理的数据转换为特定后端(分析系统)可以理解的格式,然后进行传输。
存在多种类型的Exporter,可以根据目的进行选择。
- Console Exporter: 将数据输出到终端控制台。对于开发和调试非常有用。
- OTLP Exporter: 使用OpenTelemetry的标准协议(OTLP)传输数据。它不依赖于特定供应商,可以灵活地与所有支持OpenTelemetry的后端集成。
- Vendor-specific Exporter: 针对Jaeger、Prometheus、Zipkin等特定分析工具的专有格式发送数据的Exporter。
🛠️ 实战示例:通过代码配置Exporter并验证数据
光说不练可能不太直观,对吧?让我们在Node.js环境中配置Console Exporter,直接通过代码查看Span数据是如何生成并“输出”到外部的。
1. 代码配置 (Node.js)
这是使用ConsoleSpanExporter配置TracerProvider的代码。此代码指示将所有生成的Span信息输出到控制台。
// 导入所需模块
const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');
const { ConsoleSpanExporter, SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-base');
const { registerInstrumentations } = require('@opentelemetry/instrumentation');
const { HttpInstrumentation } = require('@opentelemetry/instrumentation-http');
// 1. Exporter配置:创建ConsoleSpanExporter,将所有Span输出到控制台。
const consoleExporter = new ConsoleSpanExporter();
// 2. Provider配置:这是创建和管理Tracer的主体。
const provider = new NodeTracerProvider();
// 3. 连接Provider和Exporter:通过SimpleSpanProcessor设置,使Span在每次结束时立即发送到consoleExporter。
provider.addSpanProcessor(new SimpleSpanProcessor(consoleExporter));
// 4. 注册Provider:将此Provider全局注册,供OpenTelemetry API使用。
provider.register();
// 自动仪表化设置(例如:HTTP请求)
registerInstrumentations({
instrumentations: [new HttpInstrumentation()],
});
console.log("✅ OpenTelemetry with ConsoleExporter is running...");
// 运行一个简单的HTTP服务器进行测试
const http = require('http');
http.createServer((req, res) => {
res.end('Hello, World!');
}).listen(8080);
2. 原始数据确认 (控制台输出)
运行上述代码并使用 curl
{
"traceId": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
"parentId": undefined,
"name": "HTTP GET",
"id": "1a2b3c4d5e6f7a8b",
"kind": 1,
"timestamp": 1762021445123456,
"duration": 15678,
"attributes": {
"http.method": "GET",
"http.target": "/",
"http.status_code": 200,
"net.peer.ip": "::1"
},
"status": {
"code": 0
},
"events": []
}
如您所见,根据http.method等语义约定命名的S数据,通过Exporter以整洁的JSON格式输出。如果想将数据发送到Jaeger,只需将ConsoleSpanExporter替换为JaegerExporter即可。
✨ 总结
在构建数据可观测性(Observability)管道时,理解数据的整体流程至关重要。
- API“生成”数据,
- Semantic Conventions赋予数据一致的“含义”,
- Exporter最终将这些数据“传输”到所需的目的地。
现在,您是否清楚地理解了每个组件的作用以及它们如何协调工作?选择适合您系统的Exporter,将分散的数据汇集到一处,从而获得强大的洞察力吧!
发表回复