appsignal 2.5.1 → 2.5.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/lib/appsignal.rb +1 -1
- data/lib/appsignal/event_formatter.rb +52 -19
- data/lib/appsignal/event_formatter/action_view/render_formatter.rb +10 -4
- data/lib/appsignal/event_formatter/active_record/instantiation_formatter.rb +6 -3
- data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +6 -3
- data/lib/appsignal/event_formatter/elastic_search/search_formatter.rb +6 -3
- data/lib/appsignal/event_formatter/faraday/request_formatter.rb +6 -3
- data/lib/appsignal/event_formatter/moped/query_formatter.rb +6 -3
- data/lib/appsignal/hooks/sidekiq.rb +5 -1
- data/lib/appsignal/version.rb +1 -1
- data/spec/lib/appsignal/event_formatter_spec.rb +39 -16
- data/spec/lib/appsignal/hooks/sidekiq_spec.rb +40 -0
- data/spec/lib/appsignal_spec.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 638c33adaf9394488da292c98738966981fad1d1
|
4
|
+
data.tar.gz: e0450850d9a358e78d3391050a1c43bfbb1b5705
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 94d04b637d3f5477ea4a29f47411d385e608b85e57bd930ea3e18f85c31401288a385adc651365043df5bc6bade2870f73179b17067f706f220a8007b2efe3eb
|
7
|
+
data.tar.gz: bcdf191cb6943a854503e5504ee69c41cde23bad18ffa77374d056cb61f616af208e696674a97d72a6008a62bf80ddc513e4bbbe94ee9b631138c52b7e1da57c
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
# 2.5.2
|
2
|
+
- Support Sidekiq delay extension for ActiveRecord instances. If using this
|
3
|
+
feature in your app, an update is strongly recommended! PR #387
|
4
|
+
- Improve custom event formatter registration. An event formatter can now be
|
5
|
+
registered in a Rails initializer after AppSignal has been loaded/started.
|
6
|
+
PR #397
|
7
|
+
|
1
8
|
# 2.5.1
|
2
9
|
- Improve internal sample storage in agent.
|
3
10
|
Commit 2c8eae26685c7a1517cf2e57b44edd1557a502f2
|
data/lib/appsignal.rb
CHANGED
@@ -121,7 +121,7 @@ module Appsignal
|
|
121
121
|
config.write_to_environment
|
122
122
|
Appsignal::Extension.start
|
123
123
|
Appsignal::Hooks.load_hooks
|
124
|
-
Appsignal::EventFormatter.
|
124
|
+
Appsignal::EventFormatter.initialize_deprecated_formatters
|
125
125
|
initialize_extensions
|
126
126
|
|
127
127
|
if config[:enable_allocation_tracking] && !Appsignal::System.jruby?
|
@@ -16,12 +16,35 @@ module Appsignal
|
|
16
16
|
@@formatters ||= {}
|
17
17
|
end
|
18
18
|
|
19
|
+
def deprecated_formatter_classes
|
20
|
+
@@deprecated_formatter_classes ||= {}
|
21
|
+
end
|
22
|
+
|
19
23
|
def formatter_classes
|
20
24
|
@@formatter_classes ||= {}
|
21
25
|
end
|
22
26
|
|
23
|
-
def register(name, formatter =
|
24
|
-
|
27
|
+
def register(name, formatter = nil)
|
28
|
+
unless formatter
|
29
|
+
register_deprecated_formatter(name)
|
30
|
+
return
|
31
|
+
end
|
32
|
+
|
33
|
+
if registered?(name, formatter)
|
34
|
+
Appsignal.logger.warn(
|
35
|
+
"Formatter for '#{name}' already registered, not registering "\
|
36
|
+
"'#{formatter.name}'"
|
37
|
+
)
|
38
|
+
return
|
39
|
+
end
|
40
|
+
|
41
|
+
initialize_formatter name, formatter
|
42
|
+
end
|
43
|
+
|
44
|
+
def initialize_deprecated_formatters
|
45
|
+
deprecated_formatter_classes.each do |name, formatter|
|
46
|
+
register(name, formatter)
|
47
|
+
end
|
25
48
|
end
|
26
49
|
|
27
50
|
def unregister(name, formatter = self)
|
@@ -39,27 +62,37 @@ module Appsignal
|
|
39
62
|
end
|
40
63
|
end
|
41
64
|
|
42
|
-
def initialize_formatters
|
43
|
-
formatter_classes.each do |name, formatter|
|
44
|
-
begin
|
45
|
-
format_method = formatter.instance_method(:format)
|
46
|
-
if format_method && format_method.arity == 1
|
47
|
-
formatters[name] = formatter.new
|
48
|
-
else
|
49
|
-
raise "#{f} does not have a format(payload) method"
|
50
|
-
end
|
51
|
-
rescue => ex
|
52
|
-
formatter_classes.delete(name)
|
53
|
-
formatters.delete(name)
|
54
|
-
Appsignal.logger.debug("'#{ex.message}' when initializing #{name} event formatter")
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
65
|
def format(name, payload)
|
60
66
|
formatter = formatters[name]
|
61
67
|
formatter.format(payload) unless formatter.nil?
|
62
68
|
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def initialize_formatter(name, formatter)
|
73
|
+
format_method = formatter.instance_method(:format)
|
74
|
+
if format_method && format_method.arity == 1
|
75
|
+
formatter_classes[name] = formatter
|
76
|
+
formatters[name] = formatter.new
|
77
|
+
else
|
78
|
+
raise "#{formatter} does not have a format(payload) method"
|
79
|
+
end
|
80
|
+
rescue => ex
|
81
|
+
formatter_classes.delete(name)
|
82
|
+
formatters.delete(name)
|
83
|
+
Appsignal.logger.warn("'#{ex.message}' when initializing #{name} event formatter")
|
84
|
+
end
|
85
|
+
|
86
|
+
def register_deprecated_formatter(name)
|
87
|
+
Appsignal.logger.warn(
|
88
|
+
"Formatter for '#{name}' is using a deprecated registration " \
|
89
|
+
"method. This event formatter will not be loaded. " \
|
90
|
+
"Please update the formatter according to the documentation at: " \
|
91
|
+
"https://docs.appsignal.com/ruby/instrumentation/event-formatters.html"
|
92
|
+
)
|
93
|
+
|
94
|
+
deprecated_formatter_classes[name] = self
|
95
|
+
end
|
63
96
|
end
|
64
97
|
|
65
98
|
# @api public
|
@@ -2,10 +2,7 @@ module Appsignal
|
|
2
2
|
class EventFormatter
|
3
3
|
# @api private
|
4
4
|
module ActionView
|
5
|
-
class RenderFormatter
|
6
|
-
register "render_partial.action_view"
|
7
|
-
register "render_template.action_view"
|
8
|
-
|
5
|
+
class RenderFormatter
|
9
6
|
BLANK = "".freeze
|
10
7
|
|
11
8
|
attr_reader :root_path
|
@@ -22,3 +19,12 @@ module Appsignal
|
|
22
19
|
end
|
23
20
|
end
|
24
21
|
end
|
22
|
+
|
23
|
+
Appsignal::EventFormatter.register(
|
24
|
+
"render_partial.action_view",
|
25
|
+
Appsignal::EventFormatter::ActionView::RenderFormatter
|
26
|
+
)
|
27
|
+
Appsignal::EventFormatter.register(
|
28
|
+
"render_template.action_view",
|
29
|
+
Appsignal::EventFormatter::ActionView::RenderFormatter
|
30
|
+
)
|
@@ -2,9 +2,7 @@ module Appsignal
|
|
2
2
|
class EventFormatter
|
3
3
|
# @api private
|
4
4
|
module ActiveRecord
|
5
|
-
class InstantiationFormatter
|
6
|
-
register "instantiation.active_record"
|
7
|
-
|
5
|
+
class InstantiationFormatter
|
8
6
|
def format(payload)
|
9
7
|
[payload[:class_name], nil]
|
10
8
|
end
|
@@ -12,3 +10,8 @@ module Appsignal
|
|
12
10
|
end
|
13
11
|
end
|
14
12
|
end
|
13
|
+
|
14
|
+
Appsignal::EventFormatter.register(
|
15
|
+
"instantiation.active_record",
|
16
|
+
Appsignal::EventFormatter::ActiveRecord::InstantiationFormatter
|
17
|
+
)
|
@@ -2,9 +2,7 @@ module Appsignal
|
|
2
2
|
class EventFormatter
|
3
3
|
# @api private
|
4
4
|
module ActiveRecord
|
5
|
-
class SqlFormatter
|
6
|
-
register "sql.active_record"
|
7
|
-
|
5
|
+
class SqlFormatter
|
8
6
|
def format(payload)
|
9
7
|
[payload[:name], payload[:sql], SQL_BODY_FORMAT]
|
10
8
|
end
|
@@ -12,3 +10,8 @@ module Appsignal
|
|
12
10
|
end
|
13
11
|
end
|
14
12
|
end
|
13
|
+
|
14
|
+
Appsignal::EventFormatter.register(
|
15
|
+
"sql.active_record",
|
16
|
+
Appsignal::EventFormatter::ActiveRecord::SqlFormatter
|
17
|
+
)
|
@@ -2,9 +2,7 @@ module Appsignal
|
|
2
2
|
class EventFormatter
|
3
3
|
# @api private
|
4
4
|
module ElasticSearch
|
5
|
-
class SearchFormatter
|
6
|
-
register "search.elasticsearch"
|
7
|
-
|
5
|
+
class SearchFormatter
|
8
6
|
def format(payload)
|
9
7
|
[
|
10
8
|
"#{payload[:name]}: #{payload[:klass]}",
|
@@ -30,3 +28,8 @@ module Appsignal
|
|
30
28
|
end
|
31
29
|
end
|
32
30
|
end
|
31
|
+
|
32
|
+
Appsignal::EventFormatter.register(
|
33
|
+
"search.elasticsearch",
|
34
|
+
Appsignal::EventFormatter::ElasticSearch::SearchFormatter
|
35
|
+
)
|
@@ -2,9 +2,7 @@ module Appsignal
|
|
2
2
|
class EventFormatter
|
3
3
|
# @api private
|
4
4
|
module Faraday
|
5
|
-
class RequestFormatter
|
6
|
-
register "request.faraday"
|
7
|
-
|
5
|
+
class RequestFormatter
|
8
6
|
def format(payload)
|
9
7
|
http_method = payload[:method].to_s.upcase
|
10
8
|
uri = payload[:url]
|
@@ -17,3 +15,8 @@ module Appsignal
|
|
17
15
|
end
|
18
16
|
end
|
19
17
|
end
|
18
|
+
|
19
|
+
Appsignal::EventFormatter.register(
|
20
|
+
"request.faraday",
|
21
|
+
Appsignal::EventFormatter::Faraday::RequestFormatter
|
22
|
+
)
|
@@ -2,9 +2,7 @@ module Appsignal
|
|
2
2
|
class EventFormatter
|
3
3
|
# @api private
|
4
4
|
module Moped
|
5
|
-
class QueryFormatter
|
6
|
-
register "query.moped"
|
7
|
-
|
5
|
+
class QueryFormatter
|
8
6
|
def format(payload)
|
9
7
|
if payload[:ops] && !payload[:ops].empty?
|
10
8
|
op = payload[:ops].first
|
@@ -78,3 +76,8 @@ module Appsignal
|
|
78
76
|
end
|
79
77
|
end
|
80
78
|
end
|
79
|
+
|
80
|
+
Appsignal::EventFormatter.register(
|
81
|
+
"query.moped",
|
82
|
+
Appsignal::EventFormatter::Moped::QueryFormatter
|
83
|
+
)
|
@@ -19,7 +19,7 @@ module Appsignal
|
|
19
19
|
end
|
20
20
|
|
21
21
|
# @api private
|
22
|
-
class SidekiqPlugin
|
22
|
+
class SidekiqPlugin # rubocop:disable Metrics/ClassLength
|
23
23
|
include Appsignal::Hooks::Helpers
|
24
24
|
|
25
25
|
JOB_KEYS = %w[
|
@@ -84,6 +84,10 @@ module Appsignal
|
|
84
84
|
def parse_action_name(job)
|
85
85
|
args = job["args"]
|
86
86
|
case job["class"]
|
87
|
+
when "Sidekiq::Extensions::DelayedModel"
|
88
|
+
safe_load(job["args"][0], job["class"]) do |target, method, _|
|
89
|
+
"#{target.class}##{method}"
|
90
|
+
end
|
87
91
|
when /\ASidekiq::Extensions::Delayed/
|
88
92
|
safe_load(job["args"][0], job["class"]) do |target, method, _|
|
89
93
|
"#{target}.#{method}"
|
data/lib/appsignal/version.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
1
|
class MockFormatter < Appsignal::EventFormatter
|
2
|
-
register "mock"
|
3
|
-
|
4
2
|
attr_reader :body
|
5
3
|
|
6
4
|
def initialize
|
@@ -23,20 +21,30 @@ class IncorrectFormatMockFormatter < Appsignal::EventFormatter
|
|
23
21
|
end
|
24
22
|
|
25
23
|
class MockDependentFormatter < Appsignal::EventFormatter
|
26
|
-
register "mock.dependent"
|
27
|
-
|
28
24
|
def initialize
|
29
25
|
NonsenseDependency.something
|
30
26
|
end
|
31
27
|
end
|
32
28
|
|
29
|
+
Appsignal::EventFormatter.register "mock", MockFormatter
|
30
|
+
Appsignal::EventFormatter.register "mock.dependent", MockDependentFormatter
|
31
|
+
|
33
32
|
describe Appsignal::EventFormatter do
|
34
33
|
before do
|
35
|
-
|
34
|
+
klass.register("mock", MockFormatter)
|
36
35
|
end
|
37
36
|
|
38
37
|
let(:klass) { Appsignal::EventFormatter }
|
39
38
|
|
39
|
+
let(:deprecated_formatter) do
|
40
|
+
Class.new(Appsignal::EventFormatter) do
|
41
|
+
register "mock.deprecated"
|
42
|
+
|
43
|
+
def format(_payload)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
40
48
|
context "registering and unregistering formatters" do
|
41
49
|
it "should register a formatter" do
|
42
50
|
expect(klass.formatters["mock"]).to be_instance_of(MockFormatter)
|
@@ -53,19 +61,8 @@ describe Appsignal::EventFormatter do
|
|
53
61
|
expect(klass.registered?("mock.dependent")).to be_falsy
|
54
62
|
end
|
55
63
|
|
56
|
-
it "doesn't register formatters that don't have a format(payload) method" do
|
57
|
-
klass.register("mock.missing_format", MissingFormatMockFormatter)
|
58
|
-
klass.register("mock.incorrect_format", IncorrectFormatMockFormatter)
|
59
|
-
|
60
|
-
Appsignal::EventFormatter.initialize_formatters
|
61
|
-
|
62
|
-
expect(klass.registered?("mock.missing_format")).to be_falsy
|
63
|
-
expect(klass.registered?("mock.incorrect_format")).to be_falsy
|
64
|
-
end
|
65
|
-
|
66
64
|
it "should register a custom formatter" do
|
67
65
|
klass.register("mock.specific", MockFormatter)
|
68
|
-
Appsignal::EventFormatter.initialize_formatters
|
69
66
|
|
70
67
|
expect(klass.formatter_classes["mock.specific"]).to eq MockFormatter
|
71
68
|
expect(klass.registered?("mock.specific")).to be_truthy
|
@@ -86,6 +83,32 @@ describe Appsignal::EventFormatter do
|
|
86
83
|
klass.unregister("mock.unregister", MockFormatter)
|
87
84
|
expect(klass.registered?("mock.unregister")).to be_falsy
|
88
85
|
end
|
86
|
+
|
87
|
+
it "should not register two formatters for the same name" do
|
88
|
+
expect(Appsignal.logger).to receive(:warn)
|
89
|
+
.with("Formatter for 'mock.twice' already registered, not registering 'MockFormatter'")
|
90
|
+
klass.register("mock.twice", MockFormatter)
|
91
|
+
klass.register("mock.twice", MockFormatter)
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should not register deprecated formatter" do
|
95
|
+
expect(Appsignal.logger).to receive(:warn)
|
96
|
+
.with("Formatter for 'mock.deprecated' is using a deprecated registration method. " \
|
97
|
+
"This event formatter will not be loaded. " \
|
98
|
+
"Please update the formatter according to the documentation at: " \
|
99
|
+
"https://docs.appsignal.com/ruby/instrumentation/event-formatters.html")
|
100
|
+
|
101
|
+
deprecated_formatter
|
102
|
+
|
103
|
+
expect(Appsignal::EventFormatter.deprecated_formatter_classes.keys).to include("mock.deprecated")
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should initialize deprecated formatters" do
|
107
|
+
deprecated_formatter
|
108
|
+
Appsignal::EventFormatter.initialize_deprecated_formatters
|
109
|
+
|
110
|
+
expect(klass.registered?("mock.deprecated")).to be_truthy
|
111
|
+
end
|
89
112
|
end
|
90
113
|
|
91
114
|
context "calling formatters" do
|
@@ -151,6 +151,46 @@ describe Appsignal::Hooks::SidekiqPlugin, :with_yaml_parse_error => false do
|
|
151
151
|
end
|
152
152
|
end
|
153
153
|
|
154
|
+
context "when using the Sidekiq ActiveRecord instance delayed extension" do
|
155
|
+
let(:item) do
|
156
|
+
{
|
157
|
+
"jid" => "efb140489485999d32b5504c",
|
158
|
+
"class" => "Sidekiq::Extensions::DelayedModel",
|
159
|
+
"queue" => "default",
|
160
|
+
"args" => [
|
161
|
+
"---\n- !ruby/object:DelayedTestClass {}\n- :foo_method\n- - :bar: :baz\n"
|
162
|
+
],
|
163
|
+
"retry" => true,
|
164
|
+
"created_at" => Time.parse("2001-01-01 10:00:00UTC").to_f,
|
165
|
+
"enqueued_at" => Time.parse("2001-01-01 10:00:00UTC").to_f,
|
166
|
+
"extra" => "data"
|
167
|
+
}
|
168
|
+
end
|
169
|
+
|
170
|
+
it "uses the delayed class and method name for the action" do
|
171
|
+
perform_job
|
172
|
+
|
173
|
+
transaction_hash = transaction.to_h
|
174
|
+
expect(transaction_hash["action"]).to eq("DelayedTestClass#foo_method")
|
175
|
+
expect(transaction_hash["sample_data"]).to include(
|
176
|
+
"params" => ["bar" => "baz"]
|
177
|
+
)
|
178
|
+
end
|
179
|
+
|
180
|
+
context "when job arguments is a malformed YAML object", :with_yaml_parse_error => true do
|
181
|
+
before { item["args"] = [] }
|
182
|
+
|
183
|
+
it "logs a warning and uses the default argument" do
|
184
|
+
perform_job
|
185
|
+
|
186
|
+
transaction_hash = transaction.to_h
|
187
|
+
expect(transaction_hash["action"]).to eq("Sidekiq::Extensions::DelayedModel#perform")
|
188
|
+
expect(transaction_hash["sample_data"]).to include("params" => [])
|
189
|
+
expect(log_contents(log)).to contains_log(:warn, "Unable to load YAML")
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
154
194
|
context "when using ActiveJob" do
|
155
195
|
let(:item) do
|
156
196
|
{
|
data/spec/lib/appsignal_spec.rb
CHANGED
@@ -61,8 +61,8 @@ describe Appsignal do
|
|
61
61
|
Appsignal.start
|
62
62
|
end
|
63
63
|
|
64
|
-
it "should
|
65
|
-
expect(Appsignal::EventFormatter).to receive(:
|
64
|
+
it "should load deprecated event formatters" do
|
65
|
+
expect(Appsignal::EventFormatter).to receive(:initialize_deprecated_formatters)
|
66
66
|
Appsignal.start
|
67
67
|
end
|
68
68
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: appsignal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.5.
|
4
|
+
version: 2.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Beekman
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2018-
|
12
|
+
date: 2018-04-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|