Skip to content

feat: add Faust opentelemetry instrumentation#4829

Draft
wbarnha wants to merge 2 commits into
open-telemetry:mainfrom
wbarnha:claude/faust-opentelemetry-instrumentation-reor7a
Draft

feat: add Faust opentelemetry instrumentation#4829
wbarnha wants to merge 2 commits into
open-telemetry:mainfrom
wbarnha:claude/faust-opentelemetry-instrumentation-reor7a

Conversation

@wbarnha

@wbarnha wbarnha commented Jul 17, 2026

Copy link
Copy Markdown

Description

Adds a new instrumentation package, opentelemetry-instrumentation-faust, for
faust-streaming (Kafka stream processing).

The instrumentation is built on faust's Sensor API rather than patching library
internals (both the pure-Python and compiled Cython stream paths invoke sensors):

  • on_send_initiated/completed/error record a {topic} send PRODUCER span for every
    message published to Kafka and inject the trace context into the message headers.
  • on_stream_event_in/out record a {topic} process CONSUMER span around each event
    processed by a stream/agent, parented from the context extracted from the incoming
    message headers. The hooks run in the agent's task context, so the process span is
    current inside the agent body and sends made while processing nest under it.
  • The only wrapt patch is faust.App.__init__, used to auto-register the sensor on new
    apps; FaustInstrumentor.instrument_app()/uninstrument_app() handle pre-existing
    apps. Optional produce_hook/process_hook callbacks are supported.

Known gaps/concerns:

  • The package is not in the pyright include list: faust/mode are effectively untyped
    and cascade Unknown types that can't be fixed without pervasive casts.
  • Producer spans for send_soon() (buffered, flushed from the producer service task)
    may not parent under the caller's span since publishing happens in another task.

Note: Draft for now — I'll be back to test this soon.

Type of change

  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

  • tox -e py311-test-instrumentation-faust — 11 tests covering: instrument/uninstrument
    API, sensor registration, producer span attributes + header injection (validated
    against semconv attribute names and value types), partition attribute, send error
    status + exception event, end-to-end stream processing through real faust
    channels/streams (exercises the compiled Cython iterator), trace continuation from
    producer to process to nested send, hooks, and no-spans-after-uninstrument.
  • tox -e lint-instrumentation-faust (pylint 10/10), ruff, tox -e typecheck, docs
    build for the new page, license header/README/codespell checks.

Does This PR Require a Core Repo Change?

  • No.

Checklist:

  • Followed the style guidelines of this project
  • Changelogs have been updated
  • Unit tests have been added
  • Documentation has been updated

claude added 2 commits July 17, 2026 01:43
Instrument faust-streaming applications using faust's sensor API:

- A producer span is recorded for every message sent to a Kafka topic
  and the span context is injected into the message headers.
- A consumer span is recorded around every event processed by a stream
  (agent), continuing the trace extracted from the incoming message
  headers, and made current while the event is processed.

Apps created after FaustInstrumentor().instrument() are instrumented
automatically by wrapping faust.App.__init__; existing apps can be
instrumented with instrument_app()/uninstrument_app().

Assisted-by: Claude Fable 5

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NoKAa2xLqorEdDQKh77E8Q
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NoKAa2xLqorEdDQKh77E8Q
@linux-foundation-easycla

Copy link
Copy Markdown

CLA Missing ID

One or more co-authors of this pull request were not found. You must specify co-authors in commit message trailer via:

Co-authored-by: name <email>

Supported Co-authored-by: formats include:

  1. Anything <id+login@users.noreply.github.com> - it will locate your GitHub user by id part.
  2. Anything <login@users.noreply.github.com> - it will locate your GitHub user by login part.
  3. Anything <public-email> - it will locate your GitHub user by public-email part. Note that this email must be made public on Github.
  4. Anything <other-email> - it will locate your GitHub user by other-email part but only if that email was used before for any other CLA as a main commit author.
  5. login <any-valid-email> - it will locate your GitHub user by login part, note that login part must be at least 3 characters long.

Alternatively, if the co-author should not be included, remove the Co-authored-by: line from the commit message.

Please update your commit message(s) by doing git commit --amend and then git push [--force] and then request re-running CLA check via commenting on this pull request:

/easycla

@wbarnha wbarnha changed the title Claude/faust opentelemetry instrumentation reor7a feat: add Faust opentelemetry instrumentation reor7a Jul 17, 2026
@wbarnha wbarnha changed the title feat: add Faust opentelemetry instrumentation reor7a feat: add Faust opentelemetry instrumentation Jul 17, 2026
@wbarnha

wbarnha commented Jul 17, 2026

Copy link
Copy Markdown
Author

I’ll be back soon to test this further!

@xrmx

xrmx commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

@wbarnha since you seem to be the upstream as well, why not adding native opentelemetry support to faust itself?

@wbarnha

wbarnha commented Jul 18, 2026

Copy link
Copy Markdown
Author

My motivation for this PR stems from dependency management. The otel packages this needs are 0.x releases that are version-locked to each other and to specific api/sdk versions, and they break between releases (the messaging attributes are still incubating and keep getting renamed). If faust depended on them directly, every otel release train would couple to a faust release, and anyone pinning a different otel version than faust would hit resolver conflicts. Faust's dependency graph is heavy enough as it is. I get plenty of install-conflict issues without adding that.

The most faust could safely carry natively is an extra depending only on opentelemetry-api, but then I'd be hardcoding semconv attribute names with nobody checking them against the spec. Keeping it in contrib means the version coupling lives in the repo whose release process is actually built to manage it, and faust ships zero new dependencies.

I'm going to tinker with faust to see if I'm wrong about this.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants