Releases: haproxytech/opentelemetry-c-wrapper
Export-pipeline record counts and debug-allocator fixes
Highlights
The export-pipeline status now reports how many spans and log records each exporter carried, not just how many Export() calls it made. This release also fixes two debug-allocator issues, one of them a crash on teardown.
API changes
- Added
records_okandrecords_failtostruct otelc_export_status, tallied in the span and log counting exporters from the size of each successful or failed batch, alongside the existingexport_ok/export_failExport()-call counts. The metric signal exports oneResourceMetricsblob per reader cycle and has no per-record count, so both fields report-1there, matching the queue fields already-1for metrics.
Because struct otelc_export_status grew, the library version was raised to 5:0:0 (current bumped, age 0), moving the SOVERSION from 4 to 5; the package version took a minor bump to 2.2.0. Consumers must recompile against the new headers.
Bug fixes
Both affect the debug build (opentelemetry-c-wrapper_dbg) only.
- Fixed a
free(): invalid pointerabort. An allocation made beforeotelc_dbg_mem_init()ran left its reserved metadata-header magic uninitialized; at free time the invalid magic sentotelc_dbg_free()down a fallback that released the user pointer instead of the real allocation base, and glibc aborted. The metadata header is now initialized in that early-return path too, so a pointer handed out before the tracker exists stays freeable. - Stopped emitting
invalid magic/metadatawarnings for foreign memory.otelc_dbg_free()now passes blocks it did not allocate -- such as HAProxy-allocated memory freed during teardown -- straight to the C library, matchingotelc_dbg_realloc(), while still catching genuine double frees of tracked memory.
Documentation
- The README pipeline-status section documents the new record fields and the call-versus-record distinction.
Full Changelog: v2.1.0...v2.2.0
Export-pipeline status accessor
Highlights
A single accessor now reports the health of the export pipeline across all signals, replacing the earlier per-signal dropped-count function.
API changes
- Added
otelc_pipeline_status_get(). It fills a caller-providedstruct otelc_pipeline_statusdescribing the export pipeline for the trace, log, and metric signals. Each signal is reported through astruct otelc_export_statuscarrying successful and failed exporterExport()calls, batch-queue depth and capacity, dropped-record count, and milliseconds since the last successful export. Inapplicable fields are reported as-1; the metric signal has no batch queue, so itsdropped,queue_depth, andqueue_capacityare always-1. - Removed
otelc_processor_dropped_count(), superseded by the accessor above.
Because a public symbol was removed, the library version was raised to 4:0:0 (current bumped, age reset); the package version took a minor bump to 2.1.0.
Signal coverage
- Traces — span-exporter outcomes and span-processor queue counted.
- Logs — log-exporter outcomes and log-processor queue counted.
- Metrics — exporter outcomes counted via a counting metric exporter wired into the periodic reader; the metric reader has no queue.
Documentation
- The README now documents the export-pipeline status accessor, its per-signal fields, and the asynchronous-exporter caveat.
Configurable log observed timestamp
Package version 2.0.0 -- library version 3:0:0 (major release).
What's new
- The logger can now carry an externally observed time into a record: a new
ts_obsargument sets the log record's observed timestamp, while the event timestamp still comes fromts.
Breaking changes
- The new
ts_obsargument changes the public signatures of thelog,log_span,log_bodyandlog_body_spanoperations, so this is a major release and the library age was reset. Existing callers must add the argument and may passNULLto keep the SDK default.
Bug fixes
- The observed timestamp is no longer forced to the event time. A non-NULL event time was previously written to both the event and observed timestamps, which discarded the collection-lag signal and, for a back-dated time, reported the record as observed before it occurred. The event timestamp now comes from
tswhile the observed timestamp stays at the SDK default (the moment the record is created), keeping the two timestamps in their correct order.
Other changes
- The C++-only trace macros moved into an internal
debug.hheader. - A debug trace now flags any record whose event time post-dates its observed time.
Full Changelog: v1.1.0...v2.0.0
Thread affinity and static linking support
What's New
- Optional CPU affinity for OTel SDK threads. A new
cpu_idfield in the per-component YAML pins SDK-managed threads to a specific CPU core viapthread_setaffinity_np(). Defaults to-1(no affinity), so existing configurations are unchanged. Guarded byHAVE_SCHED_H. - Static-library builds. The wrapper itself can now be built as a
.aarchive (cmake -DBUILD_STATIC=ON/ autotools--enable-static --disable-shared). A matchinglib-type=staticargument toscripts/build-bundle.shbuilds the bundledopentelemetry-cppSDK as static archives, with full transitive-dependency probing.
Bug fix
- Fixed a double free in
make_shared_nothrowwhen the underlying allocation throwsstd::bad_alloc.
Build and packaging
- Bundled monorepo assembly script for
opentelemetry-cpp1.26.0. - Auto-detected
rymllibvslib64via a newAX_FIND_LIBDIRmacro. - Silenced GCC 15
alloc-size, clang nullability (absl), and unused-but-set warnings under-Werror. - Replaced GCC
typeofwithdecltype/__typeof__for portability.
ABI
The library libtool version was bumped from 1:1:1 to 2:0:2. The change is purely additive: it introduces a new option without altering the existing surface, so consumers continue to link against libopentelemetry_c_wrapper without modification.
Full changelog
Exporter thread stability and expanded YAML reference
What's New
- Pre-spawned background threads on OTLP HTTP, OTLP gRPC, OTLP File, and Elasticsearch exporters at construction time, so threads are ready before the first batch export.
- Added the
background_thread_wait_forYAML option for OTLP/HTTP exporters, controlling how long the curl background thread lingers after its last request. A value of 0 (the default) keeps the thread alive indefinitely, preventingstd::terminate()crashes caused by thread respawn failures inside the SDK's noexceptMaybeSpawnBackgroundThread()call. - Split the single OTel SDK patch into numbered per-feature patches and added a dedicated patch for
SetBackgroundWaitFor()support. - No public API or ABI changes since 1.0.1.
Documentation
- Expanded the YAML configuration reference (README section 6) with detailed documentation of every configurable key for all exporter types, samplers, processors, readers, providers, signal binding, and environment variables.
- Noted manual patch and CMake option requirements for builds that do not use the provided scripts.
Build system hardening and documentation updates
What's New
- Enforced minimum OpenTelemetry C++ SDK version (>= 1.26.0) and ABI version 2 at configure time in both autotools and CMake build systems.
- Required autoconf-archive as a build dependency with a clear error message when missing.
- Made the bootstrap script abort on aclocal failure.
- Commented out aws-lc and curl build steps in build-bundle.sh; users can re-enable them as needed.
Documentation
- Added build script usage recommendations to README and README.md.
- Documented default dependency configuration and SSL/curl requirements.
- Updated AWS-LC paragraph to reflect current defaults.
opentelemetry-c-wrapper 1.0.0
opentelemetry-c-wrapper 1.0.0
First public release of the OpenTelemetry C wrapper library -- a pure C API on top of the OpenTelemetry C++ SDK,
developed by HAProxy Technologies.
Signals
All three OpenTelemetry signals are supported:
- Traces -- span creation and lifecycle, context propagation, baggage, sampling (including ParentBased per-state delegates), events, links, and exception recording.
- Metrics -- synchronous and observable instruments (counters, histograms, gauges, up-down counters), views, and multiple metric reader/exporter pairs.
- Logs -- structured log records with severity filtering and span correlation.
Exporters
| Exporter | Traces | Metrics | Logs |
|---|---|---|---|
| OTLP/gRPC | yes | yes | yes |
| OTLP/HTTP | yes | yes | yes |
| OTLP/File | yes | yes | yes |
| OStream | yes | yes | yes |
| In-Memory | yes | yes | -- |
| Zipkin | yes | -- | -- |
| Elasticsearch | -- | -- | yes |
Highlights
- YAML-based configuration for all SDK components (exporters, processors, samplers, providers) via rapidyaml or libfyaml.
- Thread-safe data-plane operations with a 64-shard span map for low contention under concurrent workloads.
- Operations vtable design -- each signal instance carries an
opspointer, keeping the C API clean and extensible. - Multiple processors and exporters per signal provider.
- Dropped span/log counting via delegating processors.
- SDK internal log handler exposed through the C API.
- Build support via both Autotools and CMake.
- Bundled dependency build scripts for all required libraries.
- Test suite covering tracer, meter, logger, and YAML parsing, with Docker Compose integration tests (Elasticsearch/Kibana, OTel Collector).
Tested Platforms (amd64)
Debian 11/12/13, Ubuntu 20.04/22.04/24.04, Tuxedo 24.04, RHEL 8.10/9.5/10.0, Rocky 9.5, openSUSE Leap 15.5/15.6.