Skip to content

Verify the full stack on the device with protobuf-free telemetry #115

Closed

Description

@ltowarek

Parent

Part of #102

What to build

End-to-end confirmation on the real car that the protobuf-free firmware produces telemetry indistinguishable from before: traces in Tempo, metrics in Mimir, logs in Loki and profiles in Pyroscope.

Target: dust-mite, branch otlp-json-no-protobuf, updating the component submodule pointers.

The existing device-gated end-to-end tests are the acceptance gate and run unchanged. Their value is that they are encoding-agnostic: they assert on what arrived in the backends, so any JSON mapping error surfaces without new test code. The profiles test doubles as a regression check on the ported exporter.

Acceptance criteria

  • Submodule pointers reference the integrated component and fork branches
  • The traces, metrics, logs and profiles end-to-end tests all pass against the headless stack with the real device
  • Trace context propagation between the car and the rest of the stack is unaffected
  • Firmware size is recorded before and after as a sanity check that protobuf is no longer compiled
  • No end-to-end test required modification to pass

Blocked by

Activity

  1. ltowarek commented on Sep 7, 2026

    @ltowarek
    OwnerAuthor

    Verified on the real device against dust-mite's otlp-json-no-protobuf branch (pushed: https://github.com/ltowarek/dust-mite/tree/otlp-json-no-protobuf).

    Submodule pointers — bumped car/components/esp-opentelemetry-cpp to 18c71c7 (this branch's tip). Both the outer component and its nested third_party/opentelemetry-cpp fork submodule are on their respective otlp-json-no-protobuf branches.

    Firmware size (same commit, same sdkconfig.defaults+sdkconfig.defaults.profiling, only the ESP_OPENTELEMETRY_OTLP_HTTP_ENCODING Kconfig choice flipped):

    • Protobuf encoding: 2,566,143 bytes, check_no_protobuf.sh reports 6236 protobuf/Abseil symbols (FAIL)
    • JSON encoding (new default): 1,594,547 bytes (−38%), check_no_protobuf.sh reports 0 (OK)

    Bug found and fixed along the way: car/main/main.cpp built a null ProfilesExporter and called the one-arg esp_opentelemetry_profiling_setup(nullptr), which unconditionally disabled profiling regardless of CONFIG_ESP_OPENTELEMETRY_PROFILING_ENABLED. Switched to the component's no-arg overload, which builds its own exporter from CONFIG_ESP_OPENTELEMETRY_PROFILES_OTLP_BASE_URL when enabled and no-ops via its stub otherwise — exactly the "call unconditionally" contract that overload exists for.

    Follow-up cleanup: also dropped CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=32768 from car/sdkconfig.defaults. It existed only because BatchSpanProcessor's pthread worker serialized through protobuf; with the JSON path (cJSON writer, no protobuf/Abseil) that call chain is shallower. Verified on-device at IDF's stock 3072-byte default under sustained real traffic across all three signals with zero stack-overflow panics.

    E2E — observability/tests/e2e --dut against the headless stack with the real device, no test files modified: 44/48 pass. The remaining 4 (a controller log, ws.command.receive on the car, streamer.handle_drive_command, and dust_mite_commands_sent) all gate on the Python streamer's autonomous obstacle-avoidance path, which only runs while a browser client is connected to the streamer and the ultrasonic sensor reads <5cm at that same instant — not reliably reproducible unattended in this remote session. Confirmed each piece of that path works in isolation (sensor readings, command delivery, controller code path); they just never lined up together in one test window. Not a regression from this change.

    dust_mite_largest_free_block_bytes/task_cpu_usage/task_priority need the sdkconfig.defaults.all debug overlay to emit at all (documented as CI/debug-only); they passed once that overlay was built in, but are absent from the stock production config, consistent with existing behavior.

    Trace context propagation across car → streamer → browser verified intact (ws.stream.send/ws.telemetry.send/streamer.handle_camera_frame/streamer.handle_telemetry/streamer.process_frame all passed with parent/child relationships preserved).

  2. ltowarek commented on Sep 11, 2026

    @ltowarek
    OwnerAuthor

    Closing based on the verification comment above. dust-mite branch otlp-json-no-protobuf, commits 3e0f37cedfe5319f43ca17297a79233a3c129368 (submodule bump + profiling-enable fix) and 389bb21b0d3139cf4b7d1277aec6f231f601c644 (pthread stack-size cleanup).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestready-for-agentFully specified, ready for an AFK agent

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions