Skip to content

Commit 3dddec7

Browse files
committed
Merge branch 'master' into steep-2
2 parents cd83132 + 9e3a3e3 commit 3dddec7

File tree

40 files changed

+407
-70
lines changed

40 files changed

+407
-70
lines changed

.github/scripts/find_gem_version_bounds.rb

+30-17
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,11 @@ def process_gemfile(gemfile_name, runtime)
5252
definition.dependencies.each do |dependency|
5353
gem_name = dependency.name
5454
version = dependency.requirement.to_s
55-
update_gem_versions(runtime, gem_name, version)
55+
unspecified = version.strip == '' || version == ">= 0"
56+
if unspecified
57+
puts "#{gem_name} uses latest"
58+
end
59+
update_gem_versions(runtime, gem_name, version, unspecified)
5660
end
5761
rescue Bundler::GemfileError => e
5862
puts "Error reading Gemfile: #{e.message}"
@@ -65,30 +69,36 @@ def process_lockfile(gemfile_name, runtime)
6569
parser.specs.each do |spec|
6670
gem_name = spec.name
6771
version = spec.version.to_s
68-
update_gem_versions(runtime, gem_name, version)
72+
update_gem_versions(runtime, gem_name, version, false)
6973
end
7074
end
7175

72-
def update_gem_versions(runtime, gem_name, version)
73-
return unless version_valid?(version)
74-
75-
gem_version = Gem::Version.new(version)
76+
def update_gem_versions(runtime, gem_name, version, unspecified)
77+
return unless version_valid?(version, unspecified)
7678

79+
gem_version = Gem::Version.new(version) unless unspecified
7780
# Update minimum gems
78-
if @min_gems[runtime][gem_name].nil? || gem_version < Gem::Version.new(@min_gems[runtime][gem_name])
79-
@min_gems[runtime][gem_name] = version
81+
if not unspecified
82+
if @min_gems[runtime][gem_name].nil? || gem_version < Gem::Version.new(@min_gems[runtime][gem_name])
83+
@min_gems[runtime][gem_name] = version
84+
end
8085
end
8186

8287
# Update maximum gems
83-
if @max_gems[runtime][gem_name].nil? || gem_version > Gem::Version.new(@max_gems[runtime][gem_name])
84-
@max_gems[runtime][gem_name] = version
88+
if unspecified
89+
puts "Setting gem #{gem_name} to infinity"
90+
@max_gems[runtime][gem_name] = Float::INFINITY
91+
else
92+
if @max_gems[runtime][gem_name].nil? || (@max_gems[runtime][gem_name] != Float::INFINITY && gem_version > Gem::Version.new(@max_gems[runtime][gem_name]))
93+
@max_gems[runtime][gem_name] = version
94+
end
8595
end
8696
end
8797

8898
# Helper: Validate the version format
89-
def version_valid?(version)
99+
def version_valid?(version, unspecified)
100+
return true if unspecified
90101
return false if version.nil? || version.strip.empty?
91-
92102
Gem::Version.new(version)
93103
true
94104
rescue ArgumentError
@@ -115,17 +125,17 @@ def process_integrations
115125
def include_hardcoded_versions
116126
# `httpx` is maintained externally
117127
@integration_json_mapping['httpx'] = [
118-
'0.11', # Min version Ruby
119-
'0.11', # Max version Ruby
120-
nil, # Min version JRuby
128+
'0.11', # Min version Ruby
129+
nil, # Max version Ruby
130+
'0.11', # Min version JRuby
121131
nil # Max version JRuby
122132
]
123133

124134
# `makara` is part of `activerecord`
125135
@integration_json_mapping['makara'] = [
126136
'0.3.5', # Min version Ruby
127-
'0.3.5', # Max version Ruby
128-
nil, # Min version JRuby
137+
nil, # Max version Ruby
138+
'0.3.5', # Min version JRuby
129139
nil # Max version JRuby
130140
]
131141
end
@@ -142,6 +152,9 @@ def resolve_integration_name(integration)
142152

143153
def write_output
144154
@integration_json_mapping = @integration_json_mapping.sort.to_h
155+
@integration_json_mapping.each do |integration, versions|
156+
versions.map! { |v| v == Float::INFINITY ? 'infinity' : v }
157+
end
145158
File.write("gem_output.json", JSON.pretty_generate(@integration_json_mapping))
146159
end
147160
end

.github/scripts/generate_table_versions.rb

+8-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,14 @@
99
header = "| Integration | Ruby Min | Ruby Max | JRuby Min | JRuby Max |\n"
1010
separator = "|-------------|----------|-----------|----------|----------|\n"
1111
rows = data.map do |integration_name, versions|
12-
ruby_min, ruby_max, jruby_min, jruby_max = versions.map { |v| v || "None" }
13-
"| #{integration_name} | #{ruby_min} | #{ruby_max} | #{jruby_min} | #{jruby_max} |"
12+
ruby_min, ruby_max, jruby_min, jruby_max = versions.map do |v|
13+
if v == "infinity"
14+
"latest"
15+
else
16+
v || "None"
17+
end
18+
end
19+
"| #{integration_name} | #{ruby_min} | #{ruby_max} | #{jruby_min} | #{jruby_max} |"
1420
end
1521

1622
File.open(output_file, 'w') do |file|

Steepfile

+1
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ target :datadog do
9191
ignore 'lib/datadog/core/workers/queue.rb'
9292
ignore 'lib/datadog/core/workers/runtime_metrics.rb'
9393
ignore 'lib/datadog/di/configuration/settings.rb'
94+
ignore 'lib/datadog/di/contrib/railtie.rb'
9495
ignore 'lib/datadog/kit/appsec/events.rb' # disabled because of https://github.com/soutaro/steep/issues/701
9596
ignore 'lib/datadog/kit/identity.rb' # disabled because of https://github.com/soutaro/steep/issues/701
9697
ignore 'lib/datadog/opentelemetry.rb'

integration/apps/hanami/Gemfile

+1-9
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,7 @@ gem 'unicorn'
1515
gem 'webrick'
1616
gem 'pry-byebug'
1717

18-
gem_spec = Datadog::DemoEnv.gem_spec('datadog')
19-
req = {require: 'datadog/auto_instrument'}
20-
opts = if gem_spec.last.is_a?(Hash)
21-
gem_spec.pop.merge(req)
22-
else
23-
req
24-
end
25-
gem_spec << opts
26-
gem 'datadog', *gem_spec
18+
gem *Datadog::DemoEnv.gem_datadog_auto_instrument
2719
gem 'google-protobuf', '~> 3.0'
2820

2921
group :development do

integration/apps/rails-five/Gemfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ gem 'unicorn'
2525
gem 'loofah', '2.19.1'
2626

2727
# Choose correct specs for 'datadog' demo environment
28-
gem 'datadog', *Datadog::DemoEnv.gem_spec('datadog')
28+
gem *Datadog::DemoEnv.gem_datadog_auto_instrument
2929

3030
gem 'dogstatsd-ruby'
3131
gem 'ffi'
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-five/bin/run

+4-4
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ puts "\n== Starting application process =="
88
process = (ARGV[0] || Datadog::DemoEnv.process)
99
command = case process
1010
when 'puma'
11-
"bundle exec ddprofrb exec puma -C /app/config/puma.rb"
11+
"bundle exec puma -C /app/config/puma.rb"
1212
when 'unicorn'
13-
"bundle exec ddprofrb exec unicorn -c /app/config/unicorn.rb"
13+
"bundle exec unicorn -c /app/config/unicorn.rb"
1414
when 'console'
15-
"bundle exec ddprofrb exec rails c"
15+
"bundle exec rails c"
1616
when 'irb'
17-
"bundle exec ddprofrb exec irb"
17+
"bundle exec irb"
1818
when nil, ''
1919
abort("\n== ERROR: Must specify a application process! ==")
2020
else

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

+6
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,10 @@
2828
c.profiling.exporter.transport = Datadog::DemoEnv.profiler_file_transport
2929
end
3030
end
31+
32+
if c.respond_to?(:dynamic_instrumentation)
33+
c.remote.enabled = true
34+
c.dynamic_instrumentation.enabled = true
35+
c.dynamic_instrumentation.internal.development = true
36+
end
3137
end

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

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
get 'basic/default', to: 'basic#default'
88
get 'basic/fibonacci', to: 'basic#fibonacci'
99

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

integration/apps/rails-five/spec/support/integration_helper.rb

+19
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,23 @@ def get(path)
1919
Net::HTTP.get_response(uri)
2020
end
2121
end
22+
23+
module ClassMethods
24+
def di_test
25+
if RUBY_ENGINE == 'jruby'
26+
before(:all) do
27+
skip "Dynamic instrumentation is not supported on JRuby"
28+
end
29+
end
30+
if RUBY_VERSION < "2.6"
31+
before(:all) do
32+
skip "Dynamic instrumentation requires Ruby 2.6 or higher"
33+
end
34+
end
35+
end
36+
end
37+
38+
def self.included(base)
39+
base.extend(ClassMethods)
40+
end
2241
end

integration/apps/rails-seven/Gemfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
77
gem "rails", "~> 7.0.5"
88

99
# Choose correct specs for 'datadog' demo environment
10-
gem 'datadog', *Datadog::DemoEnv.gem_spec('datadog')
10+
gem *Datadog::DemoEnv.gem_datadog_auto_instrument
1111

1212
gem 'dogstatsd-ruby'
1313

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/bin/run

