Berserk Docs

OTEL Field Mapping

How OpenTelemetry Protocol fields map to Berserk columns for traces, logs, and metrics

Berserk converts OTLP data into rows with the following conventions:

  • Field names use snake_case
  • Timestamps are stored as DateTime (nanoseconds since epoch)
  • Durations are stored as Timespan (100-nanosecond ticks)
  • IDs (trace, span) are hex-encoded strings
  • Attribute keys are stored as-is (e.g., "http.method" stays as a flat key under attributes). Dotted-path shortcuts let you also access them as attributes.http.method.
  • Flattened metadata: Scope, metric, and status metadata are top-level prefixed columns
  • Empty/default fields are omitted to save space

Common Structures

Resource

Resource IS the attributes map directly. dropped_resource_attributes_count is stored as a separate top-level field.

resource: {
  "service.name": "my-service",
  "host.name": "host-1"
}
dropped_resource_attributes_count: 5  // only if > 0

Scope

Scope metadata is flattened to top-level columns. The scope bag holds only scope attributes.

OTEL FieldBerserk FieldType
InstrumentationScope.namescope_nameString
InstrumentationScope.versionscope_versionString
InstrumentationScope.attributesscopePropertybag
scope_name: "opentelemetry-java",
scope_version: "1.25.0",
scope: {                   // only if non-empty, flat keys
  "custom.attr": "value"
}

Attributes

All attributes (span, log, event, link) store keys as flat strings:

attributes: {
  "http.method": "GET",
  "http.status_code": 200
}

Accessible via both attributes.['http.method'] (bracket notation) and attributes.http.method (dotted shortcut).

Traces (Spans)

Each OTLP span becomes one row.

OTEL FieldBerserk FieldTypeNotes
start_time_unix_nanostart_timeDateTimeSpan start timestamp
end_time_unix_nanoend_timeDateTimeSpan end timestamp
end_time_unix_nanotimestampDateTimePrimary timestamp (copy of end_time)
(computed)ingest_timeDateTimeIngestion timestamp
(computed)durationTimespan(end_time - start_time) / 100
trace_idtrace_idStringHex-encoded
span_idspan_idStringHex-encoded
parent_span_idparent_span_idStringHex-encoded, omitted if empty
namespan_nameStringSpan operation name
kindspan_kindStringINTERNAL, SERVER, CLIENT, PRODUCER, CONSUMER
trace_statetrace_stateStringW3C trace state
status.codestatus_codeString"UNSET", "OK", "ERROR"
status.descriptionstatus_descriptionStringOnly if non-empty
flags (bit 0)sampledBooleanOnly if sampled flag is set
flags (bits 1-31)flagsLongOnly if uninterpreted bits remain
attributesattributesPropertybagFlat keys
resourceresourcePropertybagIS the attributes map directly
scope.namescope_nameStringFlattened to top level
scope.versionscope_versionStringFlattened to top level
scope.attributesscopePropertybagScope attributes only
eventseventsArraySee Events structure
linkslinksArraySee Links structure
dropped_attributes_countdropped_attributes_countLongOnly if > 0
dropped_events_countdropped_events_countLongOnly if > 0
dropped_links_countdropped_links_countLongOnly if > 0
(from resource)dropped_resource_attributes_countLongOnly if > 0
(from scope)dropped_scope_attributes_countLongOnly if > 0

Events

Each event in the events array is a propertybag with timestamp, name, attributes, and optional dropped_attributes_count.

Each link in the links array is a propertybag with trace_id, span_id, optional trace_state, sampled, is_remote, flags, attributes, and optional dropped_attributes_count.

Example

{
  "timestamp": "2024-01-15T10:30:00.150000000Z",
  "start_time": "2024-01-15T10:30:00.000000000Z",
  "end_time": "2024-01-15T10:30:00.150000000Z",
  "ingest_time": "2024-01-15T10:31:00.000000000Z",
  "trace_id": "0af7651916cd43dd8448eb211c80319c",
  "span_id": "b7ad6b7169203331",
  "parent_span_id": "00f067aa0ba902b7",
  "span_name": "GET /api/users",
  "span_kind": "SERVER",
  "duration": "150ms",
  "status_code": "OK",
  "attributes": {
    "http.method": "GET",
    "http.status_code": 200
  },
  "resource": {
    "service.name": "user-service",
    "service.version": "1.0.0"
  },
  "scope_name": "opentelemetry-java",
  "scope_version": "1.25.0"
}

Logs

Each OTLP log record becomes one row.

OTEL FieldBerserk FieldTypeNotes
time_unix_nanotimestampDateTimeFalls back to current time if 0
observed_time_unix_nanoobserved_timeDateTime
(computed)ingest_timeDateTimeIngestion timestamp
trace_idtrace_idStringHex-encoded, for log-trace correlation
span_idspan_idStringHex-encoded
severity_numberseverity_numberLong1-24 per OTEL spec
severity_textseverity_textStringINFO, ERROR, etc.
bodybodyDynamicString, object, or array
flags (bit 0)sampledBooleanOnly if sampled flag is set
flags (bits 1-31)flagsLongOnly if uninterpreted bits remain
attributesattributesPropertybagFlat keys
resourceresourcePropertybagIS the attributes map directly
scope.namescope_nameStringFlattened to top level
scope.versionscope_versionStringFlattened to top level
scope.attributesscopePropertybagScope attributes only
dropped_attributes_countdropped_attributes_countLongOnly if > 0
(from resource)dropped_resource_attributes_countLongOnly if > 0
(from scope)dropped_scope_attributes_countLongOnly if > 0

