dd-trace-rb icon indicating copy to clipboard operation
dd-trace-rb copied to clipboard

Configure `active_record` as part of `rails`

Open yijia-zhan opened this issue 6 years ago • 13 comments

With

Datadog.configure do |c|
  c.tracer env: Rails.env
  c.use :rails, service_name: "myapp-rails"
end

I see the following services instrumented in Datadog:

- active_record
- myapp-rails
- myapp-rails-cache
- myapp-rails-postgres

This is ok for one service, but I have multiple Rails apps (all using ActiveRecord) that I want to instrument, so I need to differentiate active_record from one app from another.

I understand there's c.use :active_record and c.use :rails, but I'm not sure why active_record is configured separately from rails. What I want is to have:

- myapp-active_record
- myapp-rails
- myapp-rails-cache
- myapp-rails-postgres

Is there a way to achieve this? I read this issue https://github.com/DataDog/dd-trace-rb/issues/574 and this PR https://github.com/DataDog/dd-trace-rb/pull/450, and it seems that the following is exactly what I need:

Datadog.configure do |c|
  c.use :rails do |rails|
    rails.service_name = 'myapp'
    
    rails.active_record do |active_record|
      active_record.orm_service_name = 'myapp-active_record'
    end
  end
end

But when I tried it I got a NoMethodError:

undefined method `active_record' for #<Datadog::Contrib::Rails::Configuration::Settings:0x00007ff12073d9d0> (NoMethodError)

I'm using 0.24.0.

yijia-zhan avatar May 24 '19 00:05 yijia-zhan

If I do the following:

Datadog.configure do |c|
  c.tracer env: Rails.env
  c.use :active_record, orm_service_name: "myapp-active_record"
  c.use :rails, service_name: "myapp-rails"
end

I seem to be able to get what I want. Just want to clarify, is this going to "double register" active_record? Does the order of c.use :active_record and c.use :rails matter?

yijia-zhan avatar May 24 '19 05:05 yijia-zhan

@yijia-zhan don't worry, it won't double the instrumentation; if you ever call use twice, it will only apply the new settings the second time.

Sorry about the confusion of looking at that other PR. We intend to implement that rails.active_record block configuration style, however, we aren't quite ready for it just yet. Hopefully in the near future that syntax will work just fine.

delner avatar May 24 '19 15:05 delner

Thanks @delner! Just want to double confirm on whether the order of c.use :active_record and c.use :rails matters.

If I do:

Datadog.configure do |c|
  c.use :active_record, service_name: "test", orm_service_name: "myapp-active_record"
  c.use :rails, service_name: "myapp-rails"
end

Would the test service name for active_record be overridden by the the one specified as part of rails? (https://github.com/DataDog/dd-trace-rb/blob/master/lib/ddtrace/contrib/rails/framework.rb#L57-L65)

On the other hand, if I do not specify a service_name for c.use :active_record, would it default to the one specified as part of rails?

yijia-zhan avatar May 24 '19 16:05 yijia-zhan

It's a great question, and largely depends on the load order of your application. I presume this configuration is in an initializer. Rails configuration is setup to apply after the application is fully initialized, so there's a decent chance that c.use :rails will override c.use :active_record with its own service name, regardless of order. I would have to test this to verify.

Obviously that's not ideal behavior (part of the reason we wanted to introduce that block syntax), but I think the following should work as a work around:

Datadog.configure do |c|
  c.use :active_record, orm_service_name: "myapp-active_record"
  c.use :rails, service_name: "myapp-rails", database_service: "test"
end

The Rails integration, when it reconfigures ActiveRecord will pass database_name as service_name to ActiveRecord. Give that a shot, see if that works for you.

delner avatar May 24 '19 17:05 delner

Thanks @delner. Will test out and report back.

yijia-zhan avatar May 24 '19 17:05 yijia-zhan

Hey @yijia-zhan, just wanted to let you know we're in the process of implementing the block syntax for Rails, as you shared in your original post. I'll keep you posted on any developments!

delner avatar Sep 05 '19 21:09 delner

This is very good to know! Thank you for the update @delner !

yijia-zhan avatar Sep 05 '19 22:09 yijia-zhan

Still a WIP but the PR for this is here: #810

delner avatar Sep 06 '19 18:09 delner

We ran into this today, I found setting another after_initialize block and setting the orm_service_name directly on the active_record integration configuration appears to look identical to defining the two integrations and having one override the other.

# frozen_string_literal: true

require "ddtrace"

Datadog.configure do |c|
  c.use :rails, service_name: "app-web", cache_service: "app-cache", database_service: "app-postgres"
end

Rails.application.config.after_initialize do
  # Workaround for :rails not setting :orm_service_name on :active_record https://github.com/DataDog/dd-trace-rb/issues/764
  if (active_record_integration = Datadog.configuration.instrumented_integrations[:active_record])
    active_record_integration.configuration[:orm_service_name] = "app-active_record"
  end
end

caius avatar Apr 14 '21 14:04 caius

How does all this work with v1 whereby orm_service_name has been removed? What should folks upgrading do in this case? Thank you!

agirlnamedsophia avatar May 17 '22 20:05 agirlnamedsophia

👋 @agirlnamedsophia, orm_service_name only affected active_record.instantiation spans. We removed this configuration because ActiveRecord object instantiation is part of the host application workload, thus in v1.0.0 the service for active_record.instantiation is the same as the global application DD_SERVICE (or c.service = ...).

Let us know if you have a specific use case that needed orm_service_name before that doesn't work anymore in v1.0.0. I looked it up and the active_record.instantiation spans will generate standalone metrics you can monitor and graph on, as they are considered "measured", as well as having the option to configure analytics_enabled: true if you need them analyzed.

marcotc avatar May 17 '22 22:05 marcotc

Yes, as @marcotc said, in theory you simply remove orm_service_name and that's it.

You shouldn't really expect any major changes to occur beyond that, especially as it concerns the database spans themselves.

delner avatar May 19 '22 09:05 delner

Thanks @marcotc and @delner for responding! We removed orm_service_name and I helped the engineers see how to find those spans with the operation dropdown. We are good to go!

agirlnamedsophia avatar May 19 '22 19:05 agirlnamedsophia

Hi @delner. Is the active_record supposed to be used on all the integrations? I see that Rails is using it, but Shoryuken is not reporting any active record instantiations, only database queries.

I have something like the following

Datadog.configure do |c|
  c.tracing.instrument :rails,         service_name: "#{prefix}Rails", middleware_names: true
  c.tracing.instrument :rack,          service_name: "#{prefix}Rails", request_queuing: true, web_service_name: "#{prefix}nginx"
  c.tracing.instrument :active_record, service_name: "#{prefix}ActiveRecord"
  c.tracing.instrument :shoryuken,     service_name: "#{prefix}Shoryuken"
  ...
end

frsantos avatar Mar 16 '23 13:03 frsantos