OTLP 日志记录到日志条目的映射

本文档介绍了当 OTLP 日志记录通过 Telemetry API 发送到 Google Cloud 时,Google Cloud Observability 如何从该记录中确定 LogEntry 的字段。

采用 OTLP 格式的日志数据的一般结构

使用 Telemetry API 将日志数据发送到 Google Cloud 时,这些数据必须采用与 OTLP 一致的格式。此数据的一般结构如下所示:

"resourceLogs": [
    {
      "resource": {
        "attributes": [...]
      },
      "scopeLogs": [
        {
          "logRecords": [...]
        }
      ]
    }
]

请注意,OpenTelemetry 会批量处理各个日志,每个日志都由 logRecord 结构表示,其中包含有关这些日志来源的信息,这些信息由 resource 结构表示。

当 Google Cloud Observability 收到 resourceLogs 对象时,它会为每个 logRecord 构建一个 LogEntry。与 OTLP 将来源信息与一系列单独的日志进行批处理不同,每个 LogEntry 结构都包含有关日志来源和日志本身的信息。

如需详细了解 OTLP 格式的日志数据结构,请参阅 OpenTelemetry logs.proto

如何设置 LogEntry 字段

Google Cloud Observability 使用以下规则来确定 LogEntry 字段的值:

LogEntry 字段
(名称来自 HTTP 参考)
系统如何确定字段值
logName

系统会使用以下优先级的 OpenTelemetry 日志记录属性列表来确定日志名称:

  • gcp.log_name
  • log_name
  • event_name

日志名称必须是可在网址中使用的字符,否则在提取期间会进行网址编码。

resource 系统会使用 resource 字段中设置的信息,或者推断资源。如需了解详情,请参阅 OTLP 属性到资源类型映射
timestamp

系统会使用以下按优先级排序的 OpenTelemetry 日志记录字段列表来确定 timestamp

  • 如果非零,则为 time_unix_nano
  • 如果非零,则为 observed_time_unix_nano
  • 日志条目的提取时间。

存储数据的日志存储桶的保留期限决定了可注入的最早时间戳。如需了解详情,请参阅 Cloud Logging 配额

receiveTimestamp 设置为 LogEntry 的提取时间。
severity 系统会将日志记录中的 OpenTelemetry 严重程度映射到 Cloud Logging 严重程度。如需了解详情,请参阅严重程度字段
httpRequest

系统会将日志记录中的 gcp.http_request 属性映射到等效的 LogEntry 字段。如需了解详情,请参阅 HttpRequest 字段

FIXME。还有其他字段会映射到此字段。

labels 系统会使用日志记录属性值设置此字段。 如需了解详情,请参阅标签字段
trace 系统会将此字段设置为日志记录的 traceId 字段中的值。该值必须是有效的 32 字符十六进制字符串,否则系统会拒绝该条目。
spanId 系统会将此字段设置为日志记录的 spanId 字段中的值。该值必须是有效的 16 字符十六进制字符串,否则系统会拒绝该条目。
traceSampled 未设置。
sourceLocation 系统会将此字段设置为日志记录的 Code 属性中的值。如需了解详情,请参阅 SourceLocation 字段
split 未设置。
apphub
apphubDestination
apphubSource
未设置。
otel 对于 OTLP 日志数据中没有 LogEntry 等效字段的字段,系统会转换数据类型,然后将转换后的数据添加到 otel 字段。如需了解详情,请参阅 Otel 字段
载荷 系统通过将日志记录的正文转换为适当的载荷类型来设置载荷。如需了解详情,请参阅载荷字段

HttpRequest 字段

Google Cloud Observability 会将适用于 HTTP 请求的 OTLP 属性映射到 LogEntry 字段。以下部分介绍了系统如何映射扁平属性和嵌套属性。

扁平属性

下表介绍了 Google Cloud Observability 如何将适用于 HTTP 请求的扁平属性映射到 LogEntry 字段。例如,将属性 http.request.method: "GET", 中的值设置为日志条目中 httpRequest.requestMethod 字段的值:

OpenTelemetry
LogRecord.attribute
键值对。
存储在以下
LogEntry字段中的值
(名称来自 HTTP 参考)
接受的类型
http.request.method httpRequest.requestMethod 字符串
url.full
http.url
httpRequest.requestUrl 字符串
http.request.body.size httpRequest.requestSize 字符串、整数
http.response.status_code httpRequest.status 字符串、整数
http.response.body.size httpRequest.responseSize 字符串、整数
user_agent.original
http.user_agent
httpRequest.userAgent 字符串
client.address remoteIp 字符串
server.address serverIp 字符串
referrer httpRequest.referer 字符串
latency httpRequest.latency 字符串、整数
cacheLookup httpRequest.cacheLookup 布尔值
cacheHit httpRequest.cacheHit bool
cacheValidatedWithOriginServer httpRequest.cacheValidatedWithOriginServer 布尔值
cacheFillBytes httpRequest.cacheFillBytes 字符串、整数
network.protocol.version
protocol
httpRequest.protocol 字符串

嵌套属性

本部分介绍了 Google Cloud Observability 如何将适用于 HTTP 请求的嵌套 OTLP 属性映射到 LogEntry 中的字段。以下示例展示了一条包含两个属性的日志记录,每个属性都包含至少一个其他属性:

log_record {
  attributes: {
    gcp.http_request {
      "requestMethod": "GET",
      "requestUrl": "some-URL",
    }
    http_request {
      "requestMethod": "GET",
    }
  }
}

在表格中,嵌套属性使用大括号表示。例如,gcp.http_request {requestMethod} 表示属性 gcp.http_request 包含属性 requestMethod。最内层属性的值会分配给日志条目字段的值:

OpenTelemetry
LogRecord.attribute
键值对。
存储在以下
LogEntry字段中的值
(名称来自 HTTP 参考)
接受的类型
gcp.http_request {requestMethod}
http_request {requestMethod}
httpRequest.requestMethod 字符串
gcp.http_request {requestUrl}
http_request {requestUrl}
httpRequest.requestUrl 字符串
gcp.http_request {requestSize}
http_request {requestSize}
httpRequest.requestSize 字符串、整数
gcp.http_request {status}
http_request {status}
httpRequest.status 字符串、整数
gcp.http_request {responseSize}
http_request {responseSize}
httpRequest.responseSize 字符串、整数
gcp.http_request {userAgent}
http_request {userAgent}
httpRequest.userAgent 字符串
gcp.http_request {remoteIp}
http_request {remoteIp}
httpRequest.remoteIp 字符串
gcp.http_request {serverIp}
http_request {serverIp}
httpRequest.serverIp 字符串
gcp.http_request {referer}
http_request {referrer}
httpRequest.referer 字符串
gcp.http_request {latency}
http_request {latency}
httpRequest.latency 字符串、整数
gcp.http_request {cacheLookup}
http_request {cacheLookup}
httpRequest.cacheLookup 布尔值
gcp.http_request {cacheHit}
http_request {cacheHit}
httpRequest.cacheHit bool
gcp.http_request {
cacheValidatedWithOriginServer}

http_request {
cacheValidatedWithOriginServer}
httpRequest.cacheValidatedWithOriginServer 布尔值
gcp.http_request {cacheFillBytes}
http_request {cacheFillBytes}
httpRequest.cacheFillBytes 字符串、整数
gcp.http_request {protocol}
http_request {protocol}
httpRequest.protocol 字符串

“标签”字段

为了确定要附加到日志条目的标签,系统会执行以下操作:

  1. 它会从 OTLP 日志记录中移除已映射到特定 LogEntry 字段的所有属性。

    例如,假设日志记录附加了以下属性:

    attributes: {
        "log_array_attr: ["value1", "value2"],
        "log_json_attr": {"json_key": "json_value"}
        "log-string-attr": "string",
        "code.file.path": "my-file.cc",
        "code.function.name: "my-func",
        "code.line.number": 123,
        "gcp.http_request": {
            "requestMethod": "GET",
            "requestUrl": "my-URL",
      },
    }
    

    移除映射到特定 LogEntry 字段的字段后,剩余的字段如下:

    attributes: {
        "log_array_attr: ["value1", "value2"],
        "log_json_attr": {"json_key": "json_value"}
        "log-string-attr": "string",
    }
    
  2. 如果属性包含数组或 JSON 元素,系统会将该值转换为字符串。

    例如,以下示例展示了 LogEntry 如何表示之前的属性:

    labels: {
        "log_array_attr": "[\"value1\",\"value2\"]",
        "log_json_attr": "{\"json_key\":\"json_value\"}",
        "log-string-attr": "string",
    }
    

    属性的最大嵌套深度为 5。任何嵌套更深的内容都会被截断。

Otel 字段

对于 OTLP 日志数据中没有 LogEntry 等效字段的字段,系统会转换数据类型,然后将转换后的数据添加到 otel 字段。例如,otel 字段存储来自 resourcescopeentity 字段的属性。

系统使用以下规则将 OpenTelemetry 数据类型转换为 protobuf Value 类型

OpenTelemetry 类型 protobuf 类型
string string
boolean bool
integer double
float double
Array ListValues
KeyValueList Struct

为避免出现双精度错误,请以字符串形式传递整数。

负载字段

OTLP logRecord.body 字段的数据类型决定了 LogEntry 载荷的结构:

  • string:系统将字符串复制到 LogEntry.textPayload 字段中。

  • Array:系统会创建一个包含数组元素的字符串,同时保留换行符。然后,将该字符串复制到 LogEntry.textPayload 字段中。

  • KeyValueList:系统会将这些键值对转换为 JSON,然后填充 LogEntry.jsonPayload 字段,但有以下限制:

    • 如果 OTLP 记录包含重复的属性键,系统会保留第一个键,并舍弃具有重复键的属性。
    • 如果 JSON 对的嵌套深度大于 5,系统会将内容截断为深度为 5。

严重程度字段

