OtlpTracingAppender
An io.github.smyrgeorge.log4k.Appender that publishes finished spans over OTLP/HTTP (POST /v1/traces, JSON) — the vendor-neutral OpenTelemetry protocol accepted natively by most tracing backends: the OpenTelemetry Collector, Jaeger, Grafana Tempo, Honeycomb, the Datadog Agent's OTLP ingest, and many more. Register it with RootLogger.Tracing.appenders.register(...).
Spans are shipped in batches (via BatchAppender): a batch is sent as soon as it reaches batchSize spans or when batchTimeout elapses since the first span of the batch arrived — so low traffic never holds spans back for long.
The HTTP transport is a Ktor client: pass an engine explicitly, or add exactly one Ktor engine artifact for your platform (CIO, Darwin, Curl, WinHttp, Js, ...) to the runtime classpath and leave it null so the engine is discovered automatically.
Mapping notes:
log4k's span model is already OpenTelemetry-shaped, so the mapping is direct: hex trace and span ids pass through unchanged (a 16-char/64-bit hex trace id is zero-padded; a non-hexadecimal or all-zero id is hashed to a stable valid one), events map to span events, and the status code/description map to the OTLP status.
Tags map to typed attributes: booleans to
boolValue, integer numbers tointValue, floating-point numbers todoubleValue, everything else tostringValue.When a span ends with an error but no explicit
exceptionevent was recorded, anexceptionevent (exception.type/message/stacktrace) is synthesized from the status, per the OpenTelemetry exception conventions.
Delivery is best-effort: endpoint failures are reported to the console, and the batch is dropped — the appender itself keeps running.
Parameters
The service.name resource attribute the spans are reported under.
Base URL of the OTLP/HTTP endpoint (the standard /v1/traces path is appended). Defaults to http://localhost:4318.
Maximum number of spans per request. Defaults to 100.
Maximum time to hold an incomplete batch. Defaults to 2 seconds.
Optional deployment.environment.name resource attribute.
Optional service.version resource attribute.
Extra HTTP headers for every request — most vendors authenticate this way (e.g. x-honeycomb-team, api-key, Authorization).
Optional Ktor HttpClientEngine. When null, the engine available on the classpath is used.