appsignal 4.5.16-java → 4.5.17-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
  SHA256:
3
- metadata.gz: d0c87519612771b1002ab8044e65233dcf3ae4a3f43b08fb030433e59b5df75f
4
- data.tar.gz: e31fa949c51641db4708f514c8cfba006c022156c299de36298b07545ef12fcc
3
+ metadata.gz: 666c51a5ea7ddef04551ad8340779f0d28a792fe84dfea610dbf6bcabbf885a9
4
+ data.tar.gz: 27cd215ac772b9df1fd0851b0b7cbad6c201d273ddc9d416cf739b928c632c0a
5
5
  SHA512:
6
- metadata.gz: 16cb2127adc17cde78ad3827fee08c35a4b3bdd5f3d9546a03b51211e2b36a3db42789e8ed31b91441c8dd4f600a4d108ef76acef228748e5c560c8df21804e8
7
- data.tar.gz: 8977e5c054a7de0be2fbc93128bb5cf9259d7e9eff0196af290c37e8d5b8a9892059ce0b14dcf169893376a9efdcc5f9b22e8c5c68054e012d3ece2455772393
6
+ metadata.gz: 758af432738af3ae72abe2a5b187bbdc747f9034aebd42678b5f6431401dfe30abbce293ababe64f6d6b986f594a35225bf8e6f5c9ed2b9dc8262124bd361b30
7
+ data.tar.gz: 257ffe63d397bd648fefbf055fd5955851a6a95f605f810c5e2fc6cb0aef5bc5584b34487a4d0625dec08e73f1fd77ca15840a5d2fbd5d669f3c4c0f482817de
data/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # AppSignal for Ruby gem Changelog
2
2
 
