diff --git a/.ci/.exclude.yml b/.ci/.exclude.yml index cfabf9da3..6d623870a 100644 --- a/.ci/.exclude.yml +++ b/.ci/.exclude.yml @@ -20,6 +20,8 @@ exclude: # rails-4.2 exclusions # Only test on ruby 2.4 + - VERSION: ruby:3.4 + FRAMEWORK: rails-4.2 - VERSION: ruby:3.1 FRAMEWORK: rails-4.2 - VERSION: ruby:2.7 @@ -120,6 +122,10 @@ exclude: FRAMEWORK: grape-1.6 # only test ruby >= 3.1 with rails 6.1 and rails 7.0 + - VERSION: ruby:3.4 + FRAMEWORK: rails-5.2 + - VERSION: ruby:3.4 + FRAMEWORK: rails-5.1 - VERSION: ruby:3.1 FRAMEWORK: rails-5.2 - VERSION: ruby:3.1 diff --git a/.ci/.ruby.yml b/.ci/.ruby.yml index 321ee3027..f23c32702 100644 --- a/.ci/.ruby.yml +++ b/.ci/.ruby.yml @@ -1,4 +1,5 @@ VERSION: + - ruby:3.4 - ruby:3.1 - ruby:2.7 - ruby:2.6 diff --git a/Gemfile b/Gemfile index 967f60054..28961f7c2 100644 --- a/Gemfile +++ b/Gemfile @@ -91,6 +91,10 @@ frameworks_versions.each do |framework, version| gem 'net-smtp', require: false end + if framework =='rails' && RUBY_VERSION >= '3.4' && ['4.2', '5.2', '6.1'].include?(version) + gem 'mutex_m' + end + case version when 'master' # grape gem framework, github: GITHUB_REPOS.fetch(framework) diff --git a/lib/elastic_apm/spies/sidekiq.rb b/lib/elastic_apm/spies/sidekiq.rb index 7dfb5fc45..0857f36eb 100644 --- a/lib/elastic_apm/spies/sidekiq.rb +++ b/lib/elastic_apm/spies/sidekiq.rb @@ -24,6 +24,7 @@ module Spies class SidekiqSpy ACTIVE_JOB_WRAPPER = 'ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper' + ACTIVE_JOB_WRAPPER_V8 = 'Sidekiq::ActiveJob::Wrapper' # @api private class Middleware @@ -50,7 +51,7 @@ def self.name_for(job) klass = job['class'] case klass - when ACTIVE_JOB_WRAPPER + when ACTIVE_JOB_WRAPPER, ACTIVE_JOB_WRAPPER_V8 job['wrapped'] else klass diff --git a/lib/elastic_apm/stacktrace_builder.rb b/lib/elastic_apm/stacktrace_builder.rb index 598e7099c..809782f7b 100644 --- a/lib/elastic_apm/stacktrace_builder.rb +++ b/lib/elastic_apm/stacktrace_builder.rb @@ -24,7 +24,7 @@ module ElasticAPM # @api private class StacktraceBuilder JAVA_FORMAT = /^(.+)\.([^.]+)\(([^:]+):(\d+)\)$/.freeze - RUBY_FORMAT = /^(.+?):(\d+)(?::in `(.+?)')?$/.freeze + RUBY_FORMAT = /^(.+?):(\d+)(?::in ['`](.+#)?(.+?)')?$/.freeze RUBY_VERS_REGEX = %r{ruby(/gems)?[-/](\d+\.)+\d}.freeze JRUBY_ORG_REGEX = %r{org/jruby}.freeze @@ -77,9 +77,9 @@ def parse_line(line) ruby_match = line.match(RUBY_FORMAT) if ruby_match - _, file, number, method = ruby_match.to_a + _, file, number, module_name, method = ruby_match.to_a file.sub!(/\.class$/, '.rb') - module_name = nil + module_name&.sub!('#', '') else java_match = line.match(JAVA_FORMAT) _, module_name, method, file, number = java_match.to_a diff --git a/spec/elastic_apm/spies/mongo_spec.rb b/spec/elastic_apm/spies/mongo_spec.rb index d16079970..7643bb3be 100644 --- a/spec/elastic_apm/spies/mongo_spec.rb +++ b/spec/elastic_apm/spies/mongo_spec.rb @@ -52,6 +52,7 @@ module ElasticAPM expect(db.instance).to eq 'elastic-apm-test' expect(db.type).to eq 'mongodb' expect(db.statement).to eq('{"listCollections"=>1}') + .or eq("{\"listCollections\" => 1}") expect(db.user).to be nil destination = span.context.destination @@ -102,6 +103,7 @@ module ElasticAPM expect(db.instance).to eq 'elastic-apm-test' expect(db.type).to eq 'mongodb' expect(db.statement).to eq('{"find"=>"testing", "filter"=>{"a"=>"bc"}}') + .or eq("{\"find\" => \"testing\", \"filter\" => {\"a\" => \"bc\"}}") expect(db.user).to be nil end end diff --git a/spec/integration/mongo_spec.rb b/spec/integration/mongo_spec.rb index 37546f918..79560e89a 100644 --- a/spec/integration/mongo_spec.rb +++ b/spec/integration/mongo_spec.rb @@ -56,8 +56,10 @@ module ElasticAPM db = span.context.db expect(db.instance).to eq 'elastic-apm-test' expect(db.type).to eq 'mongodb' - expect(db.statement).to include '{"listCollections"=>1, "cursor"=>{}, ' \ - '"nameOnly"=>true' + expect(db.statement).to include('{"listCollections"=>1, "cursor"=>{}, ' \ + '"nameOnly"=>true') + .or include('{"listCollections" => 1, "cursor" => {}, ' \ + '"nameOnly" => true') expect(db.user).to be nil end @@ -93,6 +95,7 @@ module ElasticAPM expect(db.instance).to eq 'elastic-apm-test' expect(db.type).to eq 'mongodb' expect(db.statement).to match('"delete"=>"testing"') + .or match('"delete" => "testing"') expect(db.user).to be nil end @@ -124,7 +127,8 @@ module ElasticAPM db = span.context.db expect(db.instance).to eq 'elastic-apm-test' expect(db.type).to eq 'mongodb' - expect(db.statement).to include '{"a"=>BSON::Decimal128(\'1\')}' + expect(db.statement).to include('{"a"=>BSON::Decimal128(\'1\')}') + .or include('{"a" => BSON::Decimal128(\'1\')}') expect(db.user).to be nil end @@ -157,7 +161,8 @@ module ElasticAPM db = find_span.context.db expect(db.instance).to eq 'elastic-apm-test' expect(db.type).to eq 'mongodb' - expect(db.statement).to include '{"find"=>"testing"' + expect(db.statement).to include('{"find"=>"testing"') + .or include('{"find" => "testing"') expect(db.user).to be nil expect(get_more_span.name).to eq 'elastic-apm-test.testing.getMore' @@ -169,7 +174,8 @@ module ElasticAPM db = get_more_span.context.db expect(db.instance).to eq 'elastic-apm-test' expect(db.type).to eq 'mongodb' - expect(db.statement).to include '{"getMore"=>## #