diff --git a/.github/workflows/ci_cron.yml b/.github/workflows/ci_cron.yml index f39e845497..b1d9ba3f50 100644 --- a/.github/workflows/ci_cron.yml +++ b/.github/workflows/ci_cron.yml @@ -35,7 +35,7 @@ jobs: strategy: fail-fast: false matrix: - ruby-version: [2.2.10, 2.3.8, 2.4.10, 2.5.9, 2.6.10, 2.7.6, 3.0.4, 3.1.2, 3.2.0-preview1, jruby-9.3.8.0] + ruby-version: [2.2.10, 2.3.8, 2.4.10, 2.5.9, 2.6.10, 2.7.6, 3.0.4, 3.1.2, 3.2.0-preview2, jruby-9.3.8.0] steps: - name: Configure git @@ -83,7 +83,7 @@ jobs: "3.1.2": { "rails": "norails,rails61,rails70,railsedge" }, - "3.2.0-preview1": { + "3.2.0-preview2": { "rails": "norails,rails61,rails70,railsedge" }, "jruby-9.3.8.0": { @@ -177,7 +177,7 @@ jobs: fail-fast: false matrix: multiverse: [agent, background, background_2, database, frameworks, httpclients, httpclients_2, rails, rest] - ruby-version: [2.2.10, 2.3.8, 2.4.10, 2.5.9, 2.6.10, 2.7.6, 3.0.4, 3.1.2, 3.2.0-preview1] + ruby-version: [2.2.10, 2.3.8, 2.4.10, 2.5.9, 2.6.10, 2.7.6, 3.0.4, 3.1.2, 3.2.0-preview2] steps: - name: Configure git run: 'git config --global init.defaultBranch main' @@ -240,7 +240,7 @@ jobs: strategy: fail-fast: false matrix: - ruby-version: [2.5.9, 2.6.10, 2.7.6, 3.0.4, 3.1.2, 3.2.0-preview1] + ruby-version: [2.5.9, 2.6.10, 2.7.6, 3.0.4, 3.1.2, 3.2.0-preview2] steps: - name: Configure git run: 'git config --global init.defaultBranch main' diff --git a/lib/new_relic/agent/samplers/vm_sampler.rb b/lib/new_relic/agent/samplers/vm_sampler.rb index d0ccbbe6ae..c07997c6a4 100644 --- a/lib/new_relic/agent/samplers/vm_sampler.rb +++ b/lib/new_relic/agent/samplers/vm_sampler.rb @@ -19,6 +19,7 @@ class VMSampler < Sampler MINOR_GC_METRIC = 'RubyVM/GC/minor_gc_count'.freeze METHOD_INVALIDATIONS_METRIC = 'RubyVM/CacheInvalidations/method'.freeze CONSTANT_INVALIDATIONS_METRIC = 'RubyVM/CacheInvalidations/constant'.freeze + CONSTANT_MISSES_METRIC = 'RubyVM/CacheMisses/constant'.freeze attr_reader :transaction_count @@ -115,6 +116,7 @@ def poll record_delta(snap, :minor_gc_count, MINOR_GC_METRIC, tcount) record_delta(snap, :method_cache_invalidations, METHOD_INVALIDATIONS_METRIC, tcount) record_delta(snap, :constant_cache_invalidations, CONSTANT_INVALIDATIONS_METRIC, tcount) + record_delta(snap, :constant_cache_misses, CONSTANT_MISSES_METRIC, tcount) record_heap_live_metric(snap) record_heap_free_metric(snap) record_thread_count_metric(snap) diff --git a/lib/new_relic/agent/vm/mri_vm.rb b/lib/new_relic/agent/vm/mri_vm.rb index 44b8af6849..900badf34f 100644 --- a/lib/new_relic/agent/vm/mri_vm.rb +++ b/lib/new_relic/agent/vm/mri_vm.rb @@ -52,18 +52,18 @@ def gather_ruby_vm_stats(snap) if supports?(:constant_cache_invalidations) snap.constant_cache_invalidations = gather_constant_cache_invalidations end + + if supports?(:constant_cache_misses) + snap.constant_cache_misses = gather_constant_cache_misses + end end def gather_constant_cache_invalidations - # Ruby >= 3.2 uses :constant_cache - # see: https://github.com/ruby/ruby/pull/5433 and https://bugs.ruby-lang.org/issues/18589 - # TODO: now that 3.2+ provides more granual cache invalidation data, should we report it instead of summing? - if RUBY_VERSION >= '3.2.0' - RubyVM.stat[:constant_cache].values.sum - # Ruby < 3.2 uses :global_constant_state - else - RubyVM.stat[:global_constant_state] - end + RubyVM.stat[RUBY_VERSION >= '3.2.0' ? :constant_cache_invalidations : :global_constant_state] + end + + def gather_constant_cache_misses + RubyVM.stat[:constant_cache_misses] end def gather_thread_stats(snap) @@ -84,6 +84,8 @@ def supports?(key) RUBY_VERSION >= '2.1.0' && RUBY_VERSION < '3.0.0' when :constant_cache_invalidations RUBY_VERSION >= '2.1.0' + when :constant_cache_misses + RUBY_VERSION >= '3.2.0' else false end diff --git a/lib/new_relic/agent/vm/snapshot.rb b/lib/new_relic/agent/vm/snapshot.rb index bdbcca7b43..9e23dbd9be 100644 --- a/lib/new_relic/agent/vm/snapshot.rb +++ b/lib/new_relic/agent/vm/snapshot.rb @@ -10,7 +10,7 @@ class Snapshot attr_accessor :gc_total_time, :gc_runs, :major_gc_count, :minor_gc_count, :total_allocated_object, :heap_live, :heap_free, :method_cache_invalidations, :constant_cache_invalidations, - :thread_count, :taken_at + :constant_cache_misses, :thread_count, :taken_at def initialize @taken_at = Process.clock_gettime(Process::CLOCK_REALTIME) diff --git a/test/new_relic/agent/samplers/vm_sampler_test.rb b/test/new_relic/agent/samplers/vm_sampler_test.rb index 5d6b397ef4..c2b5464289 100644 --- a/test/new_relic/agent/samplers/vm_sampler_test.rb +++ b/test/new_relic/agent/samplers/vm_sampler_test.rb @@ -22,7 +22,8 @@ def setup :heap_live => 0, :heap_free => 0, :method_cache_invalidations => 0, - :constant_cache_invalidations => 0 + :constant_cache_invalidations => 0, + :constant_cache_misses => 0 ) @sampler = VMSampler.new @sampler.setup_events(NewRelic::Agent.instance.events) @@ -128,7 +129,8 @@ def test_poll_records_heap_usage_metrics def test_poll_records_vm_cache_invalidations stub_snapshot( :method_cache_invalidations => 100, - :constant_cache_invalidations => 200 + :constant_cache_invalidations => 200, + :constant_cache_misses => 175 ) generate_transactions(50) @sampler.poll @@ -141,6 +143,10 @@ def test_poll_records_vm_cache_invalidations 'RubyVM/CacheInvalidations/constant' => { :call_count => 50, # number of transactions :total_call_time => 200 # number of constant cache invalidations + }, + 'RubyVM/CacheMisses/constant' => { + :call_count => 50, # number of transactions + :total_call_time => 175 # number of constant cache misses } ) end @@ -186,7 +192,8 @@ def test_poll_records_deltas_not_cumulative_values :major_gc_count => 10, :minor_gc_count => 10, :method_cache_invalidations => 10, - :constant_cache_invalidations => 10 + :constant_cache_invalidations => 10, + :constant_cache_misses => 10 ) @sampler.poll @@ -209,6 +216,9 @@ def test_poll_records_deltas_not_cumulative_values }, 'RubyVM/CacheInvalidations/constant' => { :total_call_time => 10 + }, + 'RubyVM/CacheMisses/constant' => { + :total_call_time => 10 } } @@ -223,7 +233,8 @@ def test_poll_records_deltas_not_cumulative_values :major_gc_count => 20, :minor_gc_count => 20, :method_cache_invalidations => 20, - :constant_cache_invalidations => 20 + :constant_cache_invalidations => 20, + :constant_cache_misses => 20 ) @sampler.poll @@ -242,6 +253,7 @@ def test_poll_aggregates_multiple_polls :minor_gc_count => 10, :method_cache_invalidations => 10, :constant_cache_invalidations => 10, + :constant_cache_misses => 10, :taken_at => 10 ) generate_transactions(10) @@ -255,6 +267,7 @@ def test_poll_aggregates_multiple_polls :minor_gc_count => 20, :method_cache_invalidations => 20, :constant_cache_invalidations => 20, + :constant_cache_misses => 20, :taken_at => 20 ) generate_transactions(10) @@ -286,6 +299,10 @@ def test_poll_aggregates_multiple_polls 'RubyVM/CacheInvalidations/constant' => { :call_count => 20, :total_call_time => 20 + }, + 'RubyVM/CacheMisses/constant' => { + :call_count => 20, + :total_call_time => 20 } ) end diff --git a/test/new_relic/agent/vm_test.rb b/test/new_relic/agent/vm_test.rb index 2e819aeafa..34794c0216 100644 --- a/test/new_relic/agent/vm_test.rb +++ b/test/new_relic/agent/vm_test.rb @@ -27,6 +27,7 @@ def test_gets_snapshot :heap_free, :method_cache_invalidations, :constant_cache_invalidations, + :constant_cache_misses, :thread_count ]