Task · OPN-0049

Ship the exporter's own logs through its OTLP logs pipeline (opt-in)

Description

Own slog output goes only to stderr; the transport, resource attributes and delivery accounting already exist (internal/telemetry/, internal/logship/sink_otlp.go). Opt-in flag routes the exporter’s own log records into the same OTLP sink so the 03:00 error line lands in Loki next to the firewall logs. Guard against feedback loops (sink errors logging into the sink).

Acceptance Criteria

Definition of Done

Implementation Plan

Wave 2 L6: add an opt-in exporter self-log path through the existing OTLP sink with bounded recursion protection, tests, documentation, and an exact root wiring request.

Implementation Notes

Wave 2 implementation is complete: default-off self-log forwarding preserves stderr, uses the bounded OTLP pipeline, fixes resource identity, and breaks sink-diagnostic recursion. Focused tests, full indexed just check, and L13 review passed. Landing is blocked solely by two CodeRabbit connection failures with no complete event. Preserved in codex/wip-wave2-coderabbit-blocked.patch; resume by applying it, rerunning the gate, and obtaining a completed CodeRabbit review.

Landed on main in a482f637. Opt-in, default off, correct resource attributes, documented.

CHANGED AT LANDING, and it changes how AC2 is satisfied: the wave 2 implementation bounded sink-failure recursion with a forwarding boolean on the shared handler state. That flag is process-wide, so it cannot distinguish re-entry from concurrency. TestSelfLogHandlerDeliversConcurrentRecords was written against the old code and delivered 1 of 8 records: with 65 collector pollers and the push receivers all logging, self-log records were being dropped silently and without any drop accounting.

The flag is removed. Recursion is prevented structurally instead, which it already was: pipeline.go:109 constructs the pipeline with DiagnosticLogger, a one-way path that bypasses this handler entirely, and TestSelfLogDiagnosticLoggerCannotReenterSink pins that. The remaining requirement is a contract, documented at Bind: the enqueue callback must not log through this handler. TestSelfLogHandlerSinkFailureRecursionIsBounded was removed because it asserted the behaviour of a callback that deliberately violates that contract; it is replaced by the concurrency test, which was verified to fail 1-of-8 against the old guard.

Found by CodeRabbit at severity major. Live OTLP delivery was not exercised.

Wave 4 OPN-0060 live-proof disposition: NOT PROVEN. The testbed became ready, but its API credentials were unavailable to the mandated local process and exist only in the protected CI environment; CI was forbidden as a substitute. No exporter delivery run, Loki query, or on-wire result occurred for this source. Resume through OPN-0060 after an authorised local testbed credential launcher exists.

View the source file on GitHub