Skip to content

Commit 1846a60

Browse files
authored
feat: rails autoinstrumentation (#62)
feat: rails autoinstrumentation
2 parents 7fa7c3e + 02a0435 commit 1846a60

File tree

1 file changed

+53
-13
lines changed

1 file changed

+53
-13
lines changed

pyroscope_ffi/ruby/lib/pyroscope.rb

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,32 @@ module Utils
2222
attach_function :thread_id, [], :uint64
2323
end
2424

25-
Config = Struct.new(:application_name, :app_name, :server_address, :auth_token, :log_level, :sample_rate, :detect_subprocesses, :oncpu, :report_pid, :report_thread_id, :tags, :compression, :report_encoding) do
25+
if defined?(::Rails::Engine)
26+
class Engine < ::Rails::Engine
27+
config.after_initialize do
28+
next unless ::Pyroscope.current_config && ::Pyroscope.current_config.autoinstrument_rails
29+
30+
::Pyroscope.initialize_rails_hooks
31+
end
32+
end
33+
end
34+
35+
Config = Struct.new(
36+
:application_name,
37+
:app_name,
38+
:server_address,
39+
:auth_token,
40+
:log_level,
41+
:sample_rate,
42+
:detect_subprocesses,
43+
:oncpu,
44+
:report_pid,
45+
:report_thread_id,
46+
:tags,
47+
:compression,
48+
:report_encoding,
49+
:autoinstrument_rails,
50+
) do
2651
def initialize(*)
2752
super
2853
# defaults:
@@ -38,10 +63,15 @@ def initialize(*)
3863
self.tags = {}
3964
self.compression = 'gzip'
4065
self.report_encoding = 'pprof'
66+
self.autoinstrument_rails = true
4167
end
4268
end
4369

4470
class << self
71+
def current_config
72+
@config
73+
end
74+
4575
def configure
4676
@config = Config.new
4777

@@ -64,11 +94,8 @@ def configure
6494
@log_level = 50
6595
end
6696

67-
# Initialize Logging
6897
Rust.initialize_logging(@log_level)
6998

70-
71-
# initialize Pyroscope Agent
7299
Rust.initialize_agent(
73100
# these are defaults in case user-provided values are nil:
74101
@config.app_name || @config.application_name || "",
@@ -85,6 +112,17 @@ def configure
85112
)
86113
end
87114

115+
def initialize_rails_hooks
116+
block = lambda do |ctrl, action|
117+
Pyroscope.tag_wrapper({
118+
"action" => "#{ctrl.controller_name}/#{ctrl.action_name}"
119+
}, &action)
120+
end
121+
122+
ActionController::API.__send__(:around_action, block) if defined? ActionController::API
123+
ActionController::Base.__send__(:around_action, block) if defined? ActionController::Base
124+
end
125+
88126
def tag_wrapper(tags)
89127
tid = thread_id
90128
_add_tags(tid, tags)
@@ -103,32 +141,34 @@ def remove_tags(*tags)
103141
warn("deprecated. Use `Pyroscope.tag_wrapper` instead.")
104142
end
105143

106-
# convert tags object to string
107-
def tags_to_string(tags)
108-
tags.map { |k, v| "#{k}=#{v}" }.join(',')
109-
end
110-
111-
# get thread id
112144
def thread_id
113145
return Utils.thread_id
114146
end
115147

116-
# add tags
117148
def _add_tags(thread_id, tags)
118149
tags.each do |tag_name, tag_value|
119150
Rust.add_thread_tag(thread_id, tag_name.to_s, tag_value.to_s)
120151
end
121152
end
122153

123-
# remove tags
124154
def _remove_tags(thread_id, tags)
125155
tags.each do |tag_name, tag_value|
126156
Rust.remove_thread_tag(thread_id, tag_name.to_s, tag_value.to_s)
127157
end
128158
end
129159

130-
def shutdown
160+
def stop
131161
Rust.drop_agent
132162
end
163+
164+
def shutdown
165+
stop
166+
end
167+
168+
private
169+
170+
def tags_to_string(tags)
171+
tags.map { |k, v| "#{k}=#{v}" }.join(',')
172+
end
133173
end
134174
end

0 commit comments

Comments
 (0)