plain_apm 0.9.2 → 0.9.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/plain_apm/agent.rb +42 -20
- data/lib/plain_apm/event_attributes.rb +70 -56
- data/lib/plain_apm/extensions/context/railtie.rb +11 -17
- data/lib/plain_apm/extensions/context.rb +4 -0
- data/lib/plain_apm/extensions/exceptions/active_job.rb +1 -1
- data/lib/plain_apm/extensions/exceptions/rack.rb +2 -2
- data/lib/plain_apm/extensions/exceptions/railtie.rb +5 -11
- data/lib/plain_apm/extensions/exceptions.rb +3 -0
- data/lib/plain_apm/extensions/thread_allocations/active_support_event.rb +2 -8
- data/lib/plain_apm/extensions/thread_allocations/railtie.rb +9 -13
- data/lib/plain_apm/extensions/thread_allocations.rb +2 -0
- data/lib/plain_apm/helpers.rb +2 -1
- data/lib/plain_apm/hooks/action_mailer.rb +11 -9
- data/lib/plain_apm/hooks/action_pack.rb +11 -9
- data/lib/plain_apm/hooks/action_view.rb +20 -18
- data/lib/plain_apm/hooks/active_job.rb +21 -19
- data/lib/plain_apm/hooks/active_record.rb +10 -2
- data/lib/plain_apm/hooks/active_support.rb +23 -21
- data/lib/plain_apm/hooks/active_support_subscriber.rb +0 -7
- data/lib/plain_apm/hooks/error_reporter.rb +2 -2
- data/lib/plain_apm/hooks/manual.rb +6 -6
- data/lib/plain_apm/queue.rb +123 -0
- data/lib/plain_apm/transport.rb +1 -1
- data/lib/plain_apm/version.rb +1 -1
- data/lib/plain_apm.rb +23 -26
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a2950f7d2e02a813b67a5bfb4c2ff7cc522acb8770404e3ef3dcef4e13aa4c4c
|
4
|
+
data.tar.gz: 4af16bf90b9904db8f5adf9efc6438aec2a6f31954a481f1a3384fbdadddf1d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6ceba3781efda4b4b60dc66f85ed07a065b47c624d7c6da2fbd42d52bc525cf2b95204d9030aa6e5540e7f6e5e6112b387a40008b29c69236cedcbeb9ae62e69
|
7
|
+
data.tar.gz: '08dcda87123a5e006442cfe574da4ee41c011a28880b559a19bb65871785eb06154ba19f86c00d159c7d0c3e40b22c9758b6a373150de1344a001062fab0cd96'
|
data/lib/plain_apm/agent.rb
CHANGED
@@ -6,16 +6,15 @@ module PlainApm
|
|
6
6
|
class Agent
|
7
7
|
include Singleton
|
8
8
|
|
9
|
-
def
|
10
|
-
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.start
|
14
|
-
instance.start
|
9
|
+
def enabled?
|
10
|
+
@config && @config.enabled
|
15
11
|
end
|
16
12
|
|
17
13
|
def collect(event)
|
18
|
-
return unless
|
14
|
+
return unless enabled?
|
15
|
+
|
16
|
+
# stop accepting events when shutting down / shutdown.
|
17
|
+
return if @status != :running
|
19
18
|
|
20
19
|
publisher_start if @pid != $$
|
21
20
|
|
@@ -31,7 +30,7 @@ module PlainApm
|
|
31
30
|
|
32
31
|
configure
|
33
32
|
|
34
|
-
return unless
|
33
|
+
return unless enabled?
|
35
34
|
|
36
35
|
warn("PlainAPM agent enabled.")
|
37
36
|
|
@@ -54,11 +53,13 @@ module PlainApm
|
|
54
53
|
# Already running
|
55
54
|
return if @publisher&.alive?
|
56
55
|
|
57
|
-
# TODO: sized queue
|
58
|
-
@events =
|
56
|
+
# TODO: sized queue.
|
57
|
+
@events = PlainApm::Queue.new
|
59
58
|
|
60
59
|
# TODO: Multiple threads
|
61
60
|
@publisher = Thread.new { publisher_loop }
|
61
|
+
|
62
|
+
@status = :running
|
62
63
|
end
|
63
64
|
|
64
65
|
def setup_at_exit_hooks
|
@@ -70,6 +71,7 @@ module PlainApm
|
|
70
71
|
|
71
72
|
# FIXME: raise in / kill the threads after a pre-determined timeout not
|
72
73
|
# to block
|
74
|
+
@status = :shutting_down
|
73
75
|
@events << nil
|
74
76
|
@publisher.join
|
75
77
|
@publisher = nil
|
@@ -110,18 +112,38 @@ module PlainApm
|
|
110
112
|
app_key: @config.app_key
|
111
113
|
)
|
112
114
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
Thread.exit if event.nil?
|
115
|
+
buf = []
|
116
|
+
timeout = 1.0
|
117
117
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
118
|
+
loop do
|
119
|
+
event = @events.pop(timeout: timeout)
|
120
|
+
|
121
|
+
buf << event if event
|
122
|
+
|
123
|
+
case @status
|
124
|
+
when :running
|
125
|
+
# not a timeout or full buffer
|
126
|
+
next if !event.nil? && buf.size < 128
|
127
|
+
send(transport, buf)
|
128
|
+
buf = []
|
129
|
+
when :shutting_down
|
130
|
+
send(transport, buf)
|
131
|
+
buf = []
|
132
|
+
@status = :shutdown
|
133
|
+
break
|
134
|
+
when :shutdown
|
135
|
+
nil
|
136
|
+
else
|
137
|
+
# ?
|
138
|
+
end
|
124
139
|
end
|
125
140
|
end
|
141
|
+
|
142
|
+
# TODO: retries / drops
|
143
|
+
def send(transport, buf)
|
144
|
+
return if buf.empty?
|
145
|
+
meta = { queue: @events.size, pid: $$, thread: Thread.current.object_id, sent_at: Time.now.to_f }
|
146
|
+
_response, _error, _retriable = transport.deliver(buf, meta)
|
147
|
+
end
|
126
148
|
end
|
127
149
|
end
|
@@ -21,34 +21,45 @@ module PlainApm
|
|
21
21
|
|
22
22
|
return [source, nil] if IGNORED_EXCEPTIONS.include?(e.class.name)
|
23
23
|
|
24
|
-
attrs =
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
24
|
+
attrs = context_attributes
|
25
|
+
|
26
|
+
attrs[:class] = e.class.name
|
27
|
+
attrs[:message] = e.message
|
28
|
+
attrs[:backtrace] = e.backtrace
|
29
29
|
|
30
30
|
if error_source
|
31
|
-
attrs[
|
31
|
+
attrs[:event_source] = error_source
|
32
32
|
end
|
33
33
|
|
34
34
|
if context[:env]
|
35
|
-
attrs[
|
35
|
+
attrs[:params] = context[:env]["action_dispatch.request.parameters"]
|
36
36
|
end
|
37
37
|
|
38
38
|
if context[:job]&.is_a?(ActiveJob::Base)
|
39
|
-
attrs[
|
40
|
-
attrs[
|
39
|
+
attrs[:job_class] = context[:job].class.name
|
40
|
+
attrs[:queue_name] = context[:job].queue_name
|
41
|
+
end
|
42
|
+
|
43
|
+
# https://bugs.ruby-lang.org/issues/19197
|
44
|
+
root_cause = e
|
45
|
+
root_cause = root_cause.cause while root_cause.cause
|
46
|
+
|
47
|
+
if root_cause != e
|
48
|
+
attrs[:root_cause_class] = root_cause.class.name
|
49
|
+
attrs[:root_cause_message] = root_cause.message
|
50
|
+
attrs[:root_cause_backtrace] = root_cause.backtrace
|
51
|
+
loc = source_location(root_cause.backtrace)
|
52
|
+
if !loc.nil?
|
53
|
+
attrs[:root_cause_location] = loc
|
54
|
+
end
|
41
55
|
end
|
42
56
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
"cause_message" => e.cause.message,
|
47
|
-
"cause_backtrace" => e.cause.backtrace
|
48
|
-
})
|
57
|
+
loc = source_location(e.backtrace)
|
58
|
+
if !loc.nil?
|
59
|
+
attrs[:source_location] = loc
|
49
60
|
end
|
50
61
|
|
51
|
-
attrs
|
62
|
+
add_trace_attributes(attrs)
|
52
63
|
|
53
64
|
[source, attrs]
|
54
65
|
end
|
@@ -57,70 +68,73 @@ module PlainApm
|
|
57
68
|
name, source = *event.name.split(".")
|
58
69
|
loc = source_location
|
59
70
|
|
60
|
-
attrs =
|
61
|
-
"source" => source,
|
62
|
-
"name" => name,
|
63
|
-
"allocations" => event.allocations,
|
64
|
-
"event_time" => event.time,
|
65
|
-
"duration" => event.duration
|
66
|
-
}
|
71
|
+
attrs = context_attributes
|
67
72
|
|
68
|
-
attrs[
|
69
|
-
attrs[
|
73
|
+
attrs[:source] = source
|
74
|
+
attrs[:name] = name
|
75
|
+
attrs[:allocations] = event.allocations
|
76
|
+
attrs[:event_time] = event.time
|
77
|
+
attrs[:duration] = event.duration
|
70
78
|
|
71
|
-
|
79
|
+
if event.respond_to?(:thread_allocations)
|
80
|
+
attrs[:thread_allocations] = event.thread_allocations
|
81
|
+
end
|
82
|
+
|
83
|
+
if !loc.nil?
|
84
|
+
attrs[:source_location] = loc
|
85
|
+
end
|
86
|
+
|
87
|
+
add_trace_attributes(attrs)
|
72
88
|
|
73
89
|
[name, attrs]
|
74
90
|
end
|
75
91
|
|
76
92
|
private
|
77
93
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
# the feature.
|
89
|
-
"pid" => Process.pid,
|
90
|
-
"version" => PlainApm::VERSION
|
91
|
-
}.merge(
|
92
|
-
cached_attributes
|
93
|
-
)
|
94
|
+
# TODO: There is a perf cost in Rubies for Process.pid until 3.3, so it
|
95
|
+
# might be a good idea to cache this. See
|
96
|
+
# https://bugs.ruby-lang.org/issues/19443 for the feature.
|
97
|
+
def add_trace_attributes(attrs)
|
98
|
+
attrs[:thread_id] = Thread.current.object_id
|
99
|
+
attrs[:collected_at] = Time.now.to_f
|
100
|
+
attrs[:pid] = Process.pid
|
101
|
+
attrs[:version] = PlainApm::VERSION
|
102
|
+
attrs[:hostname] = cached_attributes[:hostname]
|
103
|
+
attrs[:revision] = cached_attributes[:revision]
|
94
104
|
end
|
95
105
|
|
96
106
|
def cached_attributes
|
97
107
|
@cached_attributes ||= {
|
98
|
-
|
99
|
-
|
108
|
+
hostname: Socket.gethostname,
|
109
|
+
revision: PlainApm::DeployTracking.revision
|
100
110
|
}
|
101
111
|
end
|
102
112
|
|
113
|
+
##
|
114
|
+
# Context contains the trace ID (which comes from either
|
115
|
+
# HTTP_X_REQUEST_ID header, the deserialized job,
|
116
|
+
# or is generated by the trace_id middleware).
|
117
|
+
# It can also carry user inserted app data.
|
103
118
|
def context_attributes
|
104
|
-
##
|
105
|
-
# Context contains the trace ID (which comes from either
|
106
|
-
# HTTP_X_REQUEST_ID header, the deserialized job,
|
107
|
-
# or is generated by the trace_id middleware).
|
108
|
-
# It can also carry user inserted app data.
|
109
119
|
if defined?(PlainApm::Extensions::Context)
|
110
|
-
PlainApm::Extensions::Context.current.
|
120
|
+
PlainApm::Extensions::Context.current.dup
|
111
121
|
else
|
112
122
|
{}
|
113
123
|
end
|
114
124
|
end
|
115
125
|
|
116
|
-
def source_location
|
117
|
-
|
126
|
+
def source_location(backtrace = nil)
|
127
|
+
return if self.class.rails_root.nil?
|
128
|
+
call = (backtrace || caller).find { |frame| frame.start_with?(self.class.rails_root) } || return
|
129
|
+
call[(self.class.rails_root.size + 1)..-1]
|
118
130
|
end
|
119
131
|
|
120
|
-
def
|
121
|
-
|
122
|
-
|
123
|
-
|
132
|
+
def self.included(other)
|
133
|
+
other.class_eval do
|
134
|
+
def self.rails_root
|
135
|
+
return @rails_root if defined?(@rails_root)
|
136
|
+
@rails_root = (defined?(Rails) && Rails.root.to_s.present?) ? Rails.root.to_s.freeze : nil
|
137
|
+
end
|
124
138
|
end
|
125
139
|
end
|
126
140
|
end
|
@@ -7,27 +7,21 @@
|
|
7
7
|
#
|
8
8
|
# See LICENSE.txt in the current directory for the license.
|
9
9
|
|
10
|
-
begin
|
11
|
-
require "rails/railtie"
|
12
|
-
rescue LoadError
|
13
|
-
nil
|
14
|
-
end
|
15
|
-
|
16
10
|
module PlainApm
|
17
11
|
module Extensions
|
18
12
|
module Context
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
13
|
+
class Railtie < Rails::Railtie
|
14
|
+
initializer(:plain_apm_thread_context, after: :plain_apm_agent_start) do |app|
|
15
|
+
next if !PlainApm.agent.enabled?
|
16
|
+
|
17
|
+
ActiveSupport.on_load(:active_job, run_once: true) do |klass|
|
18
|
+
klass.prepend(PlainApm::Extensions::Context::ActiveJob)
|
19
|
+
end
|
25
20
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
end
|
21
|
+
if defined?(ActionDispatch::RequestId)
|
22
|
+
app.config.middleware.insert_after ActionDispatch::RequestId, PlainApm::Extensions::Context::Rack
|
23
|
+
else
|
24
|
+
app.config.middleware.insert_after Rack::MethodOverride, PlainApm::Extensions::Context::Rack
|
31
25
|
end
|
32
26
|
end
|
33
27
|
end
|
@@ -1,19 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
begin
|
4
|
-
require "rails/railtie"
|
5
|
-
rescue LoadError
|
6
|
-
nil
|
7
|
-
end
|
8
|
-
|
9
3
|
module PlainApm
|
10
4
|
module Extensions
|
11
5
|
module Exceptions
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
6
|
+
class Railtie < Rails::Railtie
|
7
|
+
initializer(:plain_apm_exceptions_middleware, after: :plain_apm_agent_start) do |app|
|
8
|
+
next if !PlainApm.agent.enabled?
|
9
|
+
|
10
|
+
app.config.middleware.insert(0, PlainApm::Extensions::Exceptions::Rack)
|
17
11
|
end
|
18
12
|
end
|
19
13
|
end
|
@@ -16,14 +16,8 @@ module PlainApm
|
|
16
16
|
@thread_allocation_count_finish - @thread_allocation_count_start
|
17
17
|
end
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
PlainApm::ObjectTracing.total_thread_allocated_objects
|
22
|
-
end
|
23
|
-
else
|
24
|
-
def now_thread_allocations
|
25
|
-
0
|
26
|
-
end
|
19
|
+
def now_thread_allocations
|
20
|
+
PlainApm::ObjectTracing.total_thread_allocated_objects
|
27
21
|
end
|
28
22
|
end
|
29
23
|
end
|
@@ -1,21 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
begin
|
4
|
-
require "rails/railtie"
|
5
|
-
rescue LoadError
|
6
|
-
nil
|
7
|
-
end
|
8
|
-
|
9
3
|
module PlainApm
|
10
4
|
module Extensions
|
11
5
|
module ThreadAllocations
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
6
|
+
class Railtie < Rails::Railtie
|
7
|
+
initializer(:plain_apm_thread_allocationss, after: :plain_apm_agent_start) do
|
8
|
+
next if !PlainApm.agent.enabled?
|
9
|
+
|
10
|
+
require "object_tracing"
|
11
|
+
|
12
|
+
ActiveSupport::Notifications::Event.prepend(
|
13
|
+
PlainApm::Extensions::ThreadAllocations::ActiveSupportEvent
|
14
|
+
)
|
19
15
|
end
|
20
16
|
end
|
21
17
|
end
|
data/lib/plain_apm/helpers.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
module PlainApm
|
2
2
|
module Helpers
|
3
3
|
def plain_apm_context(context = {})
|
4
|
+
return unless PlainApm.agent.enabled?
|
4
5
|
PlainApm::Extensions::Context.context.merge!(context)
|
5
6
|
end
|
6
7
|
|
7
8
|
def plain_apm_instrument(name, context = {}, &block)
|
9
|
+
return unless PlainApm.agent.enabled? && defined?(ActiveSupport::Notifications)
|
8
10
|
sanitized_name = name.gsub(/\W/, "_").gsub(/(?!^)([A-Z])/) { |m| "_#{m}" }.squeeze("_").downcase
|
9
|
-
return unless defined?(ActiveSupport::Notifications)
|
10
11
|
ActiveSupport::Notifications.instrument("#{sanitized_name}.manual_plain_apm", **context, &block)
|
11
12
|
end
|
12
13
|
end
|
@@ -17,16 +17,18 @@ module PlainApm
|
|
17
17
|
|
18
18
|
case name
|
19
19
|
when "deliver"
|
20
|
-
base.
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
base.tap do |o|
|
21
|
+
o[:message_id] = payload[:message_id]
|
22
|
+
o[:mailer] = payload[:mailer]
|
23
|
+
o[:perform_deliveries] = payload[:perform_deliveries]
|
24
|
+
end
|
25
25
|
when "process"
|
26
|
-
base.
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
base.tap do |o|
|
27
|
+
o[:mailer] = payload[:mailer]
|
28
|
+
o[:action] = payload[:action]
|
29
|
+
end
|
30
|
+
else
|
31
|
+
nil
|
30
32
|
end
|
31
33
|
end
|
32
34
|
end
|
@@ -17,20 +17,22 @@ module PlainApm
|
|
17
17
|
|
18
18
|
case name
|
19
19
|
when "process_action"
|
20
|
-
base.
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
20
|
+
base.tap do |o|
|
21
|
+
o[:controller] = payload[:controller]
|
22
|
+
o[:action] = payload[:action]
|
23
|
+
o[:params] = payload[:params]
|
24
|
+
o[:format] = payload[:format]
|
25
|
+
o[:method] = payload[:method]
|
26
|
+
o[:path] = payload[:path]
|
27
|
+
o[:status] = payload[:status]
|
28
|
+
end
|
29
29
|
when "redirect_to", "start_processing", "halted_callback", "send_file", "send_data"
|
30
30
|
nil
|
31
31
|
when "read_fragment", "write_fragment", "exist_fragment?", "expire_fragment"
|
32
32
|
# controller, action, key
|
33
33
|
nil
|
34
|
+
else
|
35
|
+
nil
|
34
36
|
end
|
35
37
|
end
|
36
38
|
end
|
@@ -17,27 +17,29 @@ module PlainApm
|
|
17
17
|
|
18
18
|
case name
|
19
19
|
when "render_collection"
|
20
|
-
base.
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
base.tap do |o|
|
21
|
+
o[:identifier] = identifier(payload[:identifier])
|
22
|
+
o[:layout] = payload[:layout]
|
23
|
+
o[:count] = payload[:count]
|
24
|
+
o[:cache_hits] = payload[:cache_hits]
|
25
|
+
end
|
26
26
|
when "render_layout"
|
27
|
-
base.
|
28
|
-
|
29
|
-
|
27
|
+
base.tap do |o|
|
28
|
+
o[:identifier] = identifier(payload[:identifier])
|
29
|
+
end
|
30
30
|
when "render_template"
|
31
|
-
base.
|
32
|
-
|
33
|
-
|
34
|
-
|
31
|
+
base.tap do |o|
|
32
|
+
o[:identifier] = identifier(payload[:identifier])
|
33
|
+
o[:layout] = payload[:layout]
|
34
|
+
end
|
35
35
|
when "render_partial"
|
36
|
-
base.
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
36
|
+
base.tap do |o|
|
37
|
+
o[:identifier] = identifier(payload[:identifier])
|
38
|
+
o[:layout] = payload[:layout]
|
39
|
+
o[:cache_hit] = payload[:cache_hit]
|
40
|
+
end
|
41
|
+
else
|
42
|
+
nil
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
@@ -16,33 +16,35 @@ module PlainApm
|
|
16
16
|
payload = event.payload
|
17
17
|
job = payload[:job]
|
18
18
|
|
19
|
-
base.
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
19
|
+
base.tap do |o|
|
20
|
+
o[:queue_name] = job.queue_name
|
21
|
+
o[:job_id] = job.job_id
|
22
|
+
o[:job_class] = job.class.name
|
23
|
+
o[:job_arguments] = job.arguments
|
24
|
+
o[:executions] = job.executions
|
25
|
+
o[:enqueued_at] = enqueued_at(job)
|
26
|
+
o[:dequeued_at] = dequeued_at(job)
|
27
|
+
o[:scheduled_at] = job.scheduled_at
|
28
|
+
o[:adapter] = payload[:adapter].class.name
|
29
|
+
o[:aborted] = payload[:aborted]
|
30
|
+
end
|
31
31
|
|
32
32
|
case name
|
33
33
|
when "enqueue", "enqueue_at", "perform"
|
34
34
|
base
|
35
35
|
when "enqueue_retry"
|
36
|
-
base.
|
37
|
-
|
38
|
-
|
39
|
-
|
36
|
+
base.tap do |o|
|
37
|
+
o[:error] = payload[:error]
|
38
|
+
o[:wait] = payload[:wait]
|
39
|
+
end
|
40
40
|
when "retry_stopped", "discard"
|
41
|
-
base.
|
42
|
-
|
43
|
-
|
41
|
+
base.tap do |o|
|
42
|
+
o[:error] = payload[:error]
|
43
|
+
end
|
44
44
|
when "perform_start"
|
45
45
|
nil
|
46
|
+
else
|
47
|
+
nil
|
46
48
|
end
|
47
49
|
end
|
48
50
|
|
@@ -22,9 +22,17 @@ module PlainApm
|
|
22
22
|
|
23
23
|
case name
|
24
24
|
when "sql"
|
25
|
-
base.
|
25
|
+
base.tap do |o|
|
26
|
+
o[:sql] = payload[:sql]
|
27
|
+
o[:sql_name] = payload[:name]
|
28
|
+
end
|
26
29
|
when "instantiation"
|
27
|
-
base.
|
30
|
+
base.tap do |o|
|
31
|
+
o[:class_name] = payload[:class_name]
|
32
|
+
o[:record_count] = payload[:record_count]
|
33
|
+
end
|
34
|
+
else
|
35
|
+
nil
|
28
36
|
end
|
29
37
|
end
|
30
38
|
end
|
@@ -15,34 +15,36 @@ module PlainApm
|
|
15
15
|
name, base = attributes_from_notification(event)
|
16
16
|
payload = event.payload
|
17
17
|
|
18
|
-
base[
|
18
|
+
base[:store] = payload[:store]
|
19
19
|
|
20
20
|
case name
|
21
21
|
when "cache_read"
|
22
|
-
base.
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
22
|
+
base.tap do |o|
|
23
|
+
o[:key] = payload[:key]
|
24
|
+
o[:hit] = payload[:hit]
|
25
|
+
o[:trigger] = payload[:super_operation]
|
26
|
+
end
|
27
27
|
when "cache_read_multi"
|
28
|
-
base.
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
base.tap do |o|
|
29
|
+
o[:keys] = payload[:key]
|
30
|
+
o[:hits] = payload[:hits]
|
31
|
+
end
|
32
32
|
when "cache_fetch_hit"
|
33
|
-
base.
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
base.tap do |o|
|
34
|
+
o[:key] = payload[:key]
|
35
|
+
o[:hit] = true
|
36
|
+
end
|
37
37
|
when "cache_write", "cache_write_multi", "cache_generate", "cache_delete", "cache_delete_matched", "cache_exist?"
|
38
|
-
base.
|
39
|
-
|
40
|
-
|
38
|
+
base.tap do |o|
|
39
|
+
o[:key] = payload[:key]
|
40
|
+
end
|
41
41
|
when "cache_increment", "cache_decrement"
|
42
|
-
base.
|
43
|
-
|
44
|
-
|
45
|
-
|
42
|
+
base.tap do |o|
|
43
|
+
o[:key] = payload[:key]
|
44
|
+
o[:amount] = payload[:amount]
|
45
|
+
end
|
46
|
+
else
|
47
|
+
nil
|
46
48
|
end
|
47
49
|
end
|
48
50
|
end
|
@@ -14,12 +14,12 @@ module PlainApm
|
|
14
14
|
def payload(event)
|
15
15
|
name, base = attributes_from_notification(event)
|
16
16
|
|
17
|
-
base.
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
17
|
+
base.tap do |o|
|
18
|
+
o[:source] = "user"
|
19
|
+
o[:name] = "manual"
|
20
|
+
o[:payload_name] = name
|
21
|
+
o[:payload] = event.payload
|
22
|
+
end
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
module PlainApm
|
2
|
+
if RUBY_VERSION >= "3.2.0"
|
3
|
+
Queue = Thread::Queue
|
4
|
+
else
|
5
|
+
# The queue is made to conform to the ruby/spec
|
6
|
+
class Queue
|
7
|
+
ClosedQueueError = Class.new(StopIteration)
|
8
|
+
|
9
|
+
def initialize(initial = nil)
|
10
|
+
@data = []
|
11
|
+
@num_waiting = 0
|
12
|
+
@closed = false
|
13
|
+
@mutex = Mutex.new
|
14
|
+
@cv = ConditionVariable.new
|
15
|
+
|
16
|
+
return if initial.nil?
|
17
|
+
|
18
|
+
raise TypeError, "can't convert #{initial.class} into Array" unless initial.respond_to?(:to_a)
|
19
|
+
|
20
|
+
elems = initial.to_a
|
21
|
+
raise TypeError, "can't convert #{initial.class} into Array (#{initial.class}#to_a gives #{elems.class})" unless elems.is_a?(Array)
|
22
|
+
|
23
|
+
@data.concat(elems)
|
24
|
+
end
|
25
|
+
|
26
|
+
def close
|
27
|
+
@mutex.synchronize do
|
28
|
+
return if @closed
|
29
|
+
@closed = true
|
30
|
+
# Wake up everyone waiting on this.
|
31
|
+
@cv.broadcast
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def closed?
|
36
|
+
@closed
|
37
|
+
end
|
38
|
+
|
39
|
+
def clear
|
40
|
+
@data = []
|
41
|
+
end
|
42
|
+
|
43
|
+
def num_waiting
|
44
|
+
@num_waiting
|
45
|
+
end
|
46
|
+
|
47
|
+
def empty?
|
48
|
+
@data.empty?
|
49
|
+
end
|
50
|
+
|
51
|
+
def length
|
52
|
+
@data.length
|
53
|
+
end
|
54
|
+
|
55
|
+
alias_method :size, :length
|
56
|
+
|
57
|
+
def push(obj)
|
58
|
+
@mutex.synchronize do
|
59
|
+
raise ClosedQueueError if closed?
|
60
|
+
@data << obj
|
61
|
+
@cv.signal
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
alias_method :<<, :push
|
66
|
+
alias_method :enq, :push
|
67
|
+
|
68
|
+
def pop(non_block = false, timeout: nil)
|
69
|
+
if non_block && timeout
|
70
|
+
raise ArgumentError, "can't set a timeout if non_block is enabled"
|
71
|
+
end
|
72
|
+
|
73
|
+
if !timeout.nil? && !timeout.is_a?(Numeric)
|
74
|
+
raise TypeError, "no implicit conversion to float from #{timeout.class.name.downcase}"
|
75
|
+
end
|
76
|
+
|
77
|
+
@mutex.synchronize do
|
78
|
+
# The data is there.
|
79
|
+
return @data.shift if !@data.empty?
|
80
|
+
|
81
|
+
# Non block raises on empty queue
|
82
|
+
raise ThreadError, "queue empty" if non_block
|
83
|
+
|
84
|
+
# 0 means immediate timeout. Closed empty queue also immediately returns a nil
|
85
|
+
return nil if timeout == 0 || @closed
|
86
|
+
|
87
|
+
# Blocking and open. Let's wait.
|
88
|
+
timeout_at = timeout.nil? ? nil : now + timeout.to_f
|
89
|
+
|
90
|
+
begin
|
91
|
+
# We could keep the threads in an array, but a counter should do as well.
|
92
|
+
@num_waiting += 1
|
93
|
+
|
94
|
+
while @data.empty? && !@closed
|
95
|
+
if timeout_at.nil?
|
96
|
+
# Wait indefinitely.
|
97
|
+
@cv.wait(@mutex)
|
98
|
+
else
|
99
|
+
# Wait for what's left of the deadline
|
100
|
+
break if (left = timeout_at - now) <= 0.0
|
101
|
+
@cv.wait(@mutex, left)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
ensure
|
105
|
+
@num_waiting -= 1
|
106
|
+
end
|
107
|
+
|
108
|
+
# Return whatever is there now, or nil (if timed out)
|
109
|
+
@data.shift
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
alias_method :deq, :pop
|
114
|
+
alias_method :shift, :pop
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
def now
|
119
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
data/lib/plain_apm/transport.rb
CHANGED
data/lib/plain_apm/version.rb
CHANGED
data/lib/plain_apm.rb
CHANGED
@@ -1,13 +1,31 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# Rails deps
|
4
|
+
begin
|
5
|
+
require "active_support"
|
6
|
+
require "active_support/notifications"
|
7
|
+
require "rails/railtie"
|
8
|
+
rescue LoadError
|
9
|
+
nil
|
10
|
+
end
|
11
|
+
|
3
12
|
require_relative "plain_apm/version"
|
4
13
|
require_relative "plain_apm/transport"
|
14
|
+
require_relative "plain_apm/queue"
|
5
15
|
require_relative "plain_apm/config"
|
6
16
|
require_relative "plain_apm/agent"
|
7
17
|
require_relative "plain_apm/deploy_tracking"
|
8
18
|
require_relative "plain_apm/event_attributes"
|
19
|
+
require_relative "plain_apm/helpers"
|
20
|
+
|
21
|
+
# Per thread context for request IDs / job IDs.
|
22
|
+
require_relative "plain_apm/extensions/context"
|
9
23
|
|
10
|
-
|
24
|
+
# Rack exceptions. Activate the middleware if in Rails.
|
25
|
+
require_relative "plain_apm/extensions/exceptions"
|
26
|
+
|
27
|
+
# Per thread allocations in ASN events
|
28
|
+
require_relative "plain_apm/extensions/thread_allocations"
|
11
29
|
|
12
30
|
# Rails instrumentation. The hooks won't install unless
|
13
31
|
# ActiveSupport::Notifications is loaded.
|
@@ -21,23 +39,6 @@ require_relative "plain_apm/hooks/active_support"
|
|
21
39
|
require_relative "plain_apm/hooks/manual"
|
22
40
|
require_relative "plain_apm/hooks/error_reporter"
|
23
41
|
|
24
|
-
# Per thread context for request IDs / job IDs.
|
25
|
-
require_relative "plain_apm/extensions/context"
|
26
|
-
require_relative "plain_apm/extensions/context/rack"
|
27
|
-
require_relative "plain_apm/extensions/context/active_job"
|
28
|
-
require_relative "plain_apm/extensions/context/railtie"
|
29
|
-
|
30
|
-
# Per thread allocations in ASN events
|
31
|
-
require_relative "plain_apm/extensions/thread_allocations/active_support_event"
|
32
|
-
require_relative "plain_apm/extensions/thread_allocations/railtie"
|
33
|
-
|
34
|
-
# Helpers du jour.
|
35
|
-
require_relative "plain_apm/helpers"
|
36
|
-
|
37
|
-
# Rack exceptions. Activate the middleware if in Rails.
|
38
|
-
require_relative "plain_apm/extensions/exceptions/rack"
|
39
|
-
require_relative "plain_apm/extensions/exceptions/railtie"
|
40
|
-
|
41
42
|
module PlainApm
|
42
43
|
# Allow swapping out the Agent for a synchronous, in-memory implementation in
|
43
44
|
# the tests.
|
@@ -49,16 +50,12 @@ module PlainApm
|
|
49
50
|
@@agent ||= Agent.instance
|
50
51
|
end
|
51
52
|
|
52
|
-
begin
|
53
|
-
require "rails/railtie"
|
54
|
-
rescue LoadError
|
55
|
-
nil
|
56
|
-
end
|
57
|
-
|
58
|
-
# after_initialize allows reading settings from ENV on app start.
|
59
53
|
if defined?(Rails::Railtie)
|
60
54
|
class Railtie < Rails::Railtie
|
61
|
-
|
55
|
+
# allows reading settings from ENV vars set in config/initializers.
|
56
|
+
initializer(:plain_apm_agent_start, after: :load_config_initializers) do
|
57
|
+
PlainApm.agent.start
|
58
|
+
end
|
62
59
|
end
|
63
60
|
else
|
64
61
|
PlainApm.agent.start
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: plain_apm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- PlainAPM Team
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-03-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -107,9 +107,11 @@ files:
|
|
107
107
|
- lib/plain_apm/extensions/context/middleware.rb
|
108
108
|
- lib/plain_apm/extensions/context/rack.rb
|
109
109
|
- lib/plain_apm/extensions/context/railtie.rb
|
110
|
+
- lib/plain_apm/extensions/exceptions.rb
|
110
111
|
- lib/plain_apm/extensions/exceptions/active_job.rb
|
111
112
|
- lib/plain_apm/extensions/exceptions/rack.rb
|
112
113
|
- lib/plain_apm/extensions/exceptions/railtie.rb
|
114
|
+
- lib/plain_apm/extensions/thread_allocations.rb
|
113
115
|
- lib/plain_apm/extensions/thread_allocations/active_support_event.rb
|
114
116
|
- lib/plain_apm/extensions/thread_allocations/railtie.rb
|
115
117
|
- lib/plain_apm/helpers.rb
|
@@ -122,6 +124,7 @@ files:
|
|
122
124
|
- lib/plain_apm/hooks/active_support_subscriber.rb
|
123
125
|
- lib/plain_apm/hooks/error_reporter.rb
|
124
126
|
- lib/plain_apm/hooks/manual.rb
|
127
|
+
- lib/plain_apm/queue.rb
|
125
128
|
- lib/plain_apm/transport.rb
|
126
129
|
- lib/plain_apm/version.rb
|
127
130
|
homepage: https://plainapm.com
|