3
+ ## 4.5.17
4
+
5
+ _Published on 2025-07-01._
6
+
7
+ ### Fixed
8
+
9
+ - When an `Appsignal::Logger` uses `.broadcast_to` to broadcast messages to other loggers, broadcast those messages even if the log level of those messages is lower than the logger's threshold. This allows other loggers to set their own logging thresholds.
10
+
11
+ When the logger is silenced, messages below the silencing threshold are *not* broadcasted to other loggers.
12
+
13
+ (patch [bd3f2147](https://github.com/appsignal/appsignal-ruby/commit/bd3f2147ec58f5ed8c6db49328429e30e1826800))
14
+ - When an `Appsignal::Logger` uses `.broadcast_to` to broadcast messages to other loggers, broadcast the original message received by the logger, without formatting it or converting it to a string. (patch [bd3f2147](https://github.com/appsignal/appsignal-ruby/commit/bd3f2147ec58f5ed8c6db49328429e30e1826800))
15
+ - Call the `Appsignal::Logger` formatter with the original message object given, rather than converting it to a string before calling the formatter. (patch [bd3f2147](https://github.com/appsignal/appsignal-ruby/commit/bd3f2147ec58f5ed8c6db49328429e30e1826800))
16
+ - When an error is passed to an `Appsignal::Logger` as the message, format it regardless of the logging level. Previously it would only be formatted when passed to `#error`. (patch [bd3f2147](https://github.com/appsignal/appsignal-ruby/commit/bd3f2147ec58f5ed8c6db49328429e30e1826800))
17
+ - Ignore `Errno::ECONNRESET` errors in the Rack wrapper. (patch [90b0b7a3](https://github.com/appsignal/appsignal-ruby/commit/90b0b7a3e14832cb3626adf4b339bee56ba9745e))
18
+
3
19
  ## 4.5.16
4
20
 
5
21
  _Published on 2025-06-27._
@@ -9,6 +9,41 @@ module Appsignal
9
9
  # @see https://docs.appsignal.com/logging/platforms/integrations/ruby.html
10
10
  # AppSignal Ruby logging documentation.
11
11
  class Logger < ::Logger
12
+ # A wrapper for a block that ensures it is only called once.
13
+ # If called again, it will return the result of the first call.
14
+ # This is useful for ensuring that a block is not executed multiple
15
+ # times when it is broadcasted to multiple loggers.
16
+ class BlockOnce
17
+ def initialize(&block)
18
+ @block = block
19
+ @called = false
20
+ @success = nil
21
+ @result = nil
22
+ @error = nil
23
+ end
24
+
25
+ def call(*args, **kwargs)
26
+ if @called
27
+ return @result if @success
28
+
29
+ raise @error
30
+ end
31
+
32
+ @called = true
33
+ @result = @block.call(*args, **kwargs)
34
+ @success = true
35
+ @result
36
+ rescue StandardError => e
37
+ @success = false
38
+ @error = e
39
+ raise @error
40
+ end
41
+
42
+ def to_proc
43
+ method(:call).to_proc
44
+ end
45
+ end
46
+
12
47
  PLAINTEXT = 0
13
48
  LOGFMT = 1
14
49
  JSON = 2
@@ -34,10 +69,11 @@ module Appsignal
34
69
 
35
70
  @group = group
36
71
  @level = level
72
+ @silenced = false
37
73
  @format = format
38
74
  @mutex = Mutex.new
39
75
  @default_attributes = attributes
40
- @appsignal_attributes = {}
76
+ @appsignal_attributes = attributes
41
77
  @loggers = []
42
78
  end
43
79
 
@@ -52,32 +88,43 @@ module Appsignal
52
88
  # We support the various methods in the Ruby
53
89
  # logger class by supplying this method.
54
90
  # @api private
55
- def add(severity, message = nil, group = nil)
91
+ def add(severity, message = nil, group = nil, &block) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
92
+ # If we do not need to broadcast to any loggers and the severity is
93
+ # below the log level, we can return early.
56
94
  severity ||= UNKNOWN
57
- return true if severity < level
95
+ return true if severity < level && @loggers.empty?
58
96
 
97
+ # If the logger is silenced, we do not log *or broadcast* messages
98
+ # below the log level.
99
+ return true if @silenced && severity < @level
100
+
101
+ # Ensure that the block is only run once, even if several loggers
102
+ # are being broadcasted to.
103
+ block = BlockOnce.new(&block) unless block.nil?
104
+
105
+ # If the group is not set, we use the default group.
59
106
  group = @group if group.nil?
60
- if message.nil?
61
- if block_given?
62
- message = yield
63
- else
64
- message = group
65
- group = @group
66
- end
67
- end
68
- return if message.nil?
107
+
108
+ did_not_log = true
69
109
 
70
110
  @loggers.each do |logger|
71
- logger.add(severity, message, group)
111
+ # Loggers should return true if they did *not* log the message.
112
+ # If any of the broadcasted loggers logs the message, that counts
113
+ # as having logged the message.
114
+ did_not_log &&= logger.add(severity, message, group, &block)
72
115
  rescue
73
116
  nil
74
117
  end
75
118
 
76
- unless message.is_a?(String)
77
- Appsignal.internal_logger.warn(
78
- "Logger message was ignored, because it was not a String: #{message.inspect}"
79
- )
80
- return
119
+ # If the severity is below the log level, we do not log the message.
120
+ return did_not_log if severity < level
121
+
122
+ message = block.call if block && message.nil?
123
+
124
+ return if message.nil?
125
+
126
+ if message.is_a?(Exception)
127
+ message = "#{message.class}: #{message.message} (#{message.backtrace[0]})"
81
128
  end
82
129
 
83
130
  message = formatter.call(severity, Time.now, group, message) if formatter
@@ -86,9 +133,11 @@ module Appsignal
86
133
  group,
87
134
  SEVERITY_MAP.fetch(severity, 0),
88
135
  @format,
89
- message,
136
+ message.to_s,
90
137
  Appsignal::Utils::Data.generate(appsignal_attributes)
91
138
  )
139
+
140
+ false
92
141
  end
93
142
  alias log add
94
143
 
@@ -96,67 +145,40 @@ module Appsignal
96
145
  # @param message Message to log
97
146
  # @param attributes Attributes to tag the log with
98
147
  # @return [void]
99
- def debug(message = nil, attributes = {})
100
- return if level > DEBUG
101
-
102
- message = yield if message.nil? && block_given?
103
- return if message.nil?
104
-
105
- add_with_attributes(DEBUG, message, @group, attributes)
148
+ def debug(message = nil, attributes = {}, &block)
149
+ add_with_attributes(DEBUG, message, @group, attributes, &block)
106
150
  end
107
151
 
108
152
  # Log an info level message
109
153
  # @param message Message to log
110
154
  # @param attributes Attributes to tag the log with
111
155
  # @return [void]
112
- def info(message = nil, attributes = {})
113
- return if level > INFO
114
-
115
- message = yield if message.nil? && block_given?
116
- return if message.nil?
117
-
118
- add_with_attributes(INFO, message, @group, attributes)
156
+ def info(message = nil, attributes = {}, &block)
157
+ add_with_attributes(INFO, message, @group, attributes, &block)
119
158
  end
120
159
 
121
160
  # Log a warn level message
122
161
  # @param message Message to log
123
162
  # @param attributes Attributes to tag the log with
124
163
  # @return [void]
125
- def warn(message = nil, attributes = {})
126
- return if level > WARN
127
-
128
- message = yield if message.nil? && block_given?
129
- return if message.nil?
130
-
131
- add_with_attributes(WARN, message, @group, attributes)
164
+ def warn(message = nil, attributes = {}, &block)
165
+ add_with_attributes(WARN, message, @group, attributes, &block)
132
166
  end
133
167
 
134
168
  # Log an error level message
135
169
  # @param message Message to log
136
170
  # @param attributes Attributes to tag the log with
137
171
  # @return [void]
138
- def error(message = nil, attributes = {})
139
- return if level > ERROR
140
-
141
- message = yield if message.nil? && block_given?
142
- return if message.nil?
143
-
144
- message = "#{message.class}: #{message.message}" if message.is_a?(Exception)
145
-
146
- add_with_attributes(ERROR, message, @group, attributes)
172
+ def error(message = nil, attributes = {}, &block)
173
+ add_with_attributes(ERROR, message, @group, attributes, &block)
147
174
  end
148
175
 
149
176
  # Log a fatal level message
150
177
  # @param message Message to log
151
178
  # @param attributes Attributes to tag the log with
152
179
  # @return [void]
153
- def fatal(message = nil, attributes = {})
154
- return if level > FATAL
155
-
156
- message = yield if message.nil? && block_given?
157
- return if message.nil?
158
-
159
- add_with_attributes(FATAL, message, @group, attributes)
180
+ def fatal(message = nil, attributes = {}, &block)
181
+ add_with_attributes(FATAL, message, @group, attributes, &block)
160
182
  end
161
183
 
162
184
  # Log an info level message
@@ -166,7 +188,7 @@ module Appsignal
166
188
  # @param message Message to log
167
189
  # @return [Integer]
168
190
  def <<(message)
169
- add(Logger::INFO, message)
191
+ info(message)
170
192
  message.length
171
193
  end
172
194
 
@@ -180,9 +202,11 @@ module Appsignal
180
202
  def silence(severity = ERROR, &block)
181
203
  previous_level = @level
182
204
  @level = severity
205
+ @silenced = true
183
206
  block.call(self)
184
207
  ensure
185
208
  @level = previous_level
209
+ @silenced = false
186
210
  end
187
211
 
188
212
  def broadcast_to(logger)
@@ -193,11 +217,11 @@ module Appsignal
193
217
 
194
218
  attr_reader :default_attributes, :appsignal_attributes
195
219
 
196
- def add_with_attributes(severity, message, group, attributes)
220
+ def add_with_attributes(severity, message, group, attributes, &block)
197
221
  @appsignal_attributes = default_attributes.merge(attributes)
198
- add(severity, message, group)
222
+ add(severity, message, group, &block)
199
223
  ensure
200
- @appsignal_attributes = {}
224
+ @appsignal_attributes = default_attributes
201
225
  end
202
226
  end
203
227
  end
@@ -4,7 +4,7 @@ module Appsignal
4
4
  module Rack
5
5
  # @api private
6
6
  class BodyWrapper
7
- IGNORED_ERRORS = [Errno::EPIPE].freeze
7
+ IGNORED_ERRORS = [Errno::EPIPE, Errno::ECONNRESET].freeze
8
8
 
9
9
  def self.wrap(original_body, appsignal_transaction)
10
10
  # The logic of how Rack treats a response body differs based on which methods
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Appsignal
4
- VERSION = "4.5.16"
4
+ VERSION = "4.5.17"
5
5
  end
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: 4.5.16
4
+ version: 4.5.17
5
5
  platform: java
6
6
  authors:
7
7
  - Robert Beekman
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2025-06-27 00:00:00.000000000 Z
13
+ date: 2025-07-01 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: logger
@@ -331,7 +331,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
331
331
  - !ruby/object:Gem::Version
332
332
  version: '0'
333
333
  requirements: []
334
- rubygems_version: 3.5.23
334
+ rubygems_version: 3.3.7
335
335
  signing_key:
336
336
  specification_version: 4
337
337
  summary: Logs performance and exception data from your app to appsignal.com