appsignal 2.5.1-java → 2.5.2-java

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f81ea689aa2d62b490a2038da3204b585332fbda
4
- data.tar.gz: f44d521a76c7e897d07d47c2bfe244ebbb5b66f8
3
+ metadata.gz: e3d9bc6665c2a3112a1aa24d8194a1c404ca933d
4
+ data.tar.gz: e0450850d9a358e78d3391050a1c43bfbb1b5705
5
5
  SHA512:
6
- metadata.gz: 81b07a75f309f88a81f2727aca17d3a66d271da23760349f68493ce690b4e9b1fd3bcd617a82a96e3c013e7d93d0ea012956e33db490e4712dc495008664734f
7
- data.tar.gz: fbda5dce446bf4e06146169e704eb0e372f5afae9c6129247e4be79b9912e2c941c3324ec2ace3a3e740f18627905dc9e6773f226faa23a3d92e73ad4b6af700
6
+ metadata.gz: 2b1bc35ce5ef95dc7f04332bb2e8f347477b13d60a19edfbe2891e27a07f409f8678efb653da4b2517d4991fd2267dddbe4077b3c48d11ded7421ce5c2594a9f
7
+ data.tar.gz: bcdf191cb6943a854503e5504ee69c41cde23bad18ffa77374d056cb61f616af208e696674a97d72a6008a62bf80ddc513e4bbbe94ee9b631138c52b7e1da57c
@@ -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
@@ -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.initialize_formatters
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 = self)
24
- formatter_classes[name] = formatter
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 < Appsignal::EventFormatter
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 < Appsignal::EventFormatter
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 < Appsignal::EventFormatter
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 < Appsignal::EventFormatter
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 < Appsignal::EventFormatter
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 < Appsignal::EventFormatter
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}"
@@ -1,3 +1,3 @@
1
1
  module Appsignal
2
- VERSION = "2.5.1".freeze
2
+ VERSION = "2.5.2".freeze
3
3
  end
@@ -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
- Appsignal::EventFormatter.initialize_formatters
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
  {
@@ -61,8 +61,8 @@ describe Appsignal do
61
61
  Appsignal.start
62
62
  end
63
63
 
64
- it "should initialize formatters" do
65
- expect(Appsignal::EventFormatter).to receive(:initialize_formatters)
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.1
4
+ version: 2.5.2
5
5
  platform: java
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-03-13 00:00:00.000000000 Z
12
+ date: 2018-04-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack