Skip to content

Configuration timing issue with auto_instrument - options affecting patching behavior are not configurable via initializers #5217

@fabn

Description

@fabn

Description

When using datadog/auto_instrument in a Rails application (as recommended in the documentation), there's a timing issue that makes certain configuration options ineffective when set in config/initializers/datadog.rb.

The Problem

The auto_instrument Railtie runs with before: :load_config_initializers, which means:

  1. auto_instrument triggers patch_all!
  2. Each integration is patched with default settings
  3. Then Rails loads initializers
  4. User's Datadog.configure block runs, but patching has already occurred

This means any configuration option that affects how patching is done (not just runtime behavior) cannot be configured via the initializer.

Affected Options

1. rack integration - request_queuing

# rack/configuration/settings.rb
option :request_queuing do |o|
  o.type :bool
  o.default false
  # No o.env - cannot be configured via environment variable
end

Workaround required:

# Monkey-patch because the option cannot be set before patching
class Datadog::Tracing::Contrib::Rack::Configuration::Settings
  def request_queuing = true
end

2. graphql integration - with_unified_tracer

# graphql/configuration/settings.rb
option :with_unified_tracer do |o|
  o.env Ext::ENV_WITH_UNIFIED_TRACER  # Has ENV var
  o.type :bool
  o.default false
end

This option does have an ENV var (DD_TRACE_GRAPHQL_WITH_UNIFIED_TRACER), so it can be configured before patching occurs. However, this is not immediately obvious from the documentation, which shows configuration via Datadog.configure block:

c.tracing.instrument :graphql, with_unified_tracer: true

This does not work with auto_instrument because patching happens before the initializer runs.

3. diagnostics.startup_logs.enabled

Similarly, this setting:

Datadog.configure do |c|
  c.diagnostics.startup_logs.enabled = false
end

Has no effect when using auto_instrument because startup logs are emitted before the initializer runs. The only way to disable them is via DD_TRACE_STARTUP_LOGS=false in the shell environment (note: using dotenv/.env files doesn't work either, as those are also loaded after auto_instrument runs).

Questions

  1. Is this timing behavior intentional? The Railtie comment says "user supplied config will take precedence", but this is only true for runtime configuration, not patching-time configuration.

  2. For options that affect patching behavior, should ENV vars be added? For example, request_queuing has no ENV var, making it impossible to configure properly with auto_instrument.

  3. If we omit require: 'datadog/auto_instrument' from the Gemfile to gain control over configuration timing, do we need to manually instrument every integration? For example:

    Datadog.configure do |c|
      c.tracing.instrument :rails
      c.tracing.instrument :rack, request_queuing: true
      c.tracing.instrument :active_record
      c.tracing.instrument :redis
      c.tracing.instrument :sidekiq
      c.tracing.instrument :graphql, with_unified_tracer: true
      # ... every other integration we use?
    end

    Or is there a way to trigger auto-instrumentation after our configuration is set?

  4. Could the documentation be clearer about this limitation? Currently, the docs show configuration via Datadog.configure blocks without mentioning that certain options must be set via ENV vars when using auto_instrument.

Environment

  • datadog gem version: 2.x
  • Ruby version: 3.2.2
  • Rails version: 7.0

Expected Behavior

Configuration set in config/initializers/datadog.rb should be respected for all options, including those that affect patching behavior.

Actual Behavior

Options that affect patching behavior are ignored because patching occurs before initializers run.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions