🚀 OpenTelemetry OTLP JSON: 追踪、指标、日志数据结构全面解析!

OpenTelemetry (OTel) 是一套标准化的工具、API 和 SDK,旨在确保分布式系统的可观测性 (Observability)。在此生成的所有宝贵数据(追踪、指标、日志)都通过名为 OTLP (OpenTelemetry Protocol) 的标准协议传输到收集服务器。而 OTLP 的传输格式之一正是 JSON 格式! 📜

今天,我们将深入探讨 OTel 收集的三种核心数据如何以 OTLP JSON 形式进行结构化,并通过示例剖析其 原始数据的深层结构。理解这一结构将大大增强您的数据分析和处理能力! 💪


🔍 理解 OTLP 数据的通用分层结构

OTLP 数据,无论是追踪、指标还是日志,都具有共同的 分层结构。这是为了清晰地分离和传递有关生成数据的环境信息。

数据类型 根对象 主要子字段 数据内容
— — — —
Trace (追踪) “resourceSpans” “scopeSpans”, “spans” 单个请求的执行流程
Metric (指标) “resourceMetrics” “scopeMetrics”, “metrics” 系统性能和数值数据
Log (日志) “resourceLogs” “scopeLogs”, “logRecords” 应用程序日志消息

🌳 1. Resource 块 (顶级标识符)

所有 OTLP 数据都包含一个 resource 块。它用于识别生成数据的实体(服务、主机等)。换句话说,这是告知我们数据来源的重要信息。

  • “attributes”: 包含环境信息,以键值对形式呈现,例如 服务名称 (service.name)、实例 ID (service.instance.id) 和云信息 (cloud.provider)。

📦 2. Scope/Instrumentation Library 块

resource 块下方紧接着是 scope 或 instrumentation library 块。

  • “scope”: 指明用于收集此数据的 库 或 版本。例如:io.opentelemetry.instrumentation.http, 版本 1.27.0。

📊 1. 追踪数据结构全面解析 (OTLP Trace JSON)

追踪数据跟踪单个请求在系统中经过的所有步骤。核心元素是 Span。

{
  "resourceSpans": [
    {
      "resource": {
        "attributes": [
          { "key": "service.name", "value": { "stringValue": "checkout-service" } },
          { "key": "service.instance.id", "value": { "stringValue": "627cc493-f310-47de-96bd-71410b7dec09" } },
          { "key": "cloud.provider", "value": { "stringValue": "aws" } },
          { "key": "host.id", "value": { "stringValue": "ip-172-31-12-55" } }
        ]
      },
      "scopeSpans": [
        {
          "scope": {
            "name": "io.opentelemetry.instrumentation.http",
            "version": "1.27.0"
          },
          "spans": [
            {
              "traceId": "4bf92f3577b34da6a3ce929d0e0e4736",
              "spanId": "00f067aa0ba902b7",
              "name": "HTTP POST /checkout",
              "kind": "SPAN_KIND_SERVER",
              "startTimeUnixNano": "1729123548123456789",
              "endTimeUnixNano": "1729123549223456789",
              "attributes": [
                { "key": "http.method", "value": { "stringValue": "POST" } },
                { "key": "http.status_code", "value": { "intValue": 200 } },
                { "key": "net.peer.ip", "value": { "stringValue": "10.10.1.12" } },
                { "key": "user.id", "value": { "stringValue": "abcd-123" } }
              ],
              "events": [
                {
                  "timeUnixNano": "1729123548156789000",
                  "name": "db.query.start",
                  "attributes": [
                    { "key": "db.statement", "value": { "stringValue": "SELECT * FROM orders WHERE id=42" } }
                  ]
                }
              ],
              "links": [
                {
                  "traceId": "4bf92f3577b34da6a3ce929d0e0e4736",
                  "spanId": "2233445566778899",
                  "attributes": [
                    { "key": "linked.operation", "value": { "stringValue": "payment-processing" } }
                  ]
                }
              ],
              "status": { "code": "STATUS_CODE_OK", "message": "completed successfully" }
            }
          ]
        }
      ]
    }
  ]
}

✨ 主要字段详细解读

字段 说明 示例值
— — —
“traceId” 识别整个事务的唯一 ID。 4bf92f3577b34da6a3ce929d0e0e4736
“spanId” 识别当前操作步骤的唯一 ID。 00f067aa0ba902b7
“name” Span 所代表的操作名称。 HTTP POST /checkout
“kind” Span 的类型(服务器、客户端、内部等)。 SPAN_KIND_SERVER
“startTimeUnixNano”, “endTimeUnixNano” 操作的开始和结束时间(纳秒)。 ⏱️ 1729123548…
“attributes” 与 Span 相关的额外详细信息(HTTP 方法、状态码、用户 ID 等)。 http.method: POST
“events” Span 执行期间特定时间点发生的事件记录(日志消息、数据库查询开始等)。 name: db.query.start
“links” 将此 Span 与其他追踪/Span 连接起来的信息(对分布式追踪很有用)。 🔗 linked.operation: payment-processing
“status” Span 的执行结果(成功/错误代码和消息)。 code: STATUS_CODE_OK

> 示例亮点:显示 checkout-service 处理 HTTP POST 请求 (traceId: 4bf92f…) 期间发生了数据库查询事件 (db.query.start),并最终成功 (STATUS_CODE_OK)。


📈 2. 指标数据结构全面解析 (OTLP Metrics JSON)

指标数据以数值形式表示系统性能或状态随时间的变化。它以各种形式存在,如 Gauge(瞬时值)、Sum(总和)和 Histogram(直方图)。