Example

{
  "timestamp": "2024-01-15T10:30:00.000000000Z",
  "observed_time": "2024-01-15T10:30:00.001000000Z",
  "ingest_time": "2024-01-15T10:31:00.000000000Z",
  "trace_id": "0af7651916cd43dd8448eb211c80319c",
  "span_id": "b7ad6b7169203331",
  "severity_number": 9,
  "severity_text": "INFO",
  "body": "User login successful",
  "attributes": {
    "user.id": "12345"
  },
  "resource": {
    "service.name": "auth-service"
  },
  "scope_name": "com.example.auth",
  "scope_version": "2.0.0"
}

Metrics

Each OTLP metric data point becomes one row. The structure varies by metric type.

Common Fields

OTEL FieldBerserk FieldTypeNotes
time_unix_nanotimestampDateTimeData point timestamp
(computed)ingest_timeDateTimeIngestion timestamp
start_time_unix_nanostart_timeDateTimeAggregation window start
Metric.namemetric_nameStringFlattened from metric metadata
Metric.typemetric_typeString"gauge", "sum", "histogram", etc.
Metric.descriptionmetric_descriptionStringFlattened from metric metadata
Metric.unitmetric_unitStringFlattened from metric metadata
attributesattributesPropertybagFlat keys, data point attributes
resourceresourcePropertybagIS the attributes map directly
scope.namescope_nameStringFlattened to top level
scope.versionscope_versionStringFlattened to top level
flags (bit 0)no_recorded_valueBooleanOnly if no_recorded_value flag is set
flags (bits 1-31)flagsLongOnly if uninterpreted bits remain
(from resource)dropped_resource_attributes_countLongOnly if > 0
(from scope)dropped_scope_attributes_countLongOnly if > 0

Gauge / Sum

Single value field (int or double). Sum also includes aggregation_temporality and is_monotonic.

{
  "timestamp": "2024-01-15T10:30:00.000000000Z",
  "metric_name": "http.server.request.duration",
  "metric_type": "sum",
  "metric_unit": "ms",
  "value": 1234.5,
  "aggregation_temporality": "CUMULATIVE",
  "attributes": {
    "http.method": "GET",
    "http.status_code": 200
  },
  "resource": {
    "service.name": "api-gateway"
  },
  "scope_name": "opentelemetry-collector"
}

Histogram

Fields: count, sum, min, max, bucket_counts, explicit_bounds, aggregation_temporality.

{
  "timestamp": "2024-01-15T10:30:00.000000000Z",
  "metric_name": "http.server.request.duration",
  "metric_type": "histogram",
  "metric_unit": "ms",
  "count": 100,
  "sum": 5432.1,
  "min": 1.2,
  "max": 234.5,
  "bucket_counts": [10, 25, 40, 20, 5],
  "explicit_bounds": [10, 50, 100, 200],
  "aggregation_temporality": "DELTA",
  "attributes": {
    "http.method": "GET"
  },
  "resource": {
    "service.name": "api-gateway"
  }
}

Exponential Histogram

Fields: count, sum, min, max, scale, zero_count, positive (offset + bucket_counts), negative (offset + bucket_counts), aggregation_temporality.

{
  "timestamp": "2024-01-15T10:30:00.000000000Z",
  "metric_name": "http.server.request.duration",
  "metric_type": "exponential_histogram",
  "count": 100,
  "sum": 5432.1,
  "min": 1.2,
  "max": 234.5,
  "scale": 3,
  "zero_count": 2,
  "positive": {
    "offset": 5,
    "bucket_counts": [10, 25, 40, 20, 5]
  },
  "negative": {
    "offset": 0,
    "bucket_counts": [1, 2]
  },
  "aggregation_temporality": "CUMULATIVE"
}

Summary

Fields: count, sum, quantile_values (array of {quantile, value}).

{
  "timestamp": "2024-01-15T10:30:00.000000000Z",
  "metric_name": "http.server.request.duration",
  "metric_type": "summary",
  "count": 100,
  "sum": 5432.1,
  "quantile_values": [
    { "quantile": 0.5, "value": 45.2 },
    { "quantile": 0.9, "value": 123.4 },
    { "quantile": 0.99, "value": 198.7 }
  ]
}

Omitted Fields

The following OTEL fields are intentionally not stored:

  • Schema URLs at all levels (not needed for storage)
  • InstrumentationScope.dropped_attributes_count (low value)
  • Metric exemplars (high cardinality; can be added if needed)
  • Link.flags are decomposed into sampled, is_remote, and remaining flags

On this page