diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fb8061..e413e61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog of RorVsWild +## Unreleased + +* Fix Sidekiq and measure_method total time when exception has been raised + ## 1.12.0 (2026-07-23) * Measure ViewComponent, it must be enabled with: `config.view_component.instrumentation_enabled = true` diff --git a/lib/rorvswild/agent.rb b/lib/rorvswild/agent.rb index a0a5314..cc8b1e4 100644 --- a/lib/rorvswild/agent.rb +++ b/lib/rorvswild/agent.rb @@ -74,13 +74,12 @@ def measure_method(method) method_file, method_line = method.source_location method_file = locator.relative_path(File.expand_path(method_file)) method.owner.define_method(method.name) do |*args| - section = Section.start - section.file = method_file - section.line = method_line - section.commands << method_full_name - result = send(method_alias, *args) - Section.stop - result + Section.measure do |section| + section.file = method_file + section.line = method_line + section.commands << method_full_name + send(method_alias, *args) + end end end diff --git a/lib/rorvswild/plugin/sidekiq.rb b/lib/rorvswild/plugin/sidekiq.rb index fbb9323..857de96 100644 --- a/lib/rorvswild/plugin/sidekiq.rb +++ b/lib/rorvswild/plugin/sidekiq.rb @@ -19,14 +19,14 @@ def call(worker, item, queue, &block) # Wrapped contains the real class name of the ActiveJob wrapper name = item["wrapped".freeze] || item["class".freeze] RorVsWild.agent.measure_job(name, parameters: item["args".freeze]) do - section = RorVsWild::Section.start - section.commands << "#{name}#perform" - if perform_method = worker.method(:perform) - section.file, section.line = worker.method(:perform).source_location - section.file = RorVsWild.agent.locator.relative_path(section.file) + RorVsWild::Section.measure do |section| + section.commands << "#{name}#perform" + if perform_method = worker.method(:perform) + section.file, section.line = worker.method(:perform).source_location + section.file = RorVsWild.agent.locator.relative_path(section.file) + end + block.call end - block.call - RorVsWild::Section.stop end end end diff --git a/lib/rorvswild/section.rb b/lib/rorvswild/section.rb index 80c12cd..5cf467f 100644 --- a/lib/rorvswild/section.rb +++ b/lib/rorvswild/section.rb @@ -12,6 +12,15 @@ def self.start(&block) section end + def self.measure(&block) + section = start + begin + block.call(section) + ensure + stop + end + end + def self.stop(&block) return if !(sections = stack) || !(section = sections.pop) block.call(section) if block_given? diff --git a/test/agent_test.rb b/test/agent_test.rb index ff4f1a1..22e3bf5 100644 --- a/test/agent_test.rb +++ b/test/agent_test.rb @@ -57,6 +57,10 @@ def self.foo def bar 2 end + + def boom + raise + end end def test_measure_class_method @@ -81,6 +85,15 @@ def test_measure_instance_method assert_equal("RorVsWild::AgentTest::Example#bar", section.commands.to_a.join) end + def test_measure_method_on_exception + agent.measure_method(Example.instance_method(:boom)) + assert_raises(RuntimeError) { agent.measure_job("job") { Example.new.boom } } + sections = current_user_sections + assert_equal(1, sections.size) + assert_equal("RorVsWild::AgentTest::Example#boom", sections[0].command) + assert(agent.current_execution.runtime > 0) + end + def test_ignored_request? agent = initialize_agent(ignore_requests: ["ApplicationController#secret"]) assert(agent.ignored_request?("ApplicationController#secret")) diff --git a/test/plugin/sidekiq_test.rb b/test/plugin/sidekiq_test.rb index 16674fd..4594bcd 100644 --- a/test/plugin/sidekiq_test.rb +++ b/test/plugin/sidekiq_test.rb @@ -33,6 +33,10 @@ def test_callback_on_exception rescue ensure assert_equal([false], agent.current_execution.error.as_json[:parameters]) + sections = current_user_sections + assert_equal(1, sections.size) + assert_equal("RorVsWild::Plugin::SidekiqTest::SampleJob#perform", sections[0].command) + assert(agent.current_execution.runtime > 0) end end diff --git a/test/section_test.rb b/test/section_test.rb index 5efbb36..c3b746a 100644 --- a/test/section_test.rb +++ b/test/section_test.rb @@ -71,6 +71,31 @@ def test_as_json ) end + def test_measure + start_request + result = RorVsWild::Section.measure do |section| + section.commands << "measured" + :return + end + assert_equal(:return, result) + section = current_user_sections.last + assert_equal("measured", section.command) + assert(section.total_ms >= 0) + end + + def test_measure_when_exception_is_raised + start_request + assert_raises(RuntimeError) do + RorVsWild::Section.measure do |section| + section.commands << "measured" + raise + end + end + section = current_user_sections.last + assert_equal("measured", section.command) + assert(section.total_ms >= 0) + end + private def section1