Skip to content

add rails.application to process tags when available#5468

Merged
wantsui merged 22 commits intomasterfrom
add-application-name-rails-process-tags
Apr 1, 2026
Merged

add rails.application to process tags when available#5468
wantsui merged 22 commits intomasterfrom
add-application-name-rails-process-tags

Conversation

@wantsui
Copy link
Copy Markdown
Collaborator

@wantsui wantsui commented Mar 17, 2026

What does this PR do?

Adds the Rails application name to the process tags list to give Rails users a way to differentiate the application, listed as rails.application. However, we need this information on ALL products (DI, Profiling, Tracing) regardless of whether tracing is enabled so that service renaming can occur consistently.

Attempt 1: This PR also adds a "recompute" functionality in the process.rb because it turns out that Rails apps don't have access to their name until AFTER initialization. I found this out because I up a real Rails app and noticed the process tags with the default Rails utils was returning no name.

Update: the approach above failed so it's crossed out now because it turns out that profiles never run through the after_initialize logic if someone doesn't use tracing, so now there's a new approach.

  1. lib/datadog/core/environment/process.rb has been updated to allow setting self.rails_application_name=(name) anywhere else in code
  2. lib/datadog/core/configuration/components.rb has been updated to load in lib/datadog/core/contrib/rails/railtie.rb when a Rails app starts
  3. lib/datadog/core/contrib/rails/railtie.rb is used to add after_initialize logic for any product when a Rails app is active. Within this we update the Rails application name.

Now we'll recompute the process tags after Rails initialization, and here's an example of how it will appear in the Profiles under "Runtime Info":
image

Motivation:

This came about from an investigation with @marcotc and @raphaelgavache into the way the default Rails Dockerfile stores apps. (Anything using that base Dockerfile will store the app in the same app folder, so the existing process tags are not unique enough).

Change log entry

Yes. Add rails.application to the process tags.

Additional Notes:

This reuses the existing Rails utils and updates the process tags, but the utils had to be refactored. You may ask, "why"?

Reason 1: CI was failing on not being able to call underscore on a nil

Example: https://github.com/DataDog/dd-trace-rb/actions/runs/23263729755/job/67639506905?pr=5468

#14 2.338 rails aborted!
#14 2.339 NoMethodError: undefined method `underscore' for nil:NilClass
#14 2.339 /usr/local/bundle/gems/datadog-2.30.0/lib/datadog/core/contrib/rails/utils.rb:11:in `app_name'
#14 2.339 /usr/local/bundle/gems/datadog-2.30.0/lib/datadog/core/environment/process.rb:90:in `rails_application'
#14 2.339 /usr/local/bundle/gems/datadog-2.30.0/lib/datadog/core/environment/process.rb:39:in `tags'
#14 2.339 /usr/local/bundle/gems/datadog-2.30.0/lib/datadog/core/environment/process.rb:19:in `serialized'
#14 2.339 /usr/local/bundle/gems/datadog-2.30.0/lib/datadog/core/crashtracking/tag_builder.rb:18:in `call'
#14 2.339 /usr/local/bundle/gems/datadog-2.30.0/lib/datadog/core/crashtracking/component.rb:67:in `latest_tag

I updated the utils to skip trying to do call underscore if the parent namespace is missing.

Reason 2: But then I ran into an exception error because sometimes the CI doesn't have access to the app name yet?

To deal with this, some error handling was added and tests.

Example run: https://github.com/DataDog/dd-trace-rb/actions/runs/23265763535/job/67646150038?pr=5468


Failures:

  1) Datadog::AppSec::Contrib::Rails::Patcher.patch :after_routes_loaded hook when error occurs while getting application routes logs the error and reports it via telemetry
     Failure/Error: application_name = ::Rails.application.class.public_send(namespace_method)

     StandardError:
       StandardError
     # ./lib/datadog/core/contrib/rails/utils.rb:11:in `app_name'
     # ./lib/datadog/core/environment/process.rb:90:in `rails_application'
     # ./lib/datadog/core/environment/process.rb:39:in `tags'
     # ./lib/datadog/core/environment/process.rb:19:in `serialized'
     # ./lib/datadog/core/crashtracking/tag_builder.rb:18:in `call'
     # ./lib/datadog/core/crashtracking/component.rb:67:in `latest_tags'
     # ./lib/datadog/core/crashtracking/component.rb:20:in `build'
     # ./lib/datadog/core/configuration/components.rb:85:in `build_crashtracker'
     # ./lib/datadog/core/configuration/components.rb:153:in `initialize'
     # ./lib/datadog/core/configuration.rb:259:in `new'
     # ./lib/datadog/core/configuration.rb:259:in `build_components'
     # ./lib/datadog/core/configuration.rb:204:in `block in components'
     # ./lib/datadog/core/configuration.rb:238:in `block in safely_synchronize'
     # ./lib/datadog/core/configuration.rb:237:in `synchronize'
     # ./lib/datadog/core/configuration.rb:237:in `safely_synchronize'
     # ./lib/datadog/core/configuration.rb:200:in `components'
     # ./lib/datadog/tracing.rb:178:in `components'
     # ./lib/datadog/tracing.rb:182:in `tracer'
     # ./spec/datadog/tracing/contrib/support/tracer_helpers.rb:16:in `tracer'
     # ./spec/datadog/tracing/contrib/support/tracer_helpers.rb:102:in `block (2 levels) in <module:TracerHelpers>'
     # ./spec/datadog/tracing/contrib/support/tracer_helpers.rb:96:in `block (2 levels) in <module:TracerHelpers>'
     # ./spec/spec_helper.rb:274:in `block (2 levels) in <top (required)>'
     # ./spec/spec_helper.rb:154:in `block (2 levels) in <top (required)>'
     # /usr/local/bundle/gems/webmock-3.25.1/lib/webmock/rspec.rb:39:in `block (2 levels) in <top (required)>'
     # /usr/local/bundle/gems/rspec-wait-0.0.10/lib/rspec/wait.rb:47:in `block (2 levels) in <top (required)>'
     # ./spec/support/execute_in_fork.rb:32:in `run'

Finished in 2 minutes 44.9 seconds (files took 1.65 seconds to load)
204 examples, 1 failure

Failed examples:

rspec ./spec/datadog/appsec/contrib/rails/patcher_spec.rb:59 # Datadog::AppSec::Contrib::Rails::Patcher.patch :after_routes_loaded hook when error occurs while getting application routes logs the error and reports it via telemetry

Both errors showed that there were some Rails/CI specific ordering that prevent the Rails app name from being obtained.

How to test the change?

I tested with a Rails 8 that I sent data to the backend for.

TODOS

@wantsui wantsui requested a review from marcotc March 17, 2026 22:06
@github-actions github-actions bot added the core Involves Datadog core libraries label Mar 17, 2026
@datadog-datadog-prod-us1
Copy link
Copy Markdown
Contributor

datadog-datadog-prod-us1 bot commented Mar 17, 2026

✅ Tests

🎉 All green!

❄️ No new flaky tests detected
🧪 All tests passed

🎯 Code Coverage (details)
Patch Coverage: 95.24%
Overall Coverage: 95.36% (+0.01%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: a2c819d | Docs | Datadog PR Page | Was this helpful? React with 👍/👎 or give us feedback!

@wantsui wantsui added the AI Generated Largely based on code generated by an AI or LLM. This label is the same across all dd-trace-* repos label Mar 18, 2026
@pr-commenter
Copy link
Copy Markdown

pr-commenter bot commented Mar 18, 2026

Benchmarks

Benchmark execution time: 2026-03-25 21:44:54

Comparing candidate commit ba91576 in PR branch add-application-name-rails-process-tags with baseline commit 78f9609 in branch master.

Found 0 performance improvements and 0 performance regressions! Performance is the same for 46 metrics, 0 unstable metrics.

Explanation

This is an A/B test comparing a candidate commit's performance against that of a baseline commit. Performance changes are noted in the tables below as:

  • 🟩 = significantly better candidate vs. baseline
  • 🟥 = significantly worse candidate vs. baseline

We compute a confidence interval (CI) over the relative difference of means between metrics from the candidate and baseline commits, considering the baseline as the reference.

If the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD), the change is considered significant.