+4-4
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ puts "\n== Starting application process =="
88
process = (ARGV[0] || Datadog::DemoEnv.process)
99
command = case process
1010
when 'puma'
11-
"bundle exec ddprofrb exec puma -C /app/config/puma.rb"
11+
"bundle exec puma -C /app/config/puma.rb"
1212
when 'unicorn'
13-
"bundle exec ddprofrb exec unicorn -c /app/config/unicorn.rb"
13+
"bundle exec unicorn -c /app/config/unicorn.rb"
1414
when 'console'
15-
"bundle exec ddprofrb exec rails c"
15+
"bundle exec rails c"
1616
when 'irb'
17-
"bundle exec ddprofrb exec irb"
17+
"bundle exec irb"
1818
when nil, ''
1919
abort("\n== ERROR: Must specify a application process! ==")
2020
else

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

+6-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,10 @@
2625
# Reconfigure transport to write pprof to file
2726
c.profiling.exporter.transport = Datadog::DemoEnv.profiler_file_transport
2827
end
28+
29+
if c.respond_to?(:dynamic_instrumentation)
30+
c.remote.enabled = true
31+
c.dynamic_instrumentation.enabled = true
32+
c.dynamic_instrumentation.internal.development = true
33+
end
2934
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,36 @@
1+
require 'spec_helper'
2+
require 'json'
3+
4+
RSpec.describe 'Dynamic Instrumentation' do
5+
include_context 'integration test'
6+
di_test
7+
8+
describe 'ActiveRecord integration' do
9+
let(:response) { get('di/ar_serializer') }
10+
subject { JSON.parse(response.body) }
11+
12+
it 'is loaded' do
13+
expect(response.code).to eq '200'
14+
15+
# If AR integration is loaded, this output will be the result of
16+
# the custom serializer.
17+
# If AR integration is not loaded, the output here will have a bunch of
18+
# internal AR fields but not the attributes themselves.
19+
expect(subject).to match(
20+
{"type"=>"Test",
21+
"entries"=>
22+
[[{"type"=>"Symbol", "value"=>"attributes"},
23+
{"type"=>"Hash",
24+
"entries"=>
25+
[[{"type"=>"String", "value"=>"id"}, {"type"=>"Integer", "value"=>String}],
26+
[{"type"=>"String", "value"=>"version"}, {"type"=>"NilClass", "isNull"=>true}],
27+
[{"type"=>"String", "value"=>"data"}, {"type"=>"NilClass", "isNull"=>true}],
28+
[{"type"=>"String", "value"=>"created_at"},
29+
{"type"=>"ActiveSupport::TimeWithZone", "value"=>String}],
30+
[{"type"=>"String", "value"=>"updated_at"},
31+
{"type"=>"ActiveSupport::TimeWithZone", "value"=>String}]]}],
32+
[{"type"=>"Symbol", "value"=>"new_record"}, {"type"=>"FalseClass", "value"=>"false"}]]}
33+
)
34+
end
35+
end
36+
end

integration/apps/rails-seven/spec/support/integration_helper.rb

+19
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,23 @@ def get(path)
1919
Net::HTTP.get_response(uri)
2020
end
2121
end
22+
23+
module ClassMethods
24+
def di_test
25+
if RUBY_ENGINE == 'jruby'
26+
before(:all) do
27+
skip "Dynamic instrumentation is not supported on JRuby"
28+
end
29+
end
30+
if RUBY_VERSION < "2.6"
31+
before(:all) do
32+
skip "Dynamic instrumentation requires Ruby 2.6 or higher"
33+
end
34+
end
35+
end
36+
end
37+
38+
def self.included(base)
39+
base.extend(ClassMethods)
40+
end
2241
end

integration/apps/rails-six/Gemfile

+9-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ gem 'puma'
1818
gem 'unicorn'
1919

2020
# Choose correct specs for 'datadog' demo environment
21-
gem 'datadog', *Datadog::DemoEnv.gem_spec('datadog')
21+
gem *Datadog::DemoEnv.gem_datadog_auto_instrument
2222

2323
gem 'dogstatsd-ruby'
2424
gem 'ffi'
@@ -90,7 +90,14 @@ end
9090

9191
group :test, :development do
9292
gem 'byebug', platform: :ruby
93-
gem 'mock_redis'
93+
# mock_redis 0.47.0+ requires redis 5 or higher
94+
# mock_redis 0.42.0+ requires Ruby 3.0 or higher
95+
# mock_redis 0.37.0+ requires Ruby 2.7 or higher
96+
if RUBY_VERSION >= '2.7'
97+
gem 'mock_redis', '~> 0.37.0'
98+
else
99+
gem 'mock_redis', '< 0.37.0'
100+
end
94101
gem 'parallel_tests'
95102

96103
gem 'listen'

0 commit comments

Comments
 (0)