![]() |
LogIt++
Header-only, macro-first C++ logging library
|
OtlpHttpLogger is an optional LogIt++ backend that exports log records to an OpenTelemetry-compatible OTLP/HTTP endpoint.
The backend is disabled by default and requires the optional kurlyk dependency.
When kurlyk is placed at external/kurlyk, LogIt++ adds it only when LOGIT_WITH_OTLP=ON.
For Windows MinGW builds, the CMake integration enables kurlyk fallback options for curl, OpenSSL, and Asio when LOGIT_USE_SUBMODULES=ON. This keeps OTLP optional while still allowing a ready-made MinGW dependency path through kurlyk.
The bundled kurlyk revision requires CMake 3.21 or newer. On other platforms, install kurlyk (and its OpenSSL/curl prerequisites) separately and let find_package(kurlyk) provide the target.
For a runnable version with environment overrides, graceful shutdown, optional compression, and optional MDC trace/span fields, see examples/example_logit_otlp_http.cpp. Build with -DLOGIT_WITH_CONTEXT=ON if you want the MDC trace/span fields to be populated.
OtlpPayloadLogger callback exporterOtlpPayloadLogger shares the OTLP JSON serializer and structured-attribute configuration with OtlpHttpLogger, but does not create an HTTP client. It passes each serialized payload chunk to Config::on_payload, so applications can use their own HTTP transport, message broker, or collector adapter.
The callback exporter is asynchronous by default and owns a bounded queue. Set async = false for synchronous callback delivery, or set drop_on_overflow = false to apply producer-side backpressure. Large batches are split at max_payload_bytes; each chunk is delivered independently. The logger does not retry callback failures, but counts them in LoggerParam::FailedExportCount.
The backend sends OTLP/HTTP JSON requests:
LogRecord fields are mapped to OTLP attributes:
| LogIt++ field | OTLP field |
|---|---|
timestamp_ms | timeUnixNano |
log_level | severityText, severityNumber |
| formatted message | body.stringValue |
file, line, function | code.file.path, code.line.number, code.function.name |
thread_id | thread.id |
format | logit.format |
arg_names | logit.arg_names (legacy, deprecated) |
args_array elements | typed attributes under logit.arg.* prefix |
When include_args = true (the default), each element of args_array is emitted as a separate OTLP attribute with a typed value. The key is built from args_prefix + the sanitized argument name.
| Flag | Default | Description |
|---|---|---|
include_args | true | Emit structured typed arg attributes. |
include_arg_names | false | Emit legacy logit.arg_names string attribute. |
args_prefix | "logit.arg." | Key prefix for structured arg attributes. |
| VariableValue type | OTLP AnyValue field |
|---|---|
BOOL_VAL | boolValue |
INT8_VAL..INT64_VAL | intValue |
UINT8_VAL..UINT32_VAL | intValue |
UINT64_VAL | intValue if <= INT64_MAX, else stringValue |
FLOAT_VAL, DOUBLE_VAL, LONG_DOUBLE_VAL | doubleValue if finite, else stringValue |
| All other types | stringValue (via to_string()) |
Argument names are sanitized: characters that are not alphanumeric, _, ., or - are replaced with _. If the sanitized name is empty or consists only of underscores, a positional key (args_prefix + index) is used instead.
Duplicate keys are resolved by appending .N (starting at 1 for the second occurrence). For example, two args both named px produce keys logit.arg.px and logit.arg.px.1.
The default prefix logit.arg. is reserved. Changing args_prefix is supported but may cause attribute collisions with other OTLP receivers.
Avoid putting unique values (timestamps, request IDs, UUIDs) into arg attributes. High-cardinality attributes increase memory and storage costs in OTLP collectors and backends (Loki, Tempo, etc.). Use structured attributes for low-cardinality dimensions like symbol, side, or region.
The logit.arg_names OTLP attribute (controlled by include_arg_names) is deprecated. It emits argument names as a single comma-separated string with no type information. Prefer include_args = true for typed, queryable attributes.
Resource attributes are configured through OtlpHttpLogger::Config.format, including service.name, service.namespace, service.instance.id, and deployment.environment.name.
OtlpHttpLogger exposes its internal counters through the generic logger parameter API:
Available diagnostic params:
| Parameter | Meaning |
|---|---|
LoggerParam::DroppedLogCount | Number of records dropped because the backend queue overflowed or the logger was stopping. |
LoggerParam::FailedExportCount | Number of failed OTLP export attempts. |
These values are also available through get_string_param() and get_float_param(). Integer retrieval saturates at int64_t max if the underlying unsigned counter ever exceeds that range.
OtlpHttpLogger is an outbound client/exporter, not a server.async=true.