fix(lfx): bootstrap and flush OTLP telemetry on the lfx run path (#14696)
* fix(lfx): bootstrap and flush OTLP telemetry on the lfx run path `lfx run` executed the flow but exported zero telemetry even with OTEL_EXPORTER_OTLP_ENDPOINT set. The OTEL_* environment variables are read only by bootstrap_application_telemetry(), which lfx serve and the langflow server call at boot and the run command never did. The flow.execute span the graph emits (correctly labelled protocol=lfx.run since #14403) therefore landed on OpenTelemetry's no-op proxy provider and was discarded, so every cron job, CI step or batch worker wired into an APM through `lfx run` was a blind surface with no warning. The run command now installs the providers before the run and flushes them after it, on every exit path: the process is one-shot, the span sits in the batch processor when the run ends, and a failed run's status=error span is the one an operator most needs. The result is echoed before the flush so a stdout consumer is never held behind the export; the flush runs off the event loop as in lfx serve. No-op when no endpoint is set or lfx lacks the otel extra. Tests: a loopback OTLP/HTTP collector drives the real console entry point in a subprocess with the standard env vars and reads the span off the protobuf that arrived (success and failure paths), with OTEL_BSP_SCHEDULE_DELAY pushed to ten minutes so only the exit flush can deliver it; plus an in-process ordering test (bootstrap -> run under protocol=lfx.run -> shutdown) that needs no otel. Both fail on the unpatched tip. The existing in-memory probe keeps proving the protocol binding and now says so. * test(lfx): tighten the run-command telemetry tests per review - Skip the OTLP wire test on the OTLP/HTTP trace exporter rather than the bare opentelemetry namespace, which opentelemetry-api alone satisfies: the exporter import brings the proto module the collector decodes with and the SDK the subprocess needs, or fails and skips. - Record typer.echo as a lifecycle event so the tests assert the actual sequence bootstrap -> run -> echo -> shutdown (success and RunError paths) instead of inferring echo-before-flush from stdout after the fact. * chore: trigger CI
E
Eric Hare committed
f4a11e4c29047341231ab33d83a46913606458c7
Parent: 12efda2
Committed by GitHub <noreply@github.com>
on 8/21/2026, 4:31:26 PM