Skip to content

Commit 051180b

Browse files
Add Appsignal::Integrations::ActiveSupportEventReporter
Rails 8.1 adds ActiveSupport::EventReporter, an interface for reporting structured events. To catch these, report them as info-level logs in the rails_events category through the newly added Appsignal::Integrations::ActiveSupportEventReporter.
1 parent e1edcca commit 051180b

File tree

7 files changed

+125
-0
lines changed

7 files changed

+125
-0
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
bump: minor
3+
type: add
4+
---
5+
6+
Report events from Rails 8.1's ActiveSupport::EventReporter as logs

lib/appsignal/hooks.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ def truncate(text)
7979
require "appsignal/hooks/action_mailer"
8080
require "appsignal/hooks/active_job"
8181
require "appsignal/hooks/active_support_notifications"
82+
require "appsignal/hooks/active_support_event_reporter"
8283
require "appsignal/hooks/celluloid"
8384
require "appsignal/hooks/code_ownership"
8485
require "appsignal/hooks/delayed_job"
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# frozen_string_literal: true
2+
3+
module Appsignal
4+
class Hooks
5+
# @!visibility private
6+
class ActiveSupportEventReporterHook < Appsignal::Hooks::Hook
7+
register :active_support_event_reporter
8+
9+
def dependencies_present?
10+
defined?(::ActiveSupport::EventReporter)
11+
end
12+
13+
def install
14+
require "appsignal/integrations/active_support_event_reporter"
15+
Rails.event.subscribe(Appsignal::Integrations::ActiveSupportEventReporter::Subscriber.new())
16+
end
17+
end
18+
end
19+
end
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# frozen_string_literal: true
2+
3+
module Appsignal
4+
module Integrations
5+
# @!visibility private
6+
module ActiveSupportEventReporter
7+
class Subscriber
8+
def initialize
9+
@logger = Appsignal::Logger.new("rails_events")
10+
end
11+
12+
def emit(event)
13+
@logger.info(event[:name], event[:payload])
14+
end
15+
end
16+
end
17+
end
18+
end
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
describe Appsignal::Hooks::ActiveSupportEventReporterHook do
2+
begin
3+
require "active_support/event_reporter"
4+
rescue LoadError
5+
end
6+
7+
describe "#dependencies_present?" do
8+
subject { described_class.new.dependencies_present? }
9+
10+
if DependencyHelper.rails8_1_present?
11+
context "when ActiveSupport::EventReporter is present" do
12+
it { is_expected.to be_truthy }
13+
end
14+
else
15+
context "when ActiveSupport::EventReporter is not present" do
16+
it { is_expected.to be_falsy }
17+
end
18+
end
19+
end
20+
21+
if defined?(::ActiveSupport::EventReporter)
22+
describe "#install" do
23+
before do
24+
# Mock Rails.event
25+
stub_const("MockEventReporter", Class.new do
26+
attr_reader :subscribers
27+
28+
def initialize
29+
@subscribers = []
30+
end
31+
32+
def subscribe(subscriber)
33+
@subscribers << subscriber
34+
end
35+
end)
36+
37+
mock_event_reporter = MockEventReporter.new
38+
39+
allow(Rails).to receive(:event).and_return(mock_event_reporter)
40+
end
41+
42+
it "subscribes the ActiveSupportEventReporter::Subscriber to Rails.event" do
43+
event_reporter = Rails.event
44+
expect(event_reporter.subscribers).to be_empty
45+
46+
described_class.new.install
47+
48+
expect(event_reporter.subscribers.length).to eq(1)
49+
expect(event_reporter.subscribers.first).to be_a(Appsignal::Integrations::ActiveSupportEventReporter::Subscriber)
50+
end
51+
end
52+
end
53+
end
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
require "appsignal/integrations/active_support_event_reporter"
2+
3+
describe Appsignal::Integrations::ActiveSupportEventReporter::Subscriber do
4+
let(:subscriber) { described_class.new }
5+
let(:logger) { instance_double(Appsignal::Logger) }
6+
7+
before do
8+
start_agent
9+
allow(Appsignal::Logger).to receive(:new).with("rails_events").and_return(logger)
10+
end
11+
12+
describe "#emit" do
13+
it "logs the event name and payload" do
14+
event = {
15+
:name => "user.created",
16+
:payload => { :id => 123, :email => "[email protected]" },
17+
}
18+
19+
expect(logger).to receive(:info).with("user.created", { :id => 123, :email => "[email protected]" })
20+
21+
subscriber.emit(event)
22+
end
23+
end
24+
end

spec/support/helpers/dependency_helper.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ def rails7_1_present?
4949
rails_present? && rails_version >= Gem::Version.new("7.1.0")
5050
end
5151

52+
def rails8_1_present?
53+
rails_present? && rails_version >= Gem::Version.new("8.1.0")
54+
end
55+
5256
def active_job_wraps_args?
5357
rails7_present? || (ruby_3_1_or_newer? && rails6_1_present? && !rails6_1_5_present?)
5458
end

0 commit comments

Comments
 (0)