OpenTelemetry supports attributes at different levels in an OpenTelemetry log request, such as the resource level, scope level, and record level.
The Log ingestion API collects and attempts to automatically transform log data.
Each log record from the ingested batch is mapped to a single Dynatrace log record, which contains three special attributes: timestamp, loglevel, content, and a set of other key-value attributes. These properties are set based on keys present in the input object as follows.
If the timestamp cannot be set based on the Timestamp field, timestamp is determined based on one of the following, evaluated in order:
If the timestamp is taken from the body or OTLP log record, it is set based on the value of the first key from the following list, evaluated in the order presented in the list, and is case-insensitive: timestamp, @timestamp, _timestamp, eventtime, date, published_date, syslog.timestamp, time, epochSecond, startTime, datetime, ts, timeMillis, @t.
Supported timestamp formats: UTC milliseconds, RFC3339, and RFC3164.
The default value is the current timestamp and the default timezone is UTC if it's missing in timestamp.
Log events older than the Log Age limit are discarded. Timestamps more than 10 minutes ahead of the current time are replaced with the current time. See the Ingestion limits section for details.
If the loglevel cannot be set based on the SeverityText or SeverityNumber field, loglevel is determined based on one of the following, evaluated in order:
If the loglevel is taken from the body or OTLP log record, it is set based on the value of the first key from the following list, evaluated in the order presented in the list, and is case-insensitive: loglevel, status, severity, level, syslog.severity.
NONE.If the Body field is of kvlist_value type (a list of key-value pairs), content is set based on the value of the first key found in Body from the following list, evaluated in the order presented in the list: content, message, payload, body, log.
If no attribute is found among supported content keys, then content is set to an empty string.
Contains all other attributes from the input record's attributes contained in the sections: Resource, InstrumentationScope, and Attributes.
The TraceID and SpanID attributes are mapped to the trace_id and span_id fields, and their values are converted to hexadecimal representation (e.g., 0xCAFEBABE).
Automatic attribute. The dt.auth.origin attribute is automatically added to every log record ingested via API. This attribute is the public part of the API key that the log source authorizes to connect to the generic log ingest API.
All attributes should preferably map to semantic attributes for Dynatrace to interpret them correctly.Refer to the Semantic attributes (Logs Classic) for more details.
Dynatrace supports OpenTelemetry data types as described in the sections below.
All attribute keys are lowercased and all attribute values are stringified. Custom attributes and semantic attributes can generally be used in queries.
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 attribute values are converted to arrays of a uniform type. The target type is chosen according to the following rules:
Maps are ingested by extracting their keys recursively and storing the values as separate attributes, with names reflecting their position in the map hierarchy and prefixed with the map name. See Log ingestion API processing for more details.
See Log Monitoring default limits (Logs Classic) for the limits applied to ingested log requests, their attributes, and their attribute values.
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 ActiveGate.
In this case, the map attribute values are flattened, i.e. replaced with keys concatenated using a dot (.) until a simple value is reached in the hierarchy, 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=="]
Flattening proceeds up to the maximum nesting level specified by the Nested objects limit. Structures nested deeper than this are replaced with the string value <truncated due to nesting limit>. See the Ingestion limits section for details.
If the Body field is of kvlist_value type (a list of key-value pairs), the structure is processed in the same way as log record attributes, including flattening and conflict resolution.
Attributes found in Body may also be used for setting the timestamp, loglevel, and content attributes of the log record, as described below.
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"
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=\"]"...
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:
my.attributeoverwritten1.my.attributeoverwritten2.my.attributeThe Log ingestion API additionally accepts log attributes through:
X-Dynatrace-AttrThese attributes are merged with those provided in the OpenTelemetry log request according to the rules described below.
Request URL
Resulting output
otlphttp:logs_endpoint: /api/v2/otlp/v1/logs?env=prod&env=blue&team=payments
Body: "Hello World!"
{"content": "Hello World!","env": ["prod", "blue"],"team": "payments"}
The API supports a special header for passing additional attributes:
otlphttp:endpoint: /api/v2/otlpheaders:X-Dynatrace-Attr: region=eu-central-1&team=core
Rules:
When attributes appear in multiple places, the Log ingestion API applies attribute precedence while still preserving body values for auditability. The attributes are applied in the following order:
When attributes from query parameters or the header override log request attributes:
overwrittenN.<attribute_key>.
Where N is an incrementing integer (1, 2, …) depending on how many log request-originating values had to be preserved. This ensures uniqueness, even when multiple conflicts occur.overwrittenN.* keys. Attributes overridden by higher-precedence sources do not generate overwritten copies.Request
Resulting output
otlphttp:logs_endpoint: /api/v2/otlp/v1/logs?team=frontend
Log Request:
Body: "Hello World!"Attributes:- "team": "backend"
{"content": "Hello World!","team": "frontend","overwritten1.team": "backend"}
Attributes provided through query parameters or headers are included in billing calculations.
For multi-value attributes, the attribute key contributes to billing only once, regardless of how many values are present.