Skip to content

Commit 24da35d

Browse files
committed
DI railtie
1 parent bb43112 commit 24da35d

File tree

10 files changed

+104
-16
lines changed

10 files changed

+104
-16
lines changed

Steepfile

+1
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ target :datadog do
145145
ignore 'lib/datadog/core/workers/queue.rb'
146146
ignore 'lib/datadog/core/workers/runtime_metrics.rb'
147147
ignore 'lib/datadog/di/configuration/settings.rb'
148+
ignore 'lib/datadog/di/contrib/railtie.rb'
148149
ignore 'lib/datadog/kit/appsec/events.rb' # disabled because of https://github.com/soutaro/steep/issues/701
149150
ignore 'lib/datadog/kit/identity.rb' # disabled because of https://github.com/soutaro/steep/issues/701
150151
ignore 'lib/datadog/opentelemetry.rb'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class DiController < ApplicationController
2+
def ar_serializer
3+
test = Test.create!
4+
render json: Datadog::DI.component.serializer.serialize_value(test)
5+
end
6+
end

integration/apps/rails-seven/config/initializers/datadog.rb

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
require 'datadog/statsd'
22
require 'datadog'
3-
require 'datadog/appsec'
43

54
Datadog.configure do |c|
65
c.env = 'integration'
@@ -26,4 +25,8 @@
2625
# Reconfigure transport to write pprof to file
2726
c.profiling.exporter.transport = Datadog::DemoEnv.profiler_file_transport
2827
end
28+
29+
c.remote.enabled = true
30+
c.dynamic_instrumentation.enabled = true
31+
c.dynamic_instrumentation.internal.development = true
2932
end

integration/apps/rails-seven/config/routes.rb

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
get 'basic/fibonacci', to: 'basic#fibonacci'
1111
get 'basic/boom', to: 'basic#boom'
1212

13+
get 'di/ar_serializer', to: 'di#ar_serializer'
14+
1315
# Job test scenarios
1416
post 'jobs', to: 'jobs#create'
1517
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
require 'spec_helper'
2+
require 'json'
3+
4+
RSpec.describe 'Dynamic Instrumentation' do
5+
include_context 'integration test'
6+
7+
describe 'ActiveRecord integration' do
8+
subject { JSON.parse(get('di/ar_serializer').body) }
9+
10+
it 'is loaded' do
11+
# If AR integration is loaded, this output will be the result of
12+
# the custom serializer.
13+
# If AR integration is not loaded, the output here will have a bunch of
14+
# internal AR fields but not the attributes themselves.
15+
expect(subject).to match(
16+
{"type"=>"Test",
17+
"entries"=>
18+
[[{"type"=>"Symbol", "value"=>"attributes"},
19+
{"type"=>"Hash",
20+
"entries"=>
21+
[[{"type"=>"String", "value"=>"id"}, {"type"=>"Integer", "value"=>String}],
22+
[{"type"=>"String", "value"=>"version"}, {"type"=>"NilClass", "isNull"=>true}],
23+
[{"type"=>"String", "value"=>"data"}, {"type"=>"NilClass", "isNull"=>true}],
24+
[{"type"=>"String", "value"=>"created_at"},
25+
{"type"=>"ActiveSupport::TimeWithZone", "value"=>String}],
26+
[{"type"=>"String", "value"=>"updated_at"},
27+
{"type"=>"ActiveSupport::TimeWithZone", "value"=>String}]]}],
28+
[{"type"=>"Symbol", "value"=>"new_record"}, {"type"=>"FalseClass", "value"=>"false"}]]}
29+
)
30+
end
31+
end
32+
end

lib/datadog/di.rb

+4-15
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,6 @@
1818
require_relative 'di/transport'
1919
require_relative 'di/utils'
2020

21-
if defined?(ActiveRecord::Base)
22-
# The third-party library integrations need to be loaded after the
23-
# third-party libraries are loaded. Tracing and appsec use Railtie
24-
# to delay integrations until all of the application's dependencies
25-
# are loaded, when running under Rails. We should do the same here in
26-
# principle, however DI currently only has an ActiveRecord integration
27-
# and AR should be loaded before any application code is loaded, being
28-
# part of Rails, therefore for now we should be OK to just require the
29-
# AR integration from here.
30-
#
31-
# TODO this require might need to be delayed via Rails post-initialization
32-
# logic?
33-
require_relative 'di/contrib/active_record'
34-
end
35-
3621
module Datadog
3722
# Namespace for Datadog dynamic instrumentation.
3823
#
@@ -75,3 +60,7 @@ def component
7560
# for line probes to work) activate tracking in an initializer.
7661
Datadog::DI.activate_tracking
7762
end
63+
64+
require_relative 'di/contrib'
65+
66+
Datadog::DI::Contrib.load_now_or_later

lib/datadog/di/contrib.rb

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# frozen_string_literal: true
2+
3+
require_relative '../core/contrib/rails/utils'
4+
5+
module Datadog
6+
module DI
7+
module Contrib
8+
module_function def load_now_or_later
9+
if Datadog::Core::Contrib::Rails::Utils.railtie_supported?
10+
require_relative 'contrib/railtie'
11+
else
12+
load_now
13+
end
14+
end
15+
16+
module_function def load_now
17+
if defined?(ActiveRecord::Base)
18+
require_relative 'contrib/active_record'
19+
end
20+
end
21+
end
22+
end
23+
end

lib/datadog/di/contrib/railtie.rb

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# frozen_string_literal: true
2+
3+
module Datadog
4+
module DI
5+
module Contrib
6+
# Railtie class initializes dynamic instrumentation contrib code
7+
# in Rails environments.
8+
class Railtie < Rails::Railtie
9+
initializer 'datadog.dynamic_instrumentation.initialize' do |app|
10+
Contrib.load_now
11+
end
12+
end
13+
end
14+
end
15+
end

sig/datadog/di/contrib.rbs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module Datadog
2+
module DI
3+
module Contrib
4+
def self?.load_now_or_later: () -> void
5+
6+
def self?.load_now: () -> void
7+
end
8+
end
9+
end

sig/datadog/di/contrib/railtie.rbs

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module Datadog
2+
module DI
3+
module Contrib
4+
class Railtie < Rails::Railtie
5+
end
6+
end
7+
end
8+
end

0 commit comments

Comments
 (0)