{
  "resourceMetrics": [
    {
      "resource": {
        "attributes": [
          { "key": "service.name", "value": { "stringValue": "checkout-service" } },
          { "key": "service.version", "value": { "stringValue": "1.5.2" } },
          { "key": "host.name", "value": { "stringValue": "ip-172-31-12-55" } }
        ]
      },
      "scopeMetrics": [
        {
          "scope": {
            "name": "io.opentelemetry.runtime",
            "version": "1.27.0"
          },
          "metrics": [
            {
              "name": "request_duration_seconds",
              "description": "HTTP request duration",
              "unit": "s",
              "sum": {
                "dataPoints": [
                  {
                    "attributes": [
                      { "key": "http.method", "value": { "stringValue": "POST" } },
                      { "key": "http.status_code", "value": { "intValue": 200 } }
                    ],
                    "startTimeUnixNano": "1729123548123456000",
                    "timeUnixNano": "1729123549223466000",
                    "value": 0.154,
                    "flags": 1
                  }
                ],
                "aggregationTemporality": "AGGREGATION_TEMPORALITY_DELTA",
                "isMonotonic": false
              }
            },
            {
              "name": "system.cpu.utilization",
              "description": "CPU usage percentage",
              "unit": "%",
              "gauge": {
                "dataPoints": [
                  {
                    "attributes": [
                      { "key": "host.id", "value": { "stringValue": "ip-172-31-12-55" } }
                    ],
                    "timeUnixNano": "1729123549123459999",
                    "value": 73.4
                  }
                ]
              }
            }
          ]
        }
      ]
    }
  ]
}

✨ 主要字段详细解读

字段 说明 示例值
— — —
“name”, “description”, “unit” 指标的名称、描述和测量单位。 request_duration_seconds, s
“sum”, “gauge” 指标的类型及其值所在的块。 sum (累计总和), gauge (瞬时值)
“dataPoints” 实际测量数据值的列表。 📝
dataPoints.”attributes” 该测量值特有的标签/过滤信息(例如:HTTP 方法、状态码)。 http.status_code: 200
dataPoints.”value” 测量的实际数值。 0.154 (秒), 73.4 (%)
dataPoints.”timeUnixNano” 测量值收集的时间。 ⏰ 1729123549…
sum.”aggregationTemporality” 总和测量值的聚合方式(增量:与前一间隔的差值,累积:从开始的总和)。 AGGREGATION_TEMPORALITY_DELTA

> 示例亮点:显示请求处理时间 (request_duration_seconds) 以总和 (sum) 形式测量为 0.154 秒,系统 CPU 利用率 (system.cpu.utilization) 以瞬时值 (gauge) 形式测量为 73.4%。


📝 3. 日志数据结构全面解析 (OTLP Logs JSON)

日志数据是记录应用程序中发生的事件的基于文本的消息。OTel 通过将追踪信息与日志关联来提高其利用率。

{
  "resourceLogs": [
    {
      "resource": {
        "attributes": [
          { "key": "service.name", "value": { "stringValue": "checkout-service" } },
          { "key": "service.namespace", "value": { "stringValue": "web-shop" } },
          { "key": "host.id", "value": { "stringValue": "ip-172-31-12-55" } }
        ]
      },
      "scopeLogs": [
        {
          "scope": {
            "name": "io.opentelemetry.logger",
            "version": "1.27.0"
          },
          "logRecords": [
            {
              "timeUnixNano": "1729123548123456789",
              "observedTimeUnixNano": "1729123548125456789",
              "severityText": "INFO",
              "severityNumber": 9,
              "body": { "stringValue": "Order ID 42 successfully processed" },
              "attributes": [
                { "key": "order.id", "value": { "intValue": 42 } },
                { "key": "user.id", "value": { "stringValue": "abcd-123" } },
                { "key": "event.name", "value": { "stringValue": "order_completed" } }
              ],
              "traceId": "4bf92f3577b34da6a3ce929d0e0e4736",
              "spanId": "00f067aa0ba902b7",
              "flags": 1
            },
            {
              "timeUnixNano": "1729123549223456000",
              "severityText": "ERROR",
              "severityNumber": 17,
              "body": { "stringValue": "Payment gateway timeout error" },
              "attributes": [
                { "key": "payment.processor", "value": { "stringValue": "stripe" } },
                { "key": "error.code", "value": { "intValue": 504 } }
              ],
              "traceId": "7aa111223344556677889900aabbccdd",
              "spanId": "11aabbccddeeff00",
              "flags": 1
            }
          ]
        }
      ]
    }
  ]
}

✨ 主要字段详细解读

字段 说明 示例值
— — —
“timeUnixNano”, “observedTimeUnixNano” 日志生成时间以及收集器观察到的时间。 1729123548…
“severityText”, “severityNumber” 日志的严重性级别(文本和数值)。 INFO (9), ERROR (17)
“body” 实际日志消息内容。 Order ID 42 successfully processed
“attributes” 与日志消息相关的额外信息。 order.id: 42, user.id: abcd-123
“traceId”, “spanId” 导致此日志的追踪和Span的 ID。(可观测性核心!) 🧩 4bf92f35…, 00f067aa…

> 示例亮点:订单成功日志 (severityText: INFO) 已链接到特定的追踪/Span ID。此外,支付网关错误日志 (severityText: ERROR) 也以严重性级别 17 记录。


💡 总结与结论

OpenTelemetry 的 OTLP JSON 格式将所有可观测数据捆绑成标准化的分层结构,从而实现高效的传输和处理。

  1. 资源 (Resource): 明确数据的来源(服务、主机信息)。
  2. 范围 (Scope): 指明用于数据收集的库信息。
  3. 数据: 包含实际内容,如追踪(Span)、指标(数据点)和日志(日志记录)。

得益于这种清晰详细的结构,使用 OTel 的系统即使在分布式环境中也能轻松收集、分析和可视化数据,从而全面掌握运营状况! 👍



Comments

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注