Skip to content

Split code into third-party workarounds and ESP integrations; document tested features with per-feature examples #37

@ltowarek

Description

@ltowarek

Summary

The component mixes two fundamentally different kinds of code: patches that make upstream third-party libraries compile on Xtensa/ESP-IDF (workarounds), and purposeful ESP32 adaptations that are part of the integration's value (features). These should live in clearly labelled subtrees. The README should then list each workaround and each integration as a first-class item, alongside an explicit inventory of which upstream OTel C++ SDK features have been tested — each backed by a dedicated example.

Current structure

src/
  esp_heap_align.cpp              — operator new/delete aligned to alignof(max_align_t)
  esp_posix_shims.c               — nanosleep, pthread_atfork, sysconf, THREADPTR pre-init
  esp_http_client_transport.cpp   — esp_http_client-backed OTLP HTTP transport
  esp_opentelemetry.cpp           — user-facing setup facade

shims/
  absl_encode_varint_bool_fix.h   — EncodeVarint overload ambiguity fix (Xtensa GCC 13.2)
  sys/mman.h                      — mmap/munmap backed by malloc (Abseil LowLevelAlloc)
  time.h                          — tm_gmtoff macro for Abseil cctz

Everything is flattened together. A reader cannot tell at a glance which files exist because of upstream bugs / toolchain gaps, and which ones represent deliberate design choices that will still be relevant after the upstream is updated.

Proposed directory split

src/
  workarounds/
    heap_align.cpp          — currently esp_heap_align.cpp
    posix_shims.c           — currently esp_posix_shims.c
    absl_varint_bool.h      — currently shims/absl_encode_varint_bool_fix.h
    mman.h                  — currently shims/sys/mman.h
    time_gmtoff.h           — currently shims/time.h
  integration/
    esp_http_client_transport.cpp / .hpp
    esp_opentelemetry.cpp
include/
  esp_opentelemetry.hpp     — unchanged public API

The workarounds/ subtree contains everything that exists purely to paper over an upstream deficiency. Each file should carry a one-line comment giving the upstream issue / GCC version / ESP-IDF version that necessitates it, making future removal straightforward.

The integration/ subtree contains code that is deliberately ESP32-specific and is part of the component's defined scope.

No public API changes; CMakeLists.txt and Kconfig are updated to reflect the new paths.

Documentation

The README should gain three explicit sections:

Workarounds

A table listing every workaround, the root cause it addresses, and the upstream component it targets. Example shape:

File Root cause Upstream
workarounds/heap_align.cpp ESP32-S3 heap_caps_aligned_alloc required for alignof(max_align_t)==8; plain malloc returns 4-byte-aligned blocks, corrupting protobuf's TaggedAllocationPolicyPtr protobuf, Abseil
workarounds/posix_shims.c nanosleep missing from newlib; pthread_atfork missing (causes libnosys collision); sysconf(_SC_PAGESIZE) returns -1 (causes Abseil LowLevelAlloc overflow); THREADPTR uninitialised before FreeRTOS scheduler (crashes thread_local accesses during global constructors) Abseil, ESP-IDF newlib
workarounds/absl_varint_bool.h int32_t is long not int on Xtensa; bool/int/pid_t do not match any EncodeVarint overload — ambiguous call on GCC 13.2 Abseil
workarounds/mman.h sys/mman.h absent from newlib; Abseil LowLevelAlloc calls mmap to grow its arena Abseil
workarounds/time_gmtoff.h struct tm in newlib lacks tm_gmtoff; Abseil cctz includes it unconditionally Abseil cctz

ESP-specific integrations

A table of purposeful integrations:

File What it provides
integration/esp_http_client_transport.cpp HttpClientFactory backed by esp_http_client, replacing libcurl for the OTLP/HTTP exporter
integration/esp_opentelemetry.cpp esp_opentelemetry_setup() / esp_opentelemetry_tracer() — ESP-friendly wiring of exporter, processor, resource, and W3C propagator via Kconfig

Tested OTel C++ SDK features

An explicit list of which upstream SDK features have been validated on ESP32 hardware or QEMU, and which are untested / known not to work:

Feature Status Example
OStreamSpanExporter Tested (QEMU) examples/ostream/
SimpleSpanProcessor Tested (QEMU) examples/ostream/
BatchSpanProcessor Tested (hardware, ESP32-S3) examples/batch/
OtlpHttpExporter (JSON) Tested (hardware, ESP32-S3) examples/batch/
W3C TraceContext propagation (inject) Tested (hardware) examples/propagation/
Span attributes (SetAttribute) Tested covered by existing examples
Span events (AddEvent) Untested
OtlpHttpExporter (protobuf) Untested
Metrics API Not integrated
Logs API Not integrated

Per-feature examples

Currently examples/simple/ and examples/batch/ each demonstrate a combination of features rather than isolating one. The goal is one example per feature, named after what it demonstrates:

Example Feature demonstrated Hardware needed
examples/ostream/ OStreamSpanExporter + SimpleSpanProcessor; printout to serial None (QEMU)
examples/batch/ BatchSpanProcessor + OtlpHttpExporter; Wi-Fi setup, PSRAM thread stack Wi-Fi
examples/propagation/ W3C TraceContext inject/extract across an HTTP boundary Wi-Fi

examples/ostream/ is a rename/copy of the current examples/simple/ with no code changes. The remaining examples follow the same pattern and need to be written.

Acceptance criteria

  • src/ is reorganised into workarounds/ and integration/ subtrees; build and CI are unaffected.
  • README contains a Workarounds table with root cause and upstream for each entry.
  • README contains an ESP integrations table.
  • README contains a tested-features table with per-feature example links.
  • Each feature in the tested-features table has a corresponding example under examples/.
  • Examples are self-contained: each has its own CMakeLists.txt, sdkconfig.defaults, and a short README explaining what to observe.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions