2. OpenTelemetry 核心概念:Signal(Trace/Metric/Log)、Resource、Instrumentation Scope

在深入指标采集优化与数据库迁移任务调度之前,必须建立对 OpenTelemetry 数据模型的统一认知。OpenTelemetry 将可观测性数据抽象为三大核心 Signal(信号),并引入 Resource(资源) 和 Instrumentation Scope(检测范围) 两个元数据层,用于描述“谁产生的数据”以及“由哪个库产生的数据”。

2.1 三大 Signal:Trace、Metric、Log

Signal 是 OpenTelemetry 中可观测性数据的顶级分类。每个 Signal 都有独立的数据模型和语义,但在实际系统中三者通过 Context 传播 和 Resource 关联 实现关联分析。

Signal 核心用途 数据粒度 典型场景(数据库迁移)
Trace(链路) 记录请求在分布式系统中的完整路径与耗时 Span(跨度) 追踪一次迁移任务从调度器 → 数据导出 → 数据导入 → 校验的完整调用链
Metric(指标) 聚合统计系统运行状态,如计数、速率、直方图 DataPoint(数据点) 采集迁移吞吐量(行/秒)、连接池使用率、任务队列积压数
Log(日志) 记录离散的事件消息,包含结构化属性 LogRecord(日志记录) 记录迁移任务开始/结束、异常堆栈、数据校验不一致详情
实践要点: 在数据库迁移场景中,Trace 用于定位慢操作(如某张表的全量导出耗时异常),Metric 用于实时监控整体进度和资源水位,Log 用于事后审计和异常排查。三者缺一不可。

2.2 Resource(资源)

Resource 描述产生可观测性数据的 实体,例如主机、容器、Kubernetes Pod、数据库实例或应用服务。Resource 是一组键值对(Attributes),会被附加到该实体产生的所有 Signal 上,实现跨 Signal 的关联查询。

常见的 Resource 属性包括:

  • service.name — 服务名称,如 migration-scheduler
  • service.instance.id — 服务实例唯一标识
  • host.name — 主机名
  • telemetry.sdk.language — SDK 语言,如 java
  • deployment.environment — 部署环境,如 production
关键设计: Resource 是 OpenTelemetry 数据模型的“根”。在数据库迁移任务中,建议将 源数据库实例 和 目标数据库实例 分别建模为独立的 Resource,以便在指标和链路中区分两端。

2.3 Instrumentation Scope(检测范围)

Instrumentation Scope 标识产生 Signal 的 检测库或检测模块。它通常对应一个具体的 instrumentation 包(如 io.opentelemetry.instrumentation.jdbc)或自定义检测代码。Scope 包含 name、version 和 schema_url 三个字段。

Scope 与 Resource 的区别:

维度 Resource Instrumentation Scope
描述对象 产生数据的实体(谁) 产生数据的检测库(用什么)
作用范围 全局,所有 Signal 共享 局部,仅该 Scope 产生的 Signal
典型值 service.name=order-service name=io.opentelemetry.jdbc
查询用途 按服务/主机/环境过滤 按检测库版本排查兼容性问题

2.4 数据模型层次关系

下图展示了 OpenTelemetry 数据模型的完整层次结构,以及 Signal、Resource、Scope 之间的包含关系:

OpenTelemetry 数据模型层次结构 OpenTelemetry 数据模型层次结构 Resource(资源) Instrumentation Scope(检测范围) Trace(链路) Span → Span → Span Metric(指标) Counter / Histogram / Gauge Log(日志) Structured LogRecord 说明: 1. 一个 Resource 可以包含多个 Instrumentation Scope。 2. 每个 Instrumentation Scope 可以产生任意数量的 Trace、Metric、Log。 3. 所有 Signal 都继承其所属 Resource 的 Attributes。 4. 在数据库迁移场景中,源库和目标库应配置不同的 Resource。 5. JDBC 检测库、自定义迁移检测代码应使用不同的 Instrumentation Scope。

2.5 数据库迁移场景中的 Signal 关联

在迁移任务调度中,三个 Signal 通过 Trace ID 和 Resource Attributes 实现关联。例如,一次“全量迁移”任务会产生如下数据:

  • Trace:一个 Root Span(任务调度)包含多个 Child Span(连接源库、读取表结构、导出数据、导入目标库、校验)。
  • Metric:在导出和导入阶段,每 10 秒记录一次 migration.rows.processed(Counter)和 migration.duration(Histogram),并附加 table_name、batch_id 等属性。
  • Log:当校验不一致时,输出一条 Error 级别的 LogRecord,包含 trace_id、span_id、不一致行主键和期望值/实际值。
常见误区: 不要将 Resource 和 Instrumentation Scope 混用。Resource 用于区分“哪个数据库实例”,Scope 用于区分“哪个检测库”。如果混淆,会导致在查询时无法准确过滤数据源或检测模块。

2.6 核心概念速查表

概念 是否必选 是否可自定义 在迁移调度中的典型值
Resource 是 是(推荐自定义) service.name=migration-scheduler, db.system=mysql
Instrumentation Scope 是(SDK 自动填充) 是(自定义检测时) name=custom-migration-instrumentation, version=1.0.0
Span(Trace) 按需 是 span.name=export_table, span.kind=client
Metric DataPoint 按需 是 metric.name=migration.rows.exported, value=15000
LogRecord 按需 是 severity=error, body=checksum mismatch

2.7 代码示例:在 Java 中创建 Resource 和 Scope

以下代码展示了如何在数据库迁移调度器中显式设置 Resource 和 Instrumentation Scope:

// 创建 Resource,标识当前服务
Resource resource = Resource.getDefault()
    .merge(Resource.create(Attributes.of(
        ResourceAttributes.SERVICE_NAME, "migration-scheduler",
        ResourceAttributes.SERVICE_VERSION, "2.1.0",
        ResourceAttributes.DEPLOYMENT_ENVIRONMENT, "production",
        ResourceAttributes.HOST_NAME, InetAddress.getLocalHost().getHostName()
    )));

// 创建 OpenTelemetry 实例
OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
    .setResource(resource)
    .build();

// 创建自定义 Instrumentation Scope
Meter meter = openTelemetry.getMeter("custom-migration-instrumentation", "1.0.0");
Tracer tracer = openTelemetry.getTracer("custom-migration-instrumentation", "1.0.0");
Logger logger = openTelemetry.getLogsBridge()
    .loggerBuilder("custom-migration-instrumentation")
    .setInstrumentationVersion("1.0.0")
    .build();
最佳实践: 在数据库迁移任务中,建议为 每个迁移任务实例 生成一个独立的 Trace,并在 Span 的 Attributes 中记录 task_id、source_database、target_database。这样可以在后续分析中快速定位特定任务的性能瓶颈。