Feel free to reach out to #apm-benchmarking-platform on Slack if you have any questions.

More details about the CI and significant changes

You can imagine this CI as a range of values that is likely to contain the true difference of means between the candidate and baseline commits.

CIs of the difference of means are often centered around 0%, because often changes are not that big:

---------------------------------(------|---^--------)-------------------------------->
                              -0.6%    0%  0.3%     +1.2%
                                 |          |        |
         lower bound of the CI --'          |        |
sample mean (center of the CI) -------------'        |
         upper bound of the CI ----------------------'

As described above, a change is considered significant if the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD).

For instance, for an execution time metric, this confidence interval indicates a significantly worse performance:

----------------------------------------|---------|---(---------^---------)---------->
                                       0%        1%  1.3%      2.2%      3.1%
                                                  |   |         |         |
       significant impact threshold --------------'   |         |         |
                      lower bound of CI --------------'         |         |
       sample mean (center of the CI) --------------------------'         |
                      upper bound of CI ----------------------------------'

@github-actions github-actions bot added integrations Involves tracing integrations tracing labels Mar 19, 2026
@wantsui wantsui requested a review from marcotc March 19, 2026 23:20
@wantsui wantsui marked this pull request as ready for review March 20, 2026 13:07
@wantsui wantsui requested review from a team as code owners March 20, 2026 13:07
@wantsui wantsui requested a review from vpellan March 20, 2026 13:07
Comment thread lib/datadog/core/contrib/rails/utils.rb Outdated
Comment thread lib/datadog/core/contrib/rails/utils.rb Outdated
Comment thread lib/datadog/core/environment/process.rb Outdated
Comment thread spec/datadog/core/contrib/rails/utils_spec.rb Outdated
Comment thread spec/datadog/core/contrib/rails/utils_spec.rb Outdated
Copy link
Copy Markdown
Member

@p-datadog p-datadog left a comment

Choose a reason for hiding this comment

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

Nice work overall.

That said — it feels like process.rb picking up a Rails dependency might work against the grain of Core. Right now Process is entirely framework-agnostic (just $0, Dir.pwd, File), and the require of Core::Contrib::Rails is the first thing to break that. Left a thought inline.

Comment thread lib/datadog/core/environment/process.rb Outdated
Comment thread lib/datadog/core/contrib/rails/utils.rb Outdated
wantsui added 2 commits March 24, 2026 15:08
… other features like profiling only apps can get the rails app name, remove the interaction of rails specific logic inside the process tags logic and clean up tests
@wantsui wantsui requested a review from marcotc March 24, 2026 20:50
Copy link
Copy Markdown
Member

@raphaelgavache raphaelgavache left a comment

Choose a reason for hiding this comment

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

very nice

Comment thread spec/datadog/core/contrib/rails/utils_spec.rb
@wantsui
Copy link
Copy Markdown
Collaborator Author

wantsui commented Mar 25, 2026

Note: I just created #5504 as a follow up to this PR because ProcessDiscovery publishes before the rails app is initialized.

Copy link
Copy Markdown
Member

@p-datadog p-datadog left a comment

Choose a reason for hiding this comment

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

👍 Really like where this landed. The setter on Process is exactly the right decoupling — and the core-level Railtie is a really nice touch. That solves the profiling-only and AppSec-only cases marcotc raised, which the patcher approach wouldn't have covered. Clean solution all around.

Two small suggestions inline.

Comment thread lib/datadog/core/contrib/rails/utils.rb Outdated
Comment thread spec/datadog/core/contrib/rails/utils_spec.rb
@wantsui wantsui merged commit b178501 into master Apr 1, 2026
627 checks passed
@wantsui wantsui deleted the add-application-name-rails-process-tags branch April 1, 2026 22:08
@github-actions github-actions bot added this to the 2.31.0 milestone Apr 1, 2026
@y9v y9v mentioned this pull request Apr 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI Generated Largely based on code generated by an AI or LLM. This label is the same across all dd-trace-* repos core Involves Datadog core libraries integrations Involves tracing integrations tracing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants