在使用 OpenTelemetry 监控应用程序时,最基础的一步是进行 "OTel 数据埋点"。所谓的数据埋点,指的是为应用程序设置一些信号(如追踪、日志、指标等),这样你就可以对它的行为进行监控和分析。通过这些信号,你可以观察应用程序的运行状态和性能表现。
数据埋点概览
获取被监控的可观测数据的重要前提是正确的数据埋点,本文将介绍 OpenTelemetry 数据埋点的两种方式。想要了解 OpenTelemetry 的各个组成部分以及它们之间如何协同工作,请参考这篇文章《OpenTelemetry 新手入门》。
OpenTelemetry 的数据收集和跟踪功能(即 "检测" 或 "仪表化")是通过 OpenTelemetry API 来完成的。而 OpenTelemetry NodeJS SDK 实现了这个 API,提供了在 Node.js 应用中使用 OpenTelemetry 功能的方式。
这些组件可以无缝嵌入代码中,并生成所需的信号,以帮助用户全面掌握服务的运行状态。
OpenTelemetry 的设计注重模块化和灵活性,遵循单一职责原则。尽管涉及的术语较多,但主要的核心组件包括以下几个:
- 通过
Meter
或Tracer
生成数据; - 使用
Reader
或Processor
对数据进行采样、过滤和转换; - 通过
Exporter
或Collector
将 OTLP 数据打包并传输到用户选择的与 OpenTelemetry 兼容的后端。
这个概述能帮助用户理解如何为应用程序进行埋点(即设置监控和收集数据的信号)。通过了解数据在不同组件之间是如何流动的,就能更好地为自己的应用程序进行仪表化设置,有效地监控和分析应用程序的性能和运行状态。
OpenTelemetry 可观测数据流向
OpenTelemetry 的设计优势在于允许用户根据 OTel API 的规范,自定义数据处理管道的各个部分。默认的实现方式能够以一致的格式生成指标和跨度(spans),并将这些数据包装成 OpenTelemetry 协议(OTLP)的格式,以便于 OTLP 后端系统进行接收和处理。
下图展示了数据如何在各组件间传输:
这些标准操作流程为可观察性工具提供了标准的指导框架,使得用户能够选择符合该标准的多种工具。更多详细信息,请参阅 OpenTelemetry 规范。
在深入了解 OTel API 的作用及数据流向后,接下来我们来看看如何实际为应用程序进行埋点。埋点主要分为两类:自动植入和手动植入,下节将讨论它们之间的区别及各自适用的场景。
自动植入埋点
自动植入是使用 OpenTelemetry 的最简单方式。该过程通过接入应用程序和服务的常见接口边缘,自动捕获一些最常见的协议操作信号。只需导入一个库并实例化一个单例,或者在某些框架和语言中,仅需安装 SDK 并导出一些环境变量即可。
以下是自动植入可以捕获的常见指标示例:
HTTP 请求:
- 请求持续时间
- 响应状态码
- URL 路径
- HTTP 方法
数据库查询:
- 查询执行时间
- SQL 语句(已清理)
- 数据库类型(如 MySQL、PostgreSQL)
消息系统:
- 消息发布/消费操作
- 队列名称
- 消息大小
框架特定信号:
- 针对 Web 框架(如 Express.js、Flask):路由处理、 中间件执行
- 针对 ORM(如 Sequelize、SQLAlchemy):模型操作(创建、读取、更新、删除)
运行时指标:
- CPU 使用率
- 内存分配
- 垃圾回收统计
为应用进行自动植入非常简单,以下是一个集成了 OpenTelemetry NodeJS SDK 的 Express 应用示例:
const express = require('express');
const { UserService } = require('./services/userService')
// ---------------------------------------------------
// ---------------------------------------------------
// ---------------------------------------------------
// Import the OpenTelemetry SDK
const { NodeSDK } = require('@opentelemetry/sdk-node');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
// Initialize the OpenTelemetry SDK
const sdk = new NodeSDK({
traceExporter: new OTLPTraceExporter(),
instrumentations: [getNodeAutoInstrumentations()]
// sets up basic defaults for express http collection and app resource consumption
});
// Start the SDK
sdk.start();
// That's all the configuration needed to start collecting metrics
// ---------------------------------------------------
// ---------------------------------------------------
// ---------------------------------------------------
// Create and set up your Express app as usual
const app = express();
// Your routes and middleware here
app.get('/', (req, res) => {
res.send('Hello, OpenTelemetry!');
});
app.listen(...);
通过自动植入埋点收集信号,用户可以在代码改动极少的条件下获取大量可观察性数据,帮助快速启动 OpenTelemetry。虽然自动埋点已经可以提供非常高的价值,但在某些情况下,应用程序所有者可能需要监听应用程序中发生的更多自定义信号。开发者可以通过手动植入实现对采集信号的精细控制。
手动植入埋点
手动植入的核心配置在于 provider
,它作为用于创建输出信号对象的生成器。在这些生成器中,用户可以配置如下对象:
resource
:标识生成遥测数据的实体。通常包括服务名称、主机信息、容器或 Pod 标识符、云提供商详细信息或描述遥测来源的其他元数据,resource
提供了数据来源的上下文信息。meter / tracer
:(如ObservableGauge
):实际捕获指标和 Trace 的工具。这些对象将用于生成遥测数据。reader
:(如PeriodicExportingMetricReader
):可以用于每n
秒导出一次指标。sampler
: (如TraceIdRatioBasedSampler
):可用于捕获r
% 的请求。exporter
:(如OTLPTraceExporter
):用于将数据发送到 OTLP 兼容后端,如 GreptimeCloud。
以下示例展示了如何通过手动植入从 Tesla API 收集电池电量数据,并将指标发送到 GreptimeCloud 托管的 OTLP 后端:
const { MeterProvider } = require('@opentelemetry/sdk-metrics');
const { Resource } = require('@opentelemetry/resources');
const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');
const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');
const { SimpleSpanProcessor, BatchSpanProcessor, ConsoleSpanExporter } = require('@opentelemetry/sdk-trace-base');
const { trace, metrics, context } = require('@opentelemetry/api');
const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-http');
const { PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics');
const teslajs = require('teslajs');
const options = {
authToken: 'your-access-token',
vehicleID: 'your-vehicle-id'
};
// Configure the resource naming the given service
const resource = new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: 'tesla-monitoring-app',
});
// Configure the exporter to be sent to Greptime cloud
const otlpExporter = new OTLPMetricExporter({
url: 'https://6qr5e68t5wpn.us-west-2.aws.greptime.cloud/v1/otlp/v1/metrics',
headers: {
'Authorization': 'Basic WxN5prHHwx1ATXMvduBlgy4K:xxxxxxx',
'X-Greptime-DB-Name': 'my-greptime-cloud-instance@tesla-monitoring',
},
});
// Set this MeterProvider to be global to the app being instrumented.
const meterProvider = new MeterProvider({ resource });
opentelemetry.metrics.setGlobalMeterProvider(meterProvider);
const metricReader = new PeriodicExportingMetricReader({
exporter: otlpExporter,
exportIntervalMillis: exportIntervalMillis: 5 * 60 * 1000
});
meterProvider.addMetricReader(metricReader);
// Create and register the tracer
const tracerProvider = new NodeTracerProvider();
// Configure span processor to send spans to simply log the results
tracerProvider.addSpanProcessor(new BatchSpanProcessor(new ConsoleSpanExporter()));
tracerProvider.register();
const tracer = trace.getTracer('example-basic-tracer-node');
const teslaMeter = metrics.getMeter(
"tesla-instrumentation",
'1.0',
);
const batteryGauge = teslaMeter.createObservableGauge("tesla.battery");
async function pollTeslaData() {
const span = tracer.startSpan('pollTeslaData');
const ctx = trace.setSpan(context.active(), span);
try {
await context.with(ctx, async () => {
const vehicleData = await teslajs.vehicleData()
vehicleData.charge_state.battery_level
batteryGauge.addCallback((result) => {
result.observe(batteryLevel);
});
});
} catch (error) {
span.recordException(error);
} finally {
span.end();
}
}
// Poll Tesla data every 5 minutes
setInterval(pollTeslaData, 5 * 60 * 1000);
该示例展示了 OpenTelemetry 在捕获可观察性数据方面的广泛支持,并展示了如何快速启动。
分析埋点所捕获的数据
通过 GreptimeDB 的 Grafana 插件,你可以在 Grafana 中直接可视化从 OpenTelemetry 捕获的所有数据。几分钟内即可完成帐户设置,利用 OpenTelemetry 为你的服务提供新的见解。
在后续文章中,我们将介绍如何将这些 OpenTelemetry 数据连接到 Grafana 进行可视化。如果你正在寻找性能卓越、可靠且开源的 OpenTelemetry 后端,欢迎了解 GreptimeDB。
关于 Greptime
Greptime 格睿科技专注于为可观测、物联网及车联网等领域提供实时、高效的数据存储和分析服务,帮助客户挖掘数据的深层价值。目前基于云原生的时序数据库 GreptimeDB 已经衍生出多款适合不同用户的解决方案,更多信息或 demo 展示请联系下方小助手(微信号:greptime)。
欢迎对开源感兴趣的朋友们参与贡献和讨论,从带有 good first issue 标签的 issue 开始你的开源之旅吧~期待在开源社群里遇见你!添加小助手微信即可加入“技术交流群”与志同道合的朋友们面对面交流哦~
Star us on GitHub Now: https://github.com/GreptimeTeam/greptimedb
Twitter: https://twitter.com/Greptime
Slack: https://greptime.com/slack