plain_apm 0.6.7 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/object_tracing/extconf.rb +4 -4
- data/lib/plain_apm/agent.rb +0 -17
- data/lib/plain_apm/event_attributes.rb +141 -0
- data/lib/plain_apm/extensions/exceptions/rack.rb +7 -23
- data/lib/plain_apm/helpers.rb +1 -1
- data/lib/plain_apm/hooks/action_mailer.rb +1 -1
- data/lib/plain_apm/hooks/action_pack.rb +1 -1
- data/lib/plain_apm/hooks/action_view.rb +1 -1
- data/lib/plain_apm/hooks/active_job.rb +1 -1
- data/lib/plain_apm/hooks/active_record.rb +3 -3
- data/lib/plain_apm/hooks/active_support.rb +4 -4
- data/lib/plain_apm/hooks/active_support_subscriber.rb +3 -26
- data/lib/plain_apm/hooks/deploy.rb +5 -11
- data/lib/plain_apm/hooks/error_reporter.rb +5 -29
- data/lib/plain_apm/hooks/manual.rb +1 -1
- data/lib/plain_apm/version.rb +1 -1
- data/lib/plain_apm.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 41e2fd7c72868351a09c83a13a22df9e9718e00cbb1950c27e7ce129cf24a826
|
4
|
+
data.tar.gz: 2f658463e3ee8f8195142a2b456b6f5c535efac868ada116f766ef92db5ab714
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 139c55ba03f6982640310ba59122fab53c6fb9c871e409c304b5d5ebd50e44c34af8db691195acb4dd7b4b43087092e7b9f1fe052f8d7aa299b863d4b4301c8e
|
7
|
+
data.tar.gz: da0cd391b91b3660ef48fc8587e26562d1caf908526b2af86e9c42e2cff945940c779b6b115763bacf8f105e33e7422e4a27d403c788b8d44be9d33d909e1460
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
1
|
+
require "mkmf"
|
2
2
|
|
3
|
-
have_header(
|
4
|
-
have_header(
|
3
|
+
have_header("ruby/ruby.h") or missing("ruby/ruby.h")
|
4
|
+
have_header("ruby/debug.h") or missing("ruby/debug.h")
|
5
5
|
|
6
|
-
create_makefile(
|
6
|
+
create_makefile("object_tracing")
|
data/lib/plain_apm/agent.rb
CHANGED
@@ -19,23 +19,6 @@ module PlainApm
|
|
19
19
|
def collect(event)
|
20
20
|
return unless @config.enabled
|
21
21
|
|
22
|
-
##
|
23
|
-
# Context contains the trace ID (which comes from either
|
24
|
-
# HTTP_X_REQUEST_ID header, the deserialized job,
|
25
|
-
# or is generated by the trace_id middleware).
|
26
|
-
# It can also carry user inserted app data.
|
27
|
-
if defined?(PlainApm::Extensions::Context)
|
28
|
-
event.merge!(PlainApm::Extensions::Context.current)
|
29
|
-
end
|
30
|
-
|
31
|
-
event.merge!(
|
32
|
-
"version" => PlainApm::VERSION,
|
33
|
-
"collected_at" => Time.now.utc.to_f,
|
34
|
-
"hostname" => Socket.gethostname,
|
35
|
-
"pid" => Process.pid,
|
36
|
-
"thread_id" => Thread.current.object_id.to_s,
|
37
|
-
)
|
38
|
-
|
39
22
|
@events << event
|
40
23
|
end
|
41
24
|
|
@@ -0,0 +1,141 @@
|
|
1
|
+
module PlainApm
|
2
|
+
module EventAttributes
|
3
|
+
SOURCES_WITH_EXTRA_ATTRIBUTES = %w[
|
4
|
+
action_controller
|
5
|
+
action_mailer
|
6
|
+
active_job
|
7
|
+
deploy
|
8
|
+
exception
|
9
|
+
].freeze
|
10
|
+
|
11
|
+
# FIXME: This is duplicated for ErrorReporter
|
12
|
+
IGNORED_EXCEPTIONS = [
|
13
|
+
"Sidekiq::JobRetry::Skip", # Sidekiq uses exceptions for control flow.
|
14
|
+
"ActionController::RoutingError" # Rails unmapped route, raised before the request hits the app.
|
15
|
+
].freeze
|
16
|
+
|
17
|
+
def attributes_from_deploy(tool, revision)
|
18
|
+
source = "deploy"
|
19
|
+
|
20
|
+
attrs = {
|
21
|
+
"source" => source,
|
22
|
+
"revision" => revision,
|
23
|
+
"name" => tool
|
24
|
+
}
|
25
|
+
|
26
|
+
attrs.merge!(trace_attributes(source))
|
27
|
+
|
28
|
+
[tool, attrs]
|
29
|
+
end
|
30
|
+
|
31
|
+
def attributes_from_exception(e, context)
|
32
|
+
source = "exception"
|
33
|
+
|
34
|
+
return [source, nil] if IGNORED_EXCEPTIONS.include?(e.class.name)
|
35
|
+
|
36
|
+
attrs = {
|
37
|
+
"class" => e.class.name,
|
38
|
+
"message" => e.message,
|
39
|
+
"backtrace" => e.backtrace
|
40
|
+
}
|
41
|
+
|
42
|
+
if context[:env]
|
43
|
+
attrs["params"] = context[:env]["action_dispatch.request.parameters"]
|
44
|
+
end
|
45
|
+
|
46
|
+
if context[:job]&.is_a?(ActiveJob::Base)
|
47
|
+
attrs["job_class"] = context[:job].class.name
|
48
|
+
attrs["queue_name"] = context[:job].queue_name
|
49
|
+
end
|
50
|
+
|
51
|
+
if e.cause
|
52
|
+
attrs.merge!({
|
53
|
+
"cause_class" => e.cause.class.name,
|
54
|
+
"cause_message" => e.cause.message,
|
55
|
+
"cause_backtrace" => e.cause.backtrace
|
56
|
+
})
|
57
|
+
end
|
58
|
+
|
59
|
+
attrs.merge!(trace_attributes(source))
|
60
|
+
|
61
|
+
[source, attrs]
|
62
|
+
end
|
63
|
+
|
64
|
+
def attributes_from_notification(event)
|
65
|
+
name, source = *event.name.split(".")
|
66
|
+
loc = source_location
|
67
|
+
|
68
|
+
attrs = {
|
69
|
+
"source" => source,
|
70
|
+
"name" => name,
|
71
|
+
"allocations" => event.allocations,
|
72
|
+
"thread_allocations" => event.thread_allocations,
|
73
|
+
"event_time" => event.time,
|
74
|
+
"duration" => event.duration
|
75
|
+
}
|
76
|
+
|
77
|
+
attrs["source_location"] = loc if !loc.nil?
|
78
|
+
|
79
|
+
attrs.merge!(trace_attributes(source))
|
80
|
+
|
81
|
+
[name, attrs]
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def trace_attributes(source)
|
87
|
+
attrs = agent_attributes
|
88
|
+
|
89
|
+
if add_extra_attributes?(source)
|
90
|
+
attrs.merge!(process_attributes, context_attributes)
|
91
|
+
else
|
92
|
+
attrs.merge!(context_attributes.slice(:trace_id))
|
93
|
+
end
|
94
|
+
|
95
|
+
attrs
|
96
|
+
end
|
97
|
+
|
98
|
+
def add_extra_attributes?(source)
|
99
|
+
SOURCES_WITH_EXTRA_ATTRIBUTES.include?(source)
|
100
|
+
end
|
101
|
+
|
102
|
+
def agent_attributes
|
103
|
+
{
|
104
|
+
"version" => PlainApm::VERSION
|
105
|
+
}
|
106
|
+
end
|
107
|
+
|
108
|
+
def process_attributes
|
109
|
+
{
|
110
|
+
"collected_at" => Time.now.iso8601(9),
|
111
|
+
"hostname" => Socket.gethostname,
|
112
|
+
"pid" => Process.pid,
|
113
|
+
"thread_id" => Thread.current.object_id
|
114
|
+
}
|
115
|
+
end
|
116
|
+
|
117
|
+
def context_attributes
|
118
|
+
##
|
119
|
+
# Context contains the trace ID (which comes from either
|
120
|
+
# HTTP_X_REQUEST_ID header, the deserialized job,
|
121
|
+
# or is generated by the trace_id middleware).
|
122
|
+
# It can also carry user inserted app data.
|
123
|
+
if defined?(PlainApm::Extensions::Context)
|
124
|
+
PlainApm::Extensions::Context.current
|
125
|
+
else
|
126
|
+
{}
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def source_location
|
131
|
+
filtered_backtrace&.first
|
132
|
+
end
|
133
|
+
|
134
|
+
def filtered_backtrace
|
135
|
+
if defined?(Rails) && defined?(Rails::BacktraceCleaner)
|
136
|
+
@cleaner ||= Rails::BacktraceCleaner.new
|
137
|
+
@cleaner.clean(caller)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -4,11 +4,7 @@ module PlainApm
|
|
4
4
|
module Extensions
|
5
5
|
module Exceptions
|
6
6
|
class Rack
|
7
|
-
|
8
|
-
IGNORED_EXCEPTIONS = [
|
9
|
-
"Sidekiq::JobRetry::Skip", # Sidekiq uses exceptions for control flow.
|
10
|
-
"ActionController::RoutingError" # Rails unmapped route, raised before the request hits the app.
|
11
|
-
].freeze
|
7
|
+
include EventAttributes
|
12
8
|
|
13
9
|
def initialize(app)
|
14
10
|
@app = app
|
@@ -29,24 +25,12 @@ module PlainApm
|
|
29
25
|
private
|
30
26
|
|
31
27
|
def report_exception(e, env)
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
"message" => e.message,
|
39
|
-
"backtrace" => e.backtrace,
|
40
|
-
"params" => env["action_dispatch.request.parameters"]
|
41
|
-
}
|
42
|
-
|
43
|
-
if e.cause
|
44
|
-
event.merge!({
|
45
|
-
"cause_class" => e.cause.class.name,
|
46
|
-
"cause_message" => e.cause.message,
|
47
|
-
"cause_backtrace" => e.cause.backtrace
|
48
|
-
})
|
49
|
-
end
|
28
|
+
source, event = attributes_from_exception(e, {env: env})
|
29
|
+
|
30
|
+
return if event.nil?
|
31
|
+
|
32
|
+
event["source"] = source
|
33
|
+
event["name"] = "rack_middleware"
|
50
34
|
|
51
35
|
PlainApm::Agent.collect(event)
|
52
36
|
end
|
data/lib/plain_apm/helpers.rb
CHANGED
@@ -5,7 +5,7 @@ module PlainApm
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def plain_apm_instrument(name, context = {}, &block)
|
8
|
-
sanitized_name = name.gsub(/\W/, "_").gsub(/(?!^)([A-Z])/) { |m| "_#{m}" }.
|
8
|
+
sanitized_name = name.gsub(/\W/, "_").gsub(/(?!^)([A-Z])/) { |m| "_#{m}" }.squeeze("_").downcase
|
9
9
|
ActiveSupport::Notifications.instrument("#{sanitized_name}.manual_plain_apm", **context, &block)
|
10
10
|
end
|
11
11
|
end
|
@@ -6,7 +6,7 @@ module PlainApm
|
|
6
6
|
module Hooks
|
7
7
|
class ActiveRecord < ActiveSupportSubscriber
|
8
8
|
NOTIFICATION_PATTERN = /\A[^!]\w+\.active_record\Z/.freeze
|
9
|
-
IGNORED_SQL_NAMES = %w
|
9
|
+
IGNORED_SQL_NAMES = %w[SCHEMA CACHE].freeze
|
10
10
|
|
11
11
|
private
|
12
12
|
|
@@ -15,14 +15,14 @@ module PlainApm
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def payload(event)
|
18
|
-
name, base =
|
18
|
+
name, base = attributes_from_notification(event)
|
19
19
|
payload = event.payload
|
20
20
|
|
21
21
|
return if IGNORED_SQL_NAMES.include?(payload[:name])
|
22
22
|
|
23
23
|
case name
|
24
24
|
when "sql"
|
25
|
-
base.merge({
|
25
|
+
base.merge({"sql" => payload[:sql]})
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module PlainApm
|
4
4
|
module Hooks
|
5
5
|
class ActiveSupport < ActiveSupportSubscriber
|
6
|
-
NOTIFICATION_PATTERN = /\Acache_[\w
|
6
|
+
NOTIFICATION_PATTERN = /\Acache_[\w?]+\.active_support\Z/.freeze
|
7
7
|
|
8
8
|
private
|
9
9
|
|
@@ -12,17 +12,17 @@ module PlainApm
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def payload(event)
|
15
|
-
name, base =
|
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
22
|
base.merge({
|
23
23
|
"key" => payload[:key],
|
24
24
|
"hit" => payload[:hit],
|
25
|
-
"trigger" => payload[:super_operation]
|
25
|
+
"trigger" => payload[:super_operation]
|
26
26
|
})
|
27
27
|
when "cache_read_multi"
|
28
28
|
base.merge({
|
@@ -3,6 +3,8 @@
|
|
3
3
|
module PlainApm
|
4
4
|
module Hooks
|
5
5
|
class ActiveSupportSubscriber
|
6
|
+
include EventAttributes
|
7
|
+
|
6
8
|
def install
|
7
9
|
begin
|
8
10
|
require "active_support/notifications"
|
@@ -26,7 +28,7 @@ module PlainApm
|
|
26
28
|
|
27
29
|
return if payload.nil?
|
28
30
|
|
29
|
-
Agent.
|
31
|
+
Agent.collect(payload)
|
30
32
|
end
|
31
33
|
|
32
34
|
private
|
@@ -38,31 +40,6 @@ module PlainApm
|
|
38
40
|
def payload(event)
|
39
41
|
raise "Not implemented"
|
40
42
|
end
|
41
|
-
|
42
|
-
def common_attributes(event)
|
43
|
-
name, source = *event.name.split(".")
|
44
|
-
bt = filtered_backtrace
|
45
|
-
|
46
|
-
attrs = {
|
47
|
-
"source" => source,
|
48
|
-
"name" => name,
|
49
|
-
"allocations" => event.allocations,
|
50
|
-
"thread_allocations" => event.thread_allocations,
|
51
|
-
"started_at" => event.time,
|
52
|
-
"finished_at" => event.end
|
53
|
-
}
|
54
|
-
|
55
|
-
attrs.merge!("backtrace" => bt) if bt && !bt.empty?
|
56
|
-
|
57
|
-
[name, attrs]
|
58
|
-
end
|
59
|
-
|
60
|
-
def filtered_backtrace
|
61
|
-
if defined?(Rails) && defined?(Rails::BacktraceCleaner)
|
62
|
-
@cleaner ||= Rails::BacktraceCleaner.new
|
63
|
-
@cleaner.clean(caller)
|
64
|
-
end
|
65
|
-
end
|
66
43
|
end
|
67
44
|
end
|
68
45
|
end
|
@@ -6,6 +6,8 @@ module PlainApm
|
|
6
6
|
# for performance regressions.
|
7
7
|
module Hooks
|
8
8
|
class Deploy
|
9
|
+
include EventAttributes
|
10
|
+
|
9
11
|
##
|
10
12
|
# Collect once, immediately on install.
|
11
13
|
def install
|
@@ -15,17 +17,9 @@ module PlainApm
|
|
15
17
|
def collect
|
16
18
|
result = git_revision || hg_revision || return
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
-
Agent.
|
21
|
-
{
|
22
|
-
"source" => "deploy",
|
23
|
-
"revision" => revision,
|
24
|
-
"name" => tool,
|
25
|
-
"started_at" => Time.now.to_f,
|
26
|
-
"finished_at" => Time.now.to_f
|
27
|
-
}
|
28
|
-
)
|
20
|
+
_, attrs = attributes_from_deploy(*result)
|
21
|
+
|
22
|
+
Agent.collect(attrs)
|
29
23
|
end
|
30
24
|
|
31
25
|
private
|
@@ -2,10 +2,7 @@ module PlainApm
|
|
2
2
|
module Hooks
|
3
3
|
# Rails 7 error notification mechanism
|
4
4
|
class ErrorReporter
|
5
|
-
|
6
|
-
"Sidekiq::JobRetry::Skip", # Sidekiq uses exceptions for control flow.
|
7
|
-
"ActionController::RoutingError" # Rails unmapped route, raised before the request hits the app.
|
8
|
-
].freeze
|
5
|
+
include EventAttributes
|
9
6
|
|
10
7
|
def install
|
11
8
|
begin
|
@@ -23,33 +20,12 @@ module PlainApm
|
|
23
20
|
end
|
24
21
|
|
25
22
|
def collect(e, handled:, severity:, context: {})
|
26
|
-
|
23
|
+
source, event = attributes_from_exception(e, context)
|
27
24
|
|
28
|
-
|
29
|
-
"source" => "exception",
|
30
|
-
"name" => "error_reporter",
|
31
|
-
"class" => e.class.name,
|
32
|
-
"message" => e.message,
|
33
|
-
"backtrace" => e.backtrace,
|
34
|
-
"handled" => handled,
|
35
|
-
"severity" => severity,
|
36
|
-
"context" => context
|
37
|
-
}
|
25
|
+
return if event.nil?
|
38
26
|
|
39
|
-
|
40
|
-
|
41
|
-
"job_class" => context[:job].class.name,
|
42
|
-
"queue_name" => context[:job].queue_name
|
43
|
-
})
|
44
|
-
end
|
45
|
-
|
46
|
-
if e.cause
|
47
|
-
event.merge!({
|
48
|
-
"cause_class" => e.cause.class.name,
|
49
|
-
"cause_message" => e.cause.message,
|
50
|
-
"cause_backtrace" => e.cause.backtrace
|
51
|
-
})
|
52
|
-
end
|
27
|
+
event["source"] = source
|
28
|
+
event["name"] = "error_reporter"
|
53
29
|
|
54
30
|
PlainApm::Agent.collect(event)
|
55
31
|
end
|
data/lib/plain_apm/version.rb
CHANGED
data/lib/plain_apm.rb
CHANGED
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.
|
4
|
+
version: 0.7.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- PlainAPM Team
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-01-
|
11
|
+
date: 2023-01-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -99,6 +99,7 @@ files:
|
|
99
99
|
- lib/plain_apm/agent.rb
|
100
100
|
- lib/plain_apm/backoff.rb
|
101
101
|
- lib/plain_apm/config.rb
|
102
|
+
- lib/plain_apm/event_attributes.rb
|
102
103
|
- lib/plain_apm/extensions/context.rb
|
103
104
|
- lib/plain_apm/extensions/context/LICENSE.txt
|
104
105
|
- lib/plain_apm/extensions/context/active_job.rb
|