appsignal 4.0.9-java → 4.1.1-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 +4 -4
- data/CHANGELOG.md +45 -0
- data/lib/appsignal/check_in/cron.rb +3 -5
- data/lib/appsignal/check_in/event.rb +72 -0
- data/lib/appsignal/check_in/scheduler.rb +10 -34
- data/lib/appsignal/check_in.rb +44 -1
- data/lib/appsignal/config.rb +18 -36
- data/lib/appsignal/integrations/capistrano/appsignal.cap +2 -2
- data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +2 -2
- data/lib/appsignal/integrations/railtie.rb +1 -0
- data/lib/appsignal/transaction.rb +32 -1
- data/lib/appsignal/transmitter.rb +1 -1
- data/lib/appsignal/version.rb +1 -1
- data/lib/appsignal.rb +1 -2
- 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: 51f686ec6cbdb470c83a24eee9a221026e3d5b4a9c8fd79c1b3e311480bc8da3
|
|
4
|
+
data.tar.gz: ef77980f54715f5b4a05ee218df8a0e51b3f867643ca793ef790dda3f324e05c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 91c3f646a11d9899994281b529d7f0d6c6ffd31fd4444704ea01528877815fc6b44faf808b95dca6e1a8b12048c532e81447b0dddd47d2f7363a56d1d772777c
|
|
7
|
+
data.tar.gz: 0cf285924ec8dd63cbcdb89a0354f76dfdc86d6737dc32c80f2538ae136b8653763b67a3507238db866751869d7c17f817eb2e766b4b7860584f4618be550d58
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,50 @@
|
|
|
1
1
|
# AppSignal for Ruby gem Changelog
|
|
2
2
|
|
|
3
|
+
## 4.1.1
|
|
4
|
+
|
|
5
|
+
_Published on 2024-09-28._
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Add the `reported_by` tag to errors reported by the Rails error reporter so the source of the error is easier to identify. (patch [ff98ed67](https://github.com/appsignal/appsignal-ruby/commit/ff98ed677bf30242c51261bf7e44c9b6ba2f33ac))
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Fix no AppSignal internal logs being logged from Capistrano tasks. (patch [089d0325](https://github.com/appsignal/appsignal-ruby/commit/089d03251c3dc8b83658a4ebfade51ab6bed1771))
|
|
14
|
+
- Report all the config options set via `Appsignal.config` in the DSL config source in the diagnose report. Previously, it would only report the options from the last time `Appsignal.configure` was called. (patch [27b9aff7](https://github.com/appsignal/appsignal-ruby/commit/27b9aff7776646dfef6c55fa589024a71052e70b))
|
|
15
|
+
- Fix 'no implicit conversion of Pathname into String' error when parsing backtrace lines of error causes in Rails apps. (patch [b767f269](https://github.com/appsignal/appsignal-ruby/commit/b767f269c41cb7625d6869d8e8acb9b288292d19))
|
|
16
|
+
|
|
17
|
+
## 4.1.0
|
|
18
|
+
|
|
19
|
+
_Published on 2024-09-26._
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- Add support for heartbeat check-ins.
|
|
24
|
+
|
|
25
|
+
Use the `Appsignal::CheckIn.heartbeat` method to send a single heartbeat check-in event from your application. This can be used, for example, in your application's main loop:
|
|
26
|
+
|
|
27
|
+
```ruby
|
|
28
|
+
loop do
|
|
29
|
+
Appsignal::CheckIn.heartbeat("job_processor")
|
|
30
|
+
process_job
|
|
31
|
+
end
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Heartbeats are deduplicated and sent asynchronously, without blocking the current thread. Regardless of how often the `.heartbeat` method is called, at most one heartbeat with the same identifier will be sent every ten seconds.
|
|
35
|
+
|
|
36
|
+
Pass `continuous: true` as the second argument to send heartbeats continuously during the entire lifetime of the current process. This can be used, for example, after your application has finished its boot process:
|
|
37
|
+
|
|
38
|
+
```ruby
|
|
39
|
+
def main
|
|
40
|
+
start_app
|
|
41
|
+
Appsignal::CheckIn.heartbeat("my_app", continuous: true)
|
|
42
|
+
end
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
(minor [7ae7152c](https://github.com/appsignal/appsignal-ruby/commit/7ae7152cddae7c257e9d62d3bf2433cce1f4287d))
|
|
46
|
+
- Include the first backtrace line from error causes to show where each cause originated in the interface. (patch [496b035a](https://github.com/appsignal/appsignal-ruby/commit/496b035a3510dbb6dc47c7c59172f488ec55c986))
|
|
47
|
+
|
|
3
48
|
## 4.0.9
|
|
4
49
|
|
|
5
50
|
_Published on 2024-09-17._
|
|
@@ -22,13 +22,11 @@ module Appsignal
|
|
|
22
22
|
private
|
|
23
23
|
|
|
24
24
|
def event(kind)
|
|
25
|
-
|
|
25
|
+
Event.cron(
|
|
26
26
|
:identifier => @identifier,
|
|
27
27
|
:digest => @digest,
|
|
28
|
-
:kind => kind
|
|
29
|
-
|
|
30
|
-
:check_in_type => "cron"
|
|
31
|
-
}
|
|
28
|
+
:kind => kind
|
|
29
|
+
)
|
|
32
30
|
end
|
|
33
31
|
end
|
|
34
32
|
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Appsignal
|
|
4
|
+
module CheckIn
|
|
5
|
+
# @api private
|
|
6
|
+
class Event
|
|
7
|
+
class << self
|
|
8
|
+
def new(check_in_type:, identifier:, digest: nil, kind: nil)
|
|
9
|
+
{
|
|
10
|
+
:identifier => identifier,
|
|
11
|
+
:digest => digest,
|
|
12
|
+
:kind => kind,
|
|
13
|
+
:timestamp => Time.now.utc.to_i,
|
|
14
|
+
:check_in_type => check_in_type
|
|
15
|
+
}.compact
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def cron(identifier:, digest:, kind:)
|
|
19
|
+
new(
|
|
20
|
+
:check_in_type => "cron",
|
|
21
|
+
:identifier => identifier,
|
|
22
|
+
:digest => digest,
|
|
23
|
+
:kind => kind
|
|
24
|
+
)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def heartbeat(identifier:)
|
|
28
|
+
new(
|
|
29
|
+
:check_in_type => "heartbeat",
|
|
30
|
+
:identifier => identifier
|
|
31
|
+
)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def redundant?(event, other)
|
|
35
|
+
return false if
|
|
36
|
+
other[:check_in_type] != event[:check_in_type] ||
|
|
37
|
+
other[:identifier] != event[:identifier]
|
|
38
|
+
|
|
39
|
+
return false if event[:check_in_type] == "cron" && (
|
|
40
|
+
other[:digest] != event[:digest] ||
|
|
41
|
+
other[:kind] != event[:kind]
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
return false if
|
|
45
|
+
event[:check_in_type] != "cron" &&
|
|
46
|
+
event[:check_in_type] != "heartbeat"
|
|
47
|
+
|
|
48
|
+
true
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def describe(events)
|
|
52
|
+
if events.empty?
|
|
53
|
+
# This shouldn't happen.
|
|
54
|
+
"no check-in events"
|
|
55
|
+
elsif events.length > 1
|
|
56
|
+
"#{events.length} check-in events"
|
|
57
|
+
else
|
|
58
|
+
event = events.first
|
|
59
|
+
if event[:check_in_type] == "cron"
|
|
60
|
+
"cron check-in `#{event[:identifier] || "unknown"}` " \
|
|
61
|
+
"#{event[:kind] || "unknown"} event (digest #{event[:digest] || "unknown"})"
|
|
62
|
+
elsif event[:check_in_type] == "heartbeat"
|
|
63
|
+
"heartbeat check-in `#{event[:identifier] || "unknown"}` event"
|
|
64
|
+
else
|
|
65
|
+
"unknown check-in event"
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -29,7 +29,7 @@ module Appsignal
|
|
|
29
29
|
def schedule(event)
|
|
30
30
|
unless Appsignal.active?
|
|
31
31
|
Appsignal.internal_logger.debug(
|
|
32
|
-
"Cannot transmit #{describe([event])}: AppSignal is not active"
|
|
32
|
+
"Cannot transmit #{Event.describe([event])}: AppSignal is not active"
|
|
33
33
|
)
|
|
34
34
|
return
|
|
35
35
|
end
|
|
@@ -37,7 +37,7 @@ module Appsignal
|
|
|
37
37
|
@mutex.synchronize do
|
|
38
38
|
if @queue.closed?
|
|
39
39
|
Appsignal.internal_logger.debug(
|
|
40
|
-
"Cannot transmit #{describe([event])}: AppSignal is stopped"
|
|
40
|
+
"Cannot transmit #{Event.describe([event])}: AppSignal is stopped"
|
|
41
41
|
)
|
|
42
42
|
return
|
|
43
43
|
end
|
|
@@ -48,7 +48,7 @@ module Appsignal
|
|
|
48
48
|
start_waker(INITIAL_DEBOUNCE_SECONDS) if @waker.nil?
|
|
49
49
|
|
|
50
50
|
Appsignal.internal_logger.debug(
|
|
51
|
-
"Scheduling #{describe([event])} to be transmitted"
|
|
51
|
+
"Scheduling #{Event.describe([event])} to be transmitted"
|
|
52
52
|
)
|
|
53
53
|
|
|
54
54
|
# Make sure to start the thread after an event has been added.
|
|
@@ -92,7 +92,7 @@ module Appsignal
|
|
|
92
92
|
end
|
|
93
93
|
|
|
94
94
|
def transmit(events)
|
|
95
|
-
description = describe(events)
|
|
95
|
+
description = Event.describe(events)
|
|
96
96
|
|
|
97
97
|
begin
|
|
98
98
|
response = CheckIn.transmitter.transmit(events, :format => :ndjson)
|
|
@@ -110,42 +110,18 @@ module Appsignal
|
|
|
110
110
|
end
|
|
111
111
|
end
|
|
112
112
|
|
|
113
|
-
def describe(events)
|
|
114
|
-
if events.empty?
|
|
115
|
-
# This shouldn't happen.
|
|
116
|
-
"no check-in events"
|
|
117
|
-
elsif events.length > 1
|
|
118
|
-
"#{events.length} check-in events"
|
|
119
|
-
else
|
|
120
|
-
event = events.first
|
|
121
|
-
if event[:check_in_type] == "cron"
|
|
122
|
-
"cron check-in `#{event[:identifier] || "unknown"}` " \
|
|
123
|
-
"#{event[:kind] || "unknown"} event (digest #{event[:digest] || "unknown"})" \
|
|
124
|
-
else
|
|
125
|
-
"unknown check-in event"
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
end
|
|
129
|
-
|
|
130
113
|
# Must be called from within a `@mutex.synchronize` block.
|
|
131
114
|
def add_event(event)
|
|
132
115
|
# Remove redundant events, keeping the newly added one, which
|
|
133
116
|
# should be the one with the most recent timestamp.
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
# digest and kind as the one we're adding.
|
|
137
|
-
@events.reject! do |existing_event|
|
|
138
|
-
next unless existing_event[:identifier] == event[:identifier] &&
|
|
139
|
-
existing_event[:digest] == event[:digest] &&
|
|
140
|
-
existing_event[:kind] == event[:kind] &&
|
|
141
|
-
existing_event[:check_in_type] == "cron"
|
|
117
|
+
@events.reject! do |existing_event|
|
|
118
|
+
next unless Event.redundant?(event, existing_event)
|
|
142
119
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
120
|
+
Appsignal.internal_logger.debug(
|
|
121
|
+
"Replacing previously scheduled #{Event.describe([existing_event])}"
|
|
122
|
+
)
|
|
146
123
|
|
|
147
|
-
|
|
148
|
-
end
|
|
124
|
+
true
|
|
149
125
|
end
|
|
150
126
|
|
|
151
127
|
@events << event
|
data/lib/appsignal/check_in.rb
CHANGED
|
@@ -2,10 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
module Appsignal
|
|
4
4
|
module CheckIn
|
|
5
|
+
HEARTBEAT_CONTINUOUS_INTERVAL_SECONDS = 30
|
|
5
6
|
class << self
|
|
7
|
+
# @api private
|
|
8
|
+
def continuous_heartbeats
|
|
9
|
+
@continuous_heartbeats ||= []
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# @api private
|
|
13
|
+
def kill_continuous_heartbeats
|
|
14
|
+
continuous_heartbeats.each(&:kill)
|
|
15
|
+
end
|
|
16
|
+
|
|
6
17
|
# Track cron check-ins.
|
|
7
18
|
#
|
|
8
|
-
# Track the execution of
|
|
19
|
+
# Track the execution of scheduled processes by sending a cron check-in.
|
|
9
20
|
#
|
|
10
21
|
# To track the duration of a piece of code, pass a block to {.cron}
|
|
11
22
|
# to report both when the process starts, and when it finishes.
|
|
@@ -40,6 +51,37 @@ module Appsignal
|
|
|
40
51
|
output
|
|
41
52
|
end
|
|
42
53
|
|
|
54
|
+
# Track heartbeat check-ins.
|
|
55
|
+
#
|
|
56
|
+
# Track the execution of long-lived processes by sending a heartbeat
|
|
57
|
+
# check-in.
|
|
58
|
+
#
|
|
59
|
+
# @example Send a heartbeat check-in
|
|
60
|
+
# Appsignal::CheckIn.heartbeat("main_loop")
|
|
61
|
+
#
|
|
62
|
+
# @param identifier [String] identifier of the heartbeat check-in to report.
|
|
63
|
+
# @param continuous [Boolean] whether the heartbeats should be sent continuously
|
|
64
|
+
# during the lifetime of the process. Defaults to `false`.
|
|
65
|
+
# @yield the block to monitor.
|
|
66
|
+
# @return [void]
|
|
67
|
+
# @since 4.1.0
|
|
68
|
+
# @see https://docs.appsignal.com/check-ins/heartbeat
|
|
69
|
+
def heartbeat(identifier, continuous: false)
|
|
70
|
+
if continuous
|
|
71
|
+
continuous_heartbeats << Thread.new do
|
|
72
|
+
loop do
|
|
73
|
+
heartbeat(identifier)
|
|
74
|
+
sleep HEARTBEAT_CONTINUOUS_INTERVAL_SECONDS
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
return
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
event = Event.heartbeat(:identifier => identifier)
|
|
82
|
+
scheduler.schedule(event)
|
|
83
|
+
end
|
|
84
|
+
|
|
43
85
|
# @api private
|
|
44
86
|
def transmitter
|
|
45
87
|
@transmitter ||= Transmitter.new(
|
|
@@ -60,5 +102,6 @@ module Appsignal
|
|
|
60
102
|
end
|
|
61
103
|
end
|
|
62
104
|
|
|
105
|
+
require "appsignal/check_in/event"
|
|
63
106
|
require "appsignal/check_in/scheduler"
|
|
64
107
|
require "appsignal/check_in/cron"
|
data/lib/appsignal/config.rb
CHANGED
|
@@ -180,36 +180,19 @@ module Appsignal
|
|
|
180
180
|
"APPSIGNAL_CPU_COUNT" => :cpu_count
|
|
181
181
|
}.freeze
|
|
182
182
|
|
|
183
|
-
# @
|
|
184
|
-
|
|
185
|
-
# Used in diagnose report.
|
|
186
|
-
# @api private
|
|
187
|
-
# @return [Hash]
|
|
188
|
-
# @!attribute [r] file_config
|
|
189
|
-
# Config loaded from `config/appsignal.yml` config file.
|
|
190
|
-
# Used in diagnose report.
|
|
191
|
-
# @api private
|
|
192
|
-
# @return [Hash]
|
|
193
|
-
# @!attribute [r] env_config
|
|
194
|
-
# Config loaded from the system environment.
|
|
195
|
-
# Used in diagnose report.
|
|
196
|
-
# @api private
|
|
197
|
-
# @return [Hash]
|
|
198
|
-
# @!attribute [r] config_hash
|
|
199
|
-
# Config used by the AppSignal gem.
|
|
200
|
-
# Combined Hash of the {system_config}, {file_config}, {env_config}
|
|
201
|
-
# attributes.
|
|
202
|
-
# @see #[]
|
|
203
|
-
# @see #[]=
|
|
204
|
-
# @api private
|
|
205
|
-
# @return [Hash]
|
|
183
|
+
# @api private
|
|
184
|
+
attr_reader :root_path, :env, :config_hash
|
|
206
185
|
|
|
186
|
+
# List of config option sources. If a config option was set by a source,
|
|
187
|
+
# it's listed in that source's config options hash.
|
|
188
|
+
#
|
|
189
|
+
# These options are merged as the config is initialized.
|
|
190
|
+
# Their values cannot be changed after the config is initialized.
|
|
191
|
+
#
|
|
192
|
+
# Used by the diagnose report to list which value was read from which source.
|
|
207
193
|
# @api private
|
|
208
|
-
attr_accessor :root_path, :env, :config_hash
|
|
209
194
|
attr_reader :system_config, :loaders_config, :initial_config, :file_config,
|
|
210
195
|
:env_config, :override_config, :dsl_config
|
|
211
|
-
# @api private
|
|
212
|
-
attr_accessor :logger
|
|
213
196
|
|
|
214
197
|
# Initialize a new configuration object for AppSignal.
|
|
215
198
|
#
|
|
@@ -217,9 +200,6 @@ module Appsignal
|
|
|
217
200
|
# @param env [String] The environment to load when AppSignal is started. It
|
|
218
201
|
# will look for an environment with this name in the `config/appsignal.yml`
|
|
219
202
|
# config file.
|
|
220
|
-
# @param logger [Logger] The logger to use for the AppSignal gem. This is
|
|
221
|
-
# used by the configuration class only. Default:
|
|
222
|
-
# {Appsignal.internal_logger}. See also {Appsignal.start}.
|
|
223
203
|
#
|
|
224
204
|
# @api private
|
|
225
205
|
# @see https://docs.appsignal.com/ruby/configuration/
|
|
@@ -230,13 +210,11 @@ module Appsignal
|
|
|
230
210
|
# How to integrate AppSignal manually
|
|
231
211
|
def initialize(
|
|
232
212
|
root_path,
|
|
233
|
-
env
|
|
234
|
-
logger = Appsignal.internal_logger
|
|
213
|
+
env
|
|
235
214
|
)
|
|
236
|
-
@root_path = root_path
|
|
215
|
+
@root_path = root_path.to_s
|
|
237
216
|
@config_file_error = false
|
|
238
217
|
@config_file = config_file
|
|
239
|
-
@logger = logger
|
|
240
218
|
@valid = false
|
|
241
219
|
|
|
242
220
|
@env = env.to_s
|
|
@@ -402,7 +380,7 @@ module Appsignal
|
|
|
402
380
|
|
|
403
381
|
# @api private
|
|
404
382
|
def merge_dsl_options(options)
|
|
405
|
-
@dsl_config
|
|
383
|
+
@dsl_config.merge!(options)
|
|
406
384
|
merge(options)
|
|
407
385
|
end
|
|
408
386
|
|
|
@@ -426,7 +404,7 @@ module Appsignal
|
|
|
426
404
|
push_api_key = config_hash[:push_api_key] || ""
|
|
427
405
|
if push_api_key.strip.empty?
|
|
428
406
|
@valid = false
|
|
429
|
-
|
|
407
|
+
logger.error "Push API key not set after loading config"
|
|
430
408
|
else
|
|
431
409
|
@valid = true
|
|
432
410
|
end
|
|
@@ -445,6 +423,10 @@ module Appsignal
|
|
|
445
423
|
|
|
446
424
|
private
|
|
447
425
|
|
|
426
|
+
def logger
|
|
427
|
+
Appsignal.internal_logger
|
|
428
|
+
end
|
|
429
|
+
|
|
448
430
|
def config_file
|
|
449
431
|
@config_file ||=
|
|
450
432
|
root_path.nil? ? nil : File.join(root_path, "config", "appsignal.yml")
|
|
@@ -546,7 +528,7 @@ module Appsignal
|
|
|
546
528
|
|
|
547
529
|
def merge(new_config)
|
|
548
530
|
new_config.each do |key, value|
|
|
549
|
-
|
|
531
|
+
logger.debug("Config key '#{key}' is being overwritten") unless config_hash[key].nil?
|
|
550
532
|
config_hash[key] = value
|
|
551
533
|
end
|
|
552
534
|
end
|
|
@@ -10,12 +10,12 @@ namespace :appsignal do
|
|
|
10
10
|
|
|
11
11
|
appsignal_config = Appsignal::Config.new(
|
|
12
12
|
Dir.pwd,
|
|
13
|
-
appsignal_env
|
|
14
|
-
Logger.new(StringIO.new)
|
|
13
|
+
appsignal_env
|
|
15
14
|
).tap do |c|
|
|
16
15
|
c.merge_dsl_options(fetch(:appsignal_config, {}))
|
|
17
16
|
c.validate
|
|
18
17
|
end
|
|
18
|
+
Appsignal._start_logger
|
|
19
19
|
|
|
20
20
|
if appsignal_config&.active?
|
|
21
21
|
marker_data = {
|
|
@@ -18,12 +18,12 @@ module Appsignal
|
|
|
18
18
|
|
|
19
19
|
appsignal_config = Appsignal::Config.new(
|
|
20
20
|
ENV.fetch("PWD", nil),
|
|
21
|
-
env
|
|
22
|
-
Appsignal::Utils::IntegrationLogger.new(StringIO.new)
|
|
21
|
+
env
|
|
23
22
|
).tap do |c|
|
|
24
23
|
c.merge_dsl_options(fetch(:appsignal_config, {}))
|
|
25
24
|
c.validate
|
|
26
25
|
end
|
|
26
|
+
Appsignal._start_logger
|
|
27
27
|
|
|
28
28
|
if appsignal_config&.active?
|
|
29
29
|
marker_data = {
|
|
@@ -94,6 +94,7 @@ module Appsignal
|
|
|
94
94
|
transaction.set_action(action_name) if action_name
|
|
95
95
|
transaction.add_custom_data(custom_data) if custom_data
|
|
96
96
|
|
|
97
|
+
tags[:reported_by] = :rails_error_reporter
|
|
97
98
|
tags[:severity] = severity
|
|
98
99
|
tags[:source] = source.to_s if source
|
|
99
100
|
transaction.add_tags(tags)
|
|
@@ -627,7 +627,8 @@ module Appsignal
|
|
|
627
627
|
causes_sample_data = causes.map do |e|
|
|
628
628
|
{
|
|
629
629
|
:name => e.class.name,
|
|
630
|
-
:message => cleaned_error_message(e)
|
|
630
|
+
:message => cleaned_error_message(e),
|
|
631
|
+
:first_line => first_formatted_backtrace_line(e)
|
|
631
632
|
}
|
|
632
633
|
end
|
|
633
634
|
|
|
@@ -639,6 +640,36 @@ module Appsignal
|
|
|
639
640
|
)
|
|
640
641
|
end
|
|
641
642
|
|
|
643
|
+
BACKTRACE_REGEX =
|
|
644
|
+
%r{(?<gem>[\w-]+ \(.+\) )?(?<path>:?/?\w+?.+?):(?<line>:?\d+)(?<group>:in `(?<method>.+)')?$}.freeze # rubocop:disable Layout/LineLength
|
|
645
|
+
|
|
646
|
+
def first_formatted_backtrace_line(error)
|
|
647
|
+
backtrace = cleaned_backtrace(error.backtrace)
|
|
648
|
+
first_line = backtrace&.first
|
|
649
|
+
return unless first_line
|
|
650
|
+
|
|
651
|
+
captures = BACKTRACE_REGEX.match(first_line)
|
|
652
|
+
return unless captures
|
|
653
|
+
|
|
654
|
+
captures.named_captures
|
|
655
|
+
.merge("original" => first_line)
|
|
656
|
+
.tap do |c|
|
|
657
|
+
config = Appsignal.config
|
|
658
|
+
c.delete("group") # Unused key, only for easier matching
|
|
659
|
+
# Strip of whitespace at the end of the gem name
|
|
660
|
+
c["gem"] = c["gem"]&.strip
|
|
661
|
+
# Strip the app path from the path if present
|
|
662
|
+
root_path = config.root_path
|
|
663
|
+
if c["path"].start_with?(root_path)
|
|
664
|
+
c["path"].delete_prefix!(root_path)
|
|
665
|
+
# Relative paths shouldn't start with a slash
|
|
666
|
+
c["path"].delete_prefix!("/")
|
|
667
|
+
end
|
|
668
|
+
# Add revision for linking to the repository from the UI
|
|
669
|
+
c["revision"] = config[:revision]
|
|
670
|
+
end
|
|
671
|
+
end
|
|
672
|
+
|
|
642
673
|
def set_sample_data(key, data)
|
|
643
674
|
return unless key && data
|
|
644
675
|
|
|
@@ -107,7 +107,7 @@ module Appsignal
|
|
|
107
107
|
if ca_file && File.exist?(ca_file) && File.readable?(ca_file)
|
|
108
108
|
http.ca_file = ca_file
|
|
109
109
|
else
|
|
110
|
-
|
|
110
|
+
Appsignal.internal_logger.warn "Ignoring non-existing or unreadable " \
|
|
111
111
|
"`ca_file_path`: #{ca_file}"
|
|
112
112
|
end
|
|
113
113
|
end
|
data/lib/appsignal/version.rb
CHANGED
data/lib/appsignal.rb
CHANGED
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.
|
|
4
|
+
version: 4.1.1
|
|
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: 2024-09-
|
|
13
|
+
date: 2024-09-28 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: logger
|
|
@@ -181,6 +181,7 @@ files:
|
|
|
181
181
|
- lib/appsignal/capistrano.rb
|
|
182
182
|
- lib/appsignal/check_in.rb
|
|
183
183
|
- lib/appsignal/check_in/cron.rb
|
|
184
|
+
- lib/appsignal/check_in/event.rb
|
|
184
185
|
- lib/appsignal/check_in/scheduler.rb
|
|
185
186
|
- lib/appsignal/cli.rb
|
|
186
187
|
- lib/appsignal/cli/demo.rb
|