LogRecord

@Serializable
data class LogRecord(val recordId: ByteString, val severityNumber: Int? = null, val severityText: String? = null, val body: String? = null, val attributes: Map<String, String> = emptyMap(), val timestampEpochNanos: Long? = null, val observedEpochNanos: Long? = null, val traceId: ByteString? = null, val spanId: ByteString? = null)

A single log-record shaped to round-trip through OTLP.

This is kuilt's KMP-native representation of an OpenTelemetry LogRecord. Fields map 1-to-1 to OTLP's LogRecord proto message so a WarpOtlpBridge can serialize them directly with no further transformation.

Trace correlation

traceId and spanId are optional: present when the log was emitted from inside an active trace span; null for untraced log lines. Byte conventions match SpanRecord exactly — 16 bytes for trace id, 8 bytes for span id.

Identity and idempotency

recordId is an 8-byte caller-assigned identifier unique per record per producer. WarpLogRecordExporter uses it to detect re-exports: submitting a record with the same recordId twice is a no-op (the second call returns ExportResult.Success immediately without inserting a duplicate into the us.tractat.kuilt.crdt.Rga).

ByteString is used for all byte fields because it provides content-based equals/hashCode, which WarpLogRecordExporter's dedup map keys on.

Honest limits

  • Clock skew. observedEpochNanos and timestampEpochNanos are the producer's local clock. Long-offline devices may have skewed clocks; HLC offset estimation on reconnect is not yet implemented.

  • Ordering. The us.tractat.kuilt.crdt.Rga preserves per-producer insertion order. Cross-producer ordering is resolved by RGA's Lamport tiebreak — deterministic but not wall-clock accurate under clock skew.

Constructors

Link copied to clipboard
constructor(recordId: ByteString, severityNumber: Int? = null, severityText: String? = null, body: String? = null, attributes: Map<String, String> = emptyMap(), timestampEpochNanos: Long? = null, observedEpochNanos: Long? = null, traceId: ByteString? = null, spanId: ByteString? = null)

Properties

Link copied to clipboard

Key/value string attributes attached to this record.

Link copied to clipboard
val body: String?

The log body as a plain string. null means the body is absent.

Link copied to clipboard

Epoch-nanosecond timestamp at which the record was observed by the SDK, from the producer's local clock — OTLP's observedTimeUnixNano.

Link copied to clipboard
@Serializable(with = ByteStringSerializer::class)
val recordId: ByteString

8-byte caller-assigned record identifier. Must be unique per record per producer. Used by WarpLogRecordExporter to make re-export idempotent.

Link copied to clipboard

OTLP severity number (1–24). null means unset (OTLP default: SEVERITY_NUMBER_UNSPECIFIED).

Link copied to clipboard

Human-readable severity text (e.g. "INFO", "WARN"). null means unset.

Link copied to clipboard
@Serializable(with = ByteStringSerializer::class)
val spanId: ByteString?

Trace context — 8-byte span id. Present only when this record was emitted inside an active span. Matches OTLP proto3 bytes span_id.

Link copied to clipboard

Epoch-nanosecond timestamp at which the event occurred, from the producer's local clock — OTLP's timeUnixNano. null if the event time is unknown.

Link copied to clipboard
@Serializable(with = ByteStringSerializer::class)
val traceId: ByteString?

Trace context — 16-byte trace id. Present only when this record was emitted inside an active span. Matches OTLP proto3 bytes trace_id.