Ingest OTLP logs

  • Latest Dynatrace
  • Reference
  • 3-min read

When ingesting OpenTelemetry logs, the following transformation rules and ingestion limitations apply.

Data types

Dynatrace supports OpenTelemetry data types as described in the sections below.

Scalar value

Scalar values are transformed as such:

  • Logs on Grail with OpenPipeline custom processing (Dynatrace SaaS version 1.295+, Environment ActiveGate version 1.295+): All JSON data types (string, number, boolean, null) are supported. All attributes can be used in queries. Keys are case-sensitive.

  • Logs on Grail with OpenPipeline routed to Classic Pipeline: All attribute keys are lowercased and all attribute values are stringified. All attributes can be used in queries.

  • Log Monitoring Classic: All attribute keys are lowercased and all attribute values are stringified. Custom attributes and semantic attributes can generally be used in queries.

Byte array

Byte arrays are converted to base64-encoded strings. For example, the following array

[0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64]

is transformed and ingested as aGVsbG8gd29yZA==.

Array

Array attribute values are converted to arrays of a uniform type. The target type is chosen according to the following rules:

  • Complex values, such as arrays, or objects are mapped to JSON string values.
  • If any value in the array is a string, or if any value must be converted to a string (e.g., an object or array), the target type of the entire array is string.
  • If all values in the source array are numeric, the target array type is numeric.
  • Null values are considered compatible with any type.

Map

Map processing depends on the data model used. See Log processing for more details.

Attribute ingestion

OpenTelemetry supports attributes at different levels in an OpenTelemetry log request, such as the resource level, scope level, and record level.

Flattened data model

When attributes are saved in a flattened fashion on the Dynatrace side, there may be name collisions if attributes on different levels share the same name. Dynatrace resolves this by prefixing duplicate attributes with overwritten[COUNTER].. The counter value indicates how many times the attribute name has been already encountered as a duplicate.

For example, if you have three attributes all named my.attribute on the resource, scope, and log levels:

  • the resource attribute is ingested as my.attribute
  • the scope attribute is ingested as overwritten1.my.attribute
  • the log attribute is ingested as overwritten2.my.attribute

Raw data model

In the raw data model, OTLP resource attributes and OTLP attributes are parsed into Dynatrace top-level attributes, and the OTLP body is parsed into the content.

Dynatrace prefixes duplicate attributes with an incrementing counter, for example overwritten1.myattribute. The counter value indicates how many times the attribute has been encountered as a duplicate. This avoids name collisions when attributes at different OTLP levels share the same name.

Ingestion limits

See Log Management and Analytics default limits and Log Monitoring default limits (Logs Classic) for the limits applied to ingested log requests, their attributes, and their attribute values.

Log ingestion API processing

The Log ingestion API ingests structured logs in OTLP format.

There are two data models that identify how structured logs are processed by log ingestion endpoints: raw and flattened. The difference between the two is in how attributes with object/dictionary values are transformed.

Raw data model

The raw data model transforms the content of structured logs as described in the sections below. All the following examples apply to Log ingestion API endpoints available on Environment ActiveGateand SaaS.

Maps and arrays in attributes

For the raw data model, the map attribute values are turned into a JSON string, and the array attribute values are turned into an array of the uniform type.

Input

Log ingestion API endpoint output

body: "Hello world!"
Resource:
- "any-attr-type-3": {"3" = "c"}
Scope:
- "any-attr-type-2": {"2" = "b"}
Attributes:
- "any-attr-type-1": {"1" = "a"}
- "any-attr-type-4":
[ "val1", 10, -123.456, false, 0x01020304 ]
“content”: "Hello world!"
"any-attr-type-1": "{\"1\": \"a\"}"
"any-attr-type-2": "{\"2\": \"b\"}"
"any-attr-type-3": "{\"3\": \"c\"}"
"any-attr-type-4":
["val1", "10", "-123.456", "false", "AQIDBA=="]

Map in body

In this case, the content is converted to a JSON string.

Input

Log ingestion API endpoint output

Body:
{
"content" = "Hello World!",
"my-body-attr-1": "abc",
"my-body-nested-1": {
"subkey": "val"
},
"@timestamp": "2025-06-01 13:01:02.123",
"loglevel": "INFO"
}
"content": "{ \"content\" = \"Hello World!\",
\"my-body-attr-1\": \"abc\",
\"my-body-nested-1\": {
\"subkey\": \"val\"
},
\"@timestamp\": \"2025-06-01 13:01:02.123\",
\"loglevel\": \"INFO\"
}"

Body as array

In this case, the array in the body is stringified.

Input

Log ingestion API endpoint output

Body:
[ "string-val", true, 12, 12.34, 0x6279746573 ]
"content": "[\"string-val\",true,12,12.34,\"Ynl0ZXM=\"]"
...

Flattened data model

With the flattened data model, the content of structured logs is transformed as described in the sections below. All the following examples apply to Log ingestion API endpoints available on Environment ActiveGateand SaaS.

Maps and arrays in attributes

In this case, the JSON attribute values are flattened, and the array attribute values are turned into a custom string.

Input

Log ingestion API endpoint output

body: "Hello world!"
Resource:
- "any-attr-type-3": {"3" = "c"}
Scope:
- "any-attr-type-2" : {"2" = "b"}
Attributes:
- "any-attr-type-1" : {"1" = "a"}
- "any-attr-type-4" :
[ "val1", 10, -123.456, false, 0x01020304 ]
“content”: "Hello world!"
"any-attr-type-1.1": "a"
"any-attr-type-2.2": "b"
"any-attr-type-3.3": "c"
"any-attr-type-4":
["val1", 10, -123.456, false, "AQIDBA=="]

Map in body

In this case, the map attributes are merged with the log record.

Input

Log ingestion API endpoint output

Body:
{
"content" = "Hello World!",
"my-body-attr-1": "abc",
"my-body-nested-1": {
"subkey": "val"
},
"@timestamp": "2025-06-01 13:01:02.123",
"loglevel": "INFO"
}
Attributes:
- "any-attr-type-1" : "my-attr"
"content": "Hello world!"
"timestamp": "2025-06-01 13:01:02.123"
"loglevel": "INFO"
"any-attr-type-1": "my-attr"
"my-body-attr-1": "abc"
"my-body-nested-1.subkey": "val"

Body as array

In this case, the array in the body is stringified.

Input

Log ingestion API endpoint output

Body:
[ "string-val", true, 12, 12.34, 0x6279746573 ]
"content": "[\"string-val\",true,12,12.34,\"Ynl0ZXM=\"]"
...
Related tags
Application Observability