Skip to content

Add Data Streams Monitoring support to ActiveJob#5961

Open
dasch wants to merge 4 commits into
DataDog:masterfrom
dasch:dasch-active-job-dsm
Open

Add Data Streams Monitoring support to ActiveJob#5961
dasch wants to merge 4 commits into
DataDog:masterfrom
dasch:dasch-active-job-dsm

Conversation

@dasch

@dasch dasch commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Adds Data Streams Monitoring (DSM) support to the ActiveJob integration. When DSM is enabled, the integration sets a produce checkpoint on enqueue and a consume checkpoint on perform, and propagates the DSM pathway context from the enqueueing process to the worker process.

The pathway context is carried through ActiveJob::Core#serialize/#deserialize: the serialized job hash is the payload every queue adapter persists and transmits, and the only thing that actually crosses the enqueue → perform process boundary. The ActiveSupport notification events (enqueue.active_job / perform.active_job) only expose the in-memory job object, so they cannot carry context to the worker. Hooking serialize/deserialize works uniformly across all queue adapters (Sidekiq, SQS, Resque, inline, …) and every supported Rails version (4.2+).

Motivation:

ActiveJob is a common messaging boundary in Rails apps, but DSM could not trace messages through it. This connects the enqueue and perform sides into a single pathway so latency and throughput across job queues show up in Data Streams Monitoring.

Change log entry

Yes. Data Streams Monitoring now traces messages through ActiveJob enqueue and perform.

Additional Notes:

DSM checkpoints are tagged type:active_job regardless of the underlying adapter, keeping the pathway self-documenting and consistent. Checkpoints are set only when Datadog::DataStreams.enabled?, mirroring the existing Kafka/WaterDrop integrations. Any error raised while setting a checkpoint is swallowed and logged at debug level, so DSM can never break a customer's job from enqueuing or running.

Closes #5976

How to test the change?

Unit tests added in spec/datadog/tracing/contrib/rails/rails_active_job_spec.rb covering: produce checkpoint + pathway injection on serialize, consume checkpoint + pathway extraction on deserialize, no-ops when DSM is disabled, and that a raising checkpoint is swallowed so serialize/deserialize still succeed. Verified green on Ruby 3.2 / Rails 6.1 and Ruby 3.4 / Rails 8.

Inject and extract the DSM pathway context through the serialized job
payload so produce (enqueue) and consume (perform) checkpoints connect
across the enqueue/perform process boundary, regardless of queue adapter.
@dasch dasch marked this pull request as ready for review June 30, 2026 08:02
@dasch dasch requested review from a team as code owners June 30, 2026 08:02
@dasch dasch requested review from vpellan and wantsui June 30, 2026 08:02

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f37bfbf454

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread lib/datadog/tracing/contrib/active_job/data_streams.rb Outdated

@Strech Strech left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have few minor suggestions to reduce nesting and increase simplicity. Of course Codex brought a valid point too

Comment thread lib/datadog/tracing/contrib/active_job/data_streams.rb Outdated
Comment thread lib/datadog/tracing/contrib/active_job/data_streams.rb Outdated
Comment thread lib/datadog/tracing/contrib/active_job/data_streams.rb Outdated
Comment thread lib/datadog/tracing/contrib/active_job/patcher.rb Outdated
Comment thread sig/datadog/tracing/contrib/active_job/data_streams.rbs Outdated
@dasch

dasch commented Jun 30, 2026

Copy link
Copy Markdown
Contributor Author

Thanks! I'll get those fixed.

Require datadog/data_streams so the enabled? facade is defined under the
tracing-only entrypoint, avoiding a NoMethodError on every serialize.
Collapse the two single-method patches into one DataStreams module and
add a regression test for the unconfigured-DSM path.
@dasch

dasch commented Jun 30, 2026

Copy link
Copy Markdown
Contributor Author

@Strech can you approve the CI run?

@vpellan vpellan left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey! Thanks for your contribution! As with the racecar PR, I'll also ask for a review from the DSM team

Comment thread sig/datadog/tracing/contrib/active_job/data_streams.rbs Outdated
Comment thread sig/datadog/tracing/contrib/active_job/patcher.rbs Outdated
@vpellan vpellan added the community Was opened by a community member label Jul 1, 2026
@Strech

Strech commented Jul 1, 2026

Copy link
Copy Markdown
Member

@dasch Done ✅

@datadog-official

This comment has been minimized.

ActiveJob 4.2 deserializes jobs via a class method, not the instance
method, so a prepended instance deserialize has no super to call and
cannot receive the queue. Gate DSM injection to ActiveJob 5.0+ and skip
the DSM specs below that version.

Replace untyped with any in the RBS and add a module self-type so steep
can resolve queue_name on the host job class.
@dasch

dasch commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Heads up on a behavioral note beyond the RBS fixes: CI caught that ActiveJob 4.2 (Rails 4) deserializes jobs through a class method, not the instance method, so a prepended instance deserialize has no super and never sees the queue. I've gated DSM injection to ActiveJob 5.0+ (mirroring how inject_log_correlation already version-checks) and the DSM specs skip below that. Enqueue/perform tracing is unaffected on 4.2; only the DSM pathway propagation is 5.0+. Pushed in 254fd79.

@dasch

dasch commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

🤖 CI note for maintainers — the two red checks are a fork-PR limitation, not the diff.

This PR is from a fork (dasch:dasch-active-job-dsm). Two checks fail as a direct consequence, and neither reflects a problem with the change:

  • Check change log entry (check) fails immediately at the DataDog/dd-octo-sts-action step with Missing required environment variables; have you set 'id-token: write' in your workflow permissions?. Fork PRs don't receive id-token: write, so the action can't mint the OIDC token and the job errors out before it ever evaluates the changelog. (The changelog entry itself is present — see the "Change log entry" section in the PR description.)
  • Check Pull Request CI Status (all-jobs-are-green) fails only because it aggregates the check job above.

The check failure also cascades into cancelling the Unit Tests matrix — those jobs are cancelled, not failed (0 failures across all Ruby versions).

Everything that does run is green, including the two jobs that caught real issues in the previous round:

  • Static Analysis (steep) — the RBS self-type fix resolved the earlier typecheck failure.
  • Unit Tests — Ruby 2.5 / build & test (standard) [4] — the exact shard that previously failed on ActiveJob 4.2; the 5.0+ version gate fixes it.
  • ✅ Test macOS, Test Nix, CodeQL, YJIT, Integration Apps, System Tests, Build gem.

To get a fully green run, a maintainer would need to re-run CI from a branch on DataDog/dd-trace-rb (where id-token: write is available), since fork PRs can't access it. Happy to push the branch directly if someone can grant access.

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

Labels

community Was opened by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants