This document describes how Google Cloud Observability determines the fields of a LogEntry
from the OTLP log record, when that record is sent
to Google Cloud by using the Telemetry API.
General structure of OTLP-formatted log data
When log data is sent to Google Cloud by using the Telemetry API, this data must be in a format that is consistent with OTLP. The general structure for this data is as shown:
"resourceLogs": [
{
"resource": {
"attributes": [...]
},
"scopeLogs": [
{
"logRecords": [...]
}
]
}
]
Notice that OpenTelemetry batches individual logs, each of which is represented by
a logRecord
structure, with information about the source of those logs,
which is represented by the resource
structure.
When Google Cloud Observability receives a resourceLogs
object, it constructs one LogEntry
for each logRecord
. Unlike OTLP which batches source
information with a collection of individual logs, each LogEntry
structure
contains information about the source of the log and the log itself.
To learn more about the structure of OTLP-formatted log data,
see the OpenTelemetry logs.proto
.
How LogEntry fields are set
Google Cloud Observability uses the following rules to determine the values for LogEntry
fields:
LogEntry
field(Names from HTTP reference)
logName
The system uses the following prioritized list of OpenTelemetry log record attributes to determine the log name:
-
gcp.log_name -
log_name -
event_name
Log names must be URL-safe or they are URL-encoded during ingestion.
resource
resource
field or it infers the resource. For details, see OTLP attributes to resource type mapping
.timestamp
The system uses the following prioritized list of OpenTelemetry
log record fields to determine the timestamp
:
-
time_unix_nanowhen non-zero. -
observed_time_unix_nanowhen non-zero. - The time the log entry was ingested.
The retention period for the log bucket that stores the data determines the oldest timestamp that can be ingested. For more information, see Cloud Logging quotas .
receiveTimestamp
LogEntry
is ingested.severity
httpRequest
The system maps the gcp.http_request
attributes in the
log record to equivalent LogEntry
fields. For more
information, see HttpRequest field
.
FIXME. There are other fields that get mapped to this field.
labels
trace
traceId
field. The value must be a
valid 32 char hex string, or the entry is rejected.spanId
spanId
field. The value must be a
valid 16 char hex string, or the entry is rejected.traceSampled
sourceLocation
split
apphub
apphubDestination
apphubSource
otel
LogEntry
, the system converts data types and then adds
the converted data to the otel
field. For more information,
see Otel field
.HttpRequest field
Google Cloud Observability maps OTLP attributes that apply to HTTP requests to LogEntry
fields. The following sections describe how the system maps
flat and nested attributes.
Flat attributes
The following table describes how Google Cloud Observability maps flat attributes that apply
to HTTP requests to LogEntry
fields.
For example, the value from the attribute http.request.method: "GET",
is set
as the value of the httpRequest.requestMethod
field in a log entry:
OpenTelemetryLogRecord.attribute
key-value pair. |
Value stored in the followingLogEntry
field(Names from HTTP reference) |
Accepted Type |
|---|---|---|
http.request.method
|
httpRequest.requestMethod
|
string |
url.full
http.url
|
httpRequest.requestUrl
|
string |
http.request.body.size
|
httpRequest.requestSize
|
string, int |
http.response.status_code
|
httpRequest.status
|
string, int |
http.response.body.size
|
httpRequest.responseSize
|
string, int |
user_agent.original
http.user_agent
|
httpRequest.userAgent
|
string |
client.address
|
remoteIp
|
string |
server.address
|
serverIp
|
string |
referrer
|
httpRequest.referer
|
string |
latency
|
httpRequest.latency
|
string, int |
cacheLookup
|
httpRequest.cacheLookup
|
bool |
cacheHit
|
httpRequest.cacheHit
|
bool |
cacheValidatedWithOriginServer
|
httpRequest.cacheValidatedWithOriginServer
|
bool |
cacheFillBytes
|
httpRequest.cacheFillBytes
|
string, int |
network.protocol.version
protocol
|
httpRequest.protocol
|
string |
Nested attributes
This section describes how Google Cloud Observability maps nested OTLP attributes that
apply to HTTP requests to fields in a LogEntry
. The following example
illustrates a log record that contains two attributes, each of which contains
at least one other attribute:
log_record {
attributes: {
gcp.http_request {
"requestMethod": "GET",
"requestUrl": "some-URL",
}
http_request {
"requestMethod": "GET",
}
}
}
In the table, the nested attributes are shown by using braces. For example, gcp.http_request {requestMethod}
means that the attribute gcp.http_request
contains the attribute requestMethod
. The value from the
innermost attribute is assigned to the value of the log entry field:
OpenTelemetryLogRecord.attribute
key-value pair. |
Value stored in the followingLogEntry
field(Names from HTTP reference) |
Accepted Type |
|---|---|---|
gcp.http_request {requestMethod}
http_request {requestMethod}
|
httpRequest.requestMethod
|
string |
gcp.http_request {requestUrl}
http_request {requestUrl}
|
httpRequest.requestUrl
|
string |
gcp.http_request {requestSize}
http_request {requestSize}
|
httpRequest.requestSize
|
string, int |
gcp.http_request {status}
http_request {status}
|
httpRequest.status
|
string, int |
gcp.http_request {responseSize}
http_request {responseSize}
|
httpRequest.responseSize
|
string, int |
gcp.http_request {userAgent}
http_request {userAgent}
|
httpRequest.userAgent
|
string |
gcp.http_request {remoteIp}
http_request {remoteIp}
|
httpRequest.remoteIp
|
string |
gcp.http_request {serverIp}
http_request {serverIp}
|
httpRequest.serverIp
|
string |
gcp.http_request {referer}
http_request {referrer}
|
httpRequest.referer
|
string |
gcp.http_request {latency}
http_request {latency}
|
httpRequest.latency
|
string, int |
gcp.http_request {cacheLookup}
http_request {cacheLookup}
|
httpRequest.cacheLookup
|
bool |
gcp.http_request {cacheHit}
http_request {cacheHit}
|
httpRequest.cacheHit
|
bool |
gcp.http_request {
http_request {
|
httpRequest.cacheValidatedWithOriginServer
|
bool |
gcp.http_request {cacheFillBytes}
http_request {cacheFillBytes}
|
httpRequest.cacheFillBytes
|
string, int |
gcp.http_request {protocol}
http_request {protocol}
|
httpRequest.protocol
|
string |
Labels field
To determine what labels to attach to the log entry, the system performs the following actions:
-
It removes from the OTLP log record any attributes that have been mapped to specific
LogEntryfields.For example, suppose there are the attributes attached to a log record:
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", }, }After removing fields that are mapped to specific
LogEntryfields, the following fields remain:attributes: { "log_array_attr: ["value1", "value2"], "log_json_attr": {"json_key": "json_value"} "log-string-attr": "string", } -
If an attribute contains an array or JSON elements, then the system converts the value into a string.
For example, the following illustrates how the
LogEntryrepresents the previous attributes:labels: { "log_array_attr": "[\"value1\",\"value2\"]", "log_json_attr": "{\"json_key\":\"json_value\"}", "log-string-attr": "string", }The maximum nesting depth for attributes is five. Any content that has deeper nesting is truncated.
Otel field
For fields in OTLP log data that don't have an equivalent field in a LogEntry
, the system converts data types and then adds
the converted data to the otel
field. For example, the otel
field
stores attributes from the resource
, scope
, and entity
fields.
The system uses the following rules to convert the OpenTelemetry data types
to protobuf Value
types
:
| OpenTelemetry type | protobuf type |
|---|---|
string
|
string
|
boolean
|
bool
|
integer
|
double
|
float
|
double
|
Array
|
ListValues
|
KeyValueList
|
Struct
|
To avoid double precision errors, pass integers as strings.
Payload field
The data type of the OTLP logRecord.body
field determines the structure
of the LogEntry
payload:
-
string: The system copies the string into theLogEntry.textPayloadfield. -
Array: The system creates a string of the array elements while preserving new lines. It then copies the string into theLogEntry.textPayloadfield. -
KeyValueList: The system converts those pairs into JSON and then populates theLogEntry.jsonPayloadfield, with the following restrictions:- When an OTLP record contains duplicate attribute keys, the system retains the first key and discards attributes with duplicate keys.
- When the nesting depth for a JSON pair is larger than five, the system truncates the content to a depth of five.
Severity field
This section describes how Google Cloud Observability maps the OpenTelemetry severity fields
to Cloud Logging severity
levels.
OpenTelemetry defines a severity number and severity text. The logs.proto
defines the severity numbers.
Google Cloud Observability determines the Logging severity from the
OpenTelemetry severity number, if set. Otherwise, it uses the severity text. If
neither are set, then the Logging severity is set to DEFAULT
.
| OpenTelemetry severity number Enum (value) |
OpenTelemetry severity text (tests are case insensitive) |
Cloud Logging severity Enum (value) |
|---|---|---|
SEVERITY_NUMBER_UNSPECIFIED
(0) |
"default" not set |
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) |
"critical" "fatal" "fatal2" |
CRITICAL
(600) |
SEVERITY_NUMBER_FATAL3
(23) |
"alert" "fatal3" |
ALERT
(700) |
SEVERITY_NUMBER_FATAL4
(24) |
"emergency" "fatal4" |
EMERGENCY
(800) |
SourceLocation field
Google Cloud Observability maps the following OTLP Code
directly to LogEntry
fields. This mapping is possible because these
OpenTelemetry attributes are semantically identical to Cloud Logging concepts.
OpenTelemetryLogRecord.attribute
key-value pair. |
Value stored in the followingLogEntry
field(Names from HTTP reference) |
Accepted Type |
|---|---|---|
code.file.path: Value
|
sourceLocation.file
|
string |
code.function.name: Value
|
sourceLocation.function
|
string |
code.function.number: Value
|
sourceLocation.line
|
string, int |
Limitations
This section describes limits. It also describes how Google Cloud Observability handles certain types of data.
Limits
| Description | Value | Notes |
|---|---|---|
|
Maximum number of logs per OTLP request
|
8192 | Refers to the maximum number of logRecords
in an
OTLP resourceLogs
structure. Limit. |
|
Maximum size of each request
|
5 MiB | Limit. |
| 256 KiB | Cloud Logging truncates or discards data from an OTLP log record when necessary. Limit. | |
|
Maximum length of an attribute key
|
512 B | Oversized label keys are truncated when the OTLP log record is converted
into a LogEntry
. Limit. |
|
Maximum length of an attribute value
|
64 KiB | Oversized label values when the OTLP log record is converted into a LogEntry
. Limit. |
|
Maximum depth of attribute nesting
|
5 | Attributes that exceed this limit are truncated when the OTLP log record is
converted into a LogEntry
. |
|
Maximum number of log-ingestion bytes per minute
|
2.4 GB for the following regions: 300 MB for all other regions. |
Quota. |
Behavior
-
When both the OpenTelemetry severity number and severity text are set, the system uses the severity number to determine the Cloud Logging severity level. If the OTLP record doesn't contain severity information, then the Cloud Logging severity level is set to
DEFAULT. -
When an OTLP record contains duplicate attribute keys, the system retains the first key and discards the attributes with duplicate keys.
-
The system converts attributes attached to a log record into a string. For an example, see Labels field .
-
Log names must be URL-safe or they are URL-encoded during ingestion. For information about how log names are set, see How
LogEntryfields are set .