本部分介绍了 Google Cloud Observability 如何将 OpenTelemetry 严重程度字段映射到 Cloud Logging 严重程度级别。OpenTelemetry 定义了严重程度编号和严重程度文本。logs.proto 定义严重程度编号。

如果设置了 OpenTelemetry 严重程度编号,Google Cloud Observability 会根据该编号确定 Logging 严重程度。否则,它会使用严重程度文本。如果两者均未设置,则将日志记录严重程度设置为 DEFAULT

OpenTelemetry 严重程度编号
枚举(值)
OpenTelemetry 严重程度文本
(测试不区分大小写)
Cloud Logging 严重程度
枚举(值)
SEVERITY_NUMBER_UNSPECIFIED (0) 未设置“default”
DEFAULT (0)
SEVERITY_NUMBER_TRACE (1)
SEVERITY_NUMBER_TRACE2 (2)
SEVERITY_NUMBER_TRACE3 (3)
SEVERITY_NUMBER_TRACE4 (4)
“trace”
“trace2”
“trace3”
“trace4”
DEBUG (100)
SEVERITY_NUMBER_DEBUG (5)
SEVERITY_NUMBER_DEBUG2 (6)
SEVERITY_NUMBER_DEBUG3 (7)
SEVERITY_NUMBER_DEBUG4 (8)
“debug”
“debug2”
“debug3”
“debug4”
DEBUG (100)
SEVERITY_NUMBER_INFO (9)
SEVERITY_NUMBER_INFO2 (10)
“info”
“info2”
INFO (200)
SEVERITY_NUMBER_INFO3 (11)
SEVERITY_NUMBER_INFO4 (12)
“notice”
“info3”
“info4”
NOTICE (300)
SEVERITY_NUMBER_WARN (13)
SEVERITY_NUMBER_WARN2 (14)
SEVERITY_NUMBER_WARN3 (15)
SEVERITY_NUMBER_WARN4 (16)
“warning”
“warn”
“warn2”
“warn3”
“warn4”
WARNING (400)
SEVERITY_NUMBER_ERROR (17)
SEVERITY_NUMBER_ERROR2 (18)
SEVERITY_NUMBER_ERROR3 (19)
SEVERITY_NUMBER_ERROR4 (20)
“error”
“error2”
“error3”
“error4”
ERROR (500)
SEVERITY_NUMBER_FATAL (21)
SEVERITY_NUMBER_FATAL2 (22)
“严重”
“致命”
“致命 2”
CRITICAL (600)
SEVERITY_NUMBER_FATAL3 (23) “alert”
“fatal3”
ALERT (700)
SEVERITY_NUMBER_FATAL4 (24) “紧急”
“致命 4”
EMERGENCY (800)

SourceLocation 字段

Google Cloud Observability 会将以下 OTLP Code 直接映射到 LogEntry 字段。之所以可以进行这种映射,是因为这些 OpenTelemetry 属性在语义上与 Cloud Logging 概念相同。

OpenTelemetry
LogRecord.attribute
键值对。
存储在以下
LogEntry字段中的值
(名称来自 HTTP 参考)
接受的类型
code.file.path: Value sourceLocation.file 字符串
code.function.name: Value sourceLocation.function 字符串
code.function.number: Value sourceLocation.line 字符串、整数

限制

本部分介绍了限制。还介绍了 Google Cloud Observability 如何处理某些类型的数据。

限制

说明 备注
每个 OTLP 请求的日志数上限 8192 指 OTLP resourceLogs 结构中 logRecords 的最大数量。限制。
每个请求的大小上限 5 MiB 限制。
根据 OTLP 日志记录创建的 LogEntry
的最大大小
256 KiB Cloud Logging 会在必要时截断或舍弃 OTLP 日志记录中的数据。限制。
属性键的长度上限 512 B 将 OTLP 日志记录转换为 LogEntry 时,超大的标签键会被截断。限制。
属性值的长度上限 64 KiB 当 OTLP 日志记录转换为 LogEntry 时,标签值过大。限制。
属性嵌套的最大深度 5 当 OTLP 日志记录转换为 LogEntry 时,超出此限制的属性会被截断。
每分钟的日志提取字节数上限

以下区域的存储空间为 2.4 GB:asia-east1, asia-northeast1, asia-southeast1, asia-south1, europe-west1, europe-west2, europe-west3, europe-west4, us-central1, us-east4, us-west1

对于所有其他区域,为 300 MB。

配额。

行为

  • 如果同时设置了 OpenTelemetry 严重程度编号和严重程度文本,系统会使用严重程度编号来确定 Cloud Logging 严重程度级别。如果 OTLP 记录不包含严重程度信息,则 Cloud Logging 严重程度级别会设置为 DEFAULT

  • 如果 OTLP 记录包含重复的属性键,系统会保留第一个键,并舍弃具有重复键的属性。

  • 系统会将附加到日志记录的属性转换为字符串。如需查看相关示例,请参阅标签字段

  • 日志名称必须是可在网址中使用的名称,否则在提取期间会进行网址编码。 如需了解如何设置日志名称,请参阅如何设置 LogEntry 字段