appsignal 3.7.0-java → 3.7.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 +4 -4
- data/.semaphore/semaphore.yml +417 -0
- data/CHANGELOG.md +27 -0
- data/build_matrix.yml +8 -0
- data/ext/agent.rb +27 -27
- data/ext/base.rb +3 -0
- data/lib/appsignal/config.rb +16 -7
- data/lib/appsignal/event_formatter.rb +0 -2
- data/lib/appsignal/helpers/instrumentation.rb +5 -5
- data/lib/appsignal/helpers/metrics.rb +2 -2
- data/lib/appsignal/hooks/gvl.rb +1 -1
- data/lib/appsignal/hooks/mri.rb +1 -1
- data/lib/appsignal/hooks/sidekiq.rb +1 -1
- data/lib/appsignal/hooks.rb +1 -1
- data/lib/appsignal/integrations/railtie.rb +1 -1
- data/lib/appsignal/probes.rb +268 -0
- data/lib/appsignal/utils/stdout_and_logger_message.rb +17 -0
- data/lib/appsignal/utils.rb +1 -1
- data/lib/appsignal/version.rb +1 -1
- data/lib/appsignal.rb +23 -4
- data/spec/lib/appsignal/config_spec.rb +32 -10
- data/spec/lib/appsignal/hooks/gvl_spec.rb +1 -1
- data/spec/lib/appsignal/hooks/mri_spec.rb +1 -1
- data/spec/lib/appsignal/hooks/puma_spec.rb +1 -1
- data/spec/lib/appsignal/{minutely_spec.rb → probes_spec.rb} +206 -57
- data/spec/lib/appsignal_spec.rb +31 -5
- data/spec/lib/puma/appsignal_spec.rb +8 -2
- data/spec/spec_helper.rb +2 -2
- metadata +5 -6
- data/lib/appsignal/minutely.rb +0 -206
- data/lib/appsignal/utils/deprecation_message.rb +0 -16
data/ext/agent.rb
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
# Modifications to this file will be overwritten with the next agent release.
|
7
7
|
|
8
8
|
APPSIGNAL_AGENT_CONFIG = {
|
9
|
-
"version" => "0.35.
|
9
|
+
"version" => "0.35.5",
|
10
10
|
"mirrors" => [
|
11
11
|
"https://appsignal-agent-releases.global.ssl.fastly.net",
|
12
12
|
"https://d135dj0rjqvssy.cloudfront.net"
|
@@ -14,131 +14,131 @@ APPSIGNAL_AGENT_CONFIG = {
|
|
14
14
|
"triples" => {
|
15
15
|
"x86_64-darwin" => {
|
16
16
|
"static" => {
|
17
|
-
"checksum" => "
|
17
|
+
"checksum" => "3985b53b2a2814d44737182890e6fbe31b4b88361025140477a598e0e41fd948",
|
18
18
|
"filename" => "appsignal-x86_64-darwin-all-static.tar.gz"
|
19
19
|
},
|
20
20
|
"dynamic" => {
|
21
|
-
"checksum" => "
|
21
|
+
"checksum" => "d135e2daf5c041a4ce7a7ab720cfd977fbae8375a007995e33a96558d3635792",
|
22
22
|
"filename" => "appsignal-x86_64-darwin-all-dynamic.tar.gz"
|
23
23
|
}
|
24
24
|
},
|
25
25
|
"universal-darwin" => {
|
26
26
|
"static" => {
|
27
|
-
"checksum" => "
|
27
|
+
"checksum" => "3985b53b2a2814d44737182890e6fbe31b4b88361025140477a598e0e41fd948",
|
28
28
|
"filename" => "appsignal-x86_64-darwin-all-static.tar.gz"
|
29
29
|
},
|
30
30
|
"dynamic" => {
|
31
|
-
"checksum" => "
|
31
|
+
"checksum" => "d135e2daf5c041a4ce7a7ab720cfd977fbae8375a007995e33a96558d3635792",
|
32
32
|
"filename" => "appsignal-x86_64-darwin-all-dynamic.tar.gz"
|
33
33
|
}
|
34
34
|
},
|
35
35
|
"aarch64-darwin" => {
|
36
36
|
"static" => {
|
37
|
-
"checksum" => "
|
37
|
+
"checksum" => "79d22436bfe32dab4661f2a4149c6ab34c71e810c5d808ee3e60cd9f8a1395e4",
|
38
38
|
"filename" => "appsignal-aarch64-darwin-all-static.tar.gz"
|
39
39
|
},
|
40
40
|
"dynamic" => {
|
41
|
-
"checksum" => "
|
41
|
+
"checksum" => "2c49c8f24a9dd8f9d55c28015b3e1096180807e7b13d4a9cd8ed30f58bc6612f",
|
42
42
|
"filename" => "appsignal-aarch64-darwin-all-dynamic.tar.gz"
|
43
43
|
}
|
44
44
|
},
|
45
45
|
"arm64-darwin" => {
|
46
46
|
"static" => {
|
47
|
-
"checksum" => "
|
47
|
+
"checksum" => "79d22436bfe32dab4661f2a4149c6ab34c71e810c5d808ee3e60cd9f8a1395e4",
|
48
48
|
"filename" => "appsignal-aarch64-darwin-all-static.tar.gz"
|
49
49
|
},
|
50
50
|
"dynamic" => {
|
51
|
-
"checksum" => "
|
51
|
+
"checksum" => "2c49c8f24a9dd8f9d55c28015b3e1096180807e7b13d4a9cd8ed30f58bc6612f",
|
52
52
|
"filename" => "appsignal-aarch64-darwin-all-dynamic.tar.gz"
|
53
53
|
}
|
54
54
|
},
|
55
55
|
"arm-darwin" => {
|
56
56
|
"static" => {
|
57
|
-
"checksum" => "
|
57
|
+
"checksum" => "79d22436bfe32dab4661f2a4149c6ab34c71e810c5d808ee3e60cd9f8a1395e4",
|
58
58
|
"filename" => "appsignal-aarch64-darwin-all-static.tar.gz"
|
59
59
|
},
|
60
60
|
"dynamic" => {
|
61
|
-
"checksum" => "
|
61
|
+
"checksum" => "2c49c8f24a9dd8f9d55c28015b3e1096180807e7b13d4a9cd8ed30f58bc6612f",
|
62
62
|
"filename" => "appsignal-aarch64-darwin-all-dynamic.tar.gz"
|
63
63
|
}
|
64
64
|
},
|
65
65
|
"aarch64-linux" => {
|
66
66
|
"static" => {
|
67
|
-
"checksum" => "
|
67
|
+
"checksum" => "4a54587bb61f59d0b60032b2e0c1d14d2e726e20af049353c2ff279d07dd3028",
|
68
68
|
"filename" => "appsignal-aarch64-linux-all-static.tar.gz"
|
69
69
|
},
|
70
70
|
"dynamic" => {
|
71
|
-
"checksum" => "
|
71
|
+
"checksum" => "aa2d011c538ce547c87110e7c8e49a24597d60ea2d1418032fc3db06267efba2",
|
72
72
|
"filename" => "appsignal-aarch64-linux-all-dynamic.tar.gz"
|
73
73
|
}
|
74
74
|
},
|
75
75
|
"i686-linux" => {
|
76
76
|
"static" => {
|
77
|
-
"checksum" => "
|
77
|
+
"checksum" => "01e2237029c3af23cc6f348fb63f65a92b8caf8f4731b78d014bb4001559aad5",
|
78
78
|
"filename" => "appsignal-i686-linux-all-static.tar.gz"
|
79
79
|
},
|
80
80
|
"dynamic" => {
|
81
|
-
"checksum" => "
|
81
|
+
"checksum" => "c1043ac92b000a406d9afb77b6ec1d3ab6cfffd63c218a720c11daa3edb7fd1f",
|
82
82
|
"filename" => "appsignal-i686-linux-all-dynamic.tar.gz"
|
83
83
|
}
|
84
84
|
},
|
85
85
|
"x86-linux" => {
|
86
86
|
"static" => {
|
87
|
-
"checksum" => "
|
87
|
+
"checksum" => "01e2237029c3af23cc6f348fb63f65a92b8caf8f4731b78d014bb4001559aad5",
|
88
88
|
"filename" => "appsignal-i686-linux-all-static.tar.gz"
|
89
89
|
},
|
90
90
|
"dynamic" => {
|
91
|
-
"checksum" => "
|
91
|
+
"checksum" => "c1043ac92b000a406d9afb77b6ec1d3ab6cfffd63c218a720c11daa3edb7fd1f",
|
92
92
|
"filename" => "appsignal-i686-linux-all-dynamic.tar.gz"
|
93
93
|
}
|
94
94
|
},
|
95
95
|
"x86_64-linux" => {
|
96
96
|
"static" => {
|
97
|
-
"checksum" => "
|
97
|
+
"checksum" => "beae1db2c122eb579f1ccb450177b0c64d65569d774efc7a1ee72c42d3382d39",
|
98
98
|
"filename" => "appsignal-x86_64-linux-all-static.tar.gz"
|
99
99
|
},
|
100
100
|
"dynamic" => {
|
101
|
-
"checksum" => "
|
101
|
+
"checksum" => "67650f59d2ea9c99cde7dfe44da65a506522a3cdccabe697931d89ebaea96d18",
|
102
102
|
"filename" => "appsignal-x86_64-linux-all-dynamic.tar.gz"
|
103
103
|
}
|
104
104
|
},
|
105
105
|
"x86_64-linux-musl" => {
|
106
106
|
"static" => {
|
107
|
-
"checksum" => "
|
107
|
+
"checksum" => "521c4486d10cdafa1f72103cc439d6f0e4f549f1522c4473bf43dc487ec42436",
|
108
108
|
"filename" => "appsignal-x86_64-linux-musl-all-static.tar.gz"
|
109
109
|
},
|
110
110
|
"dynamic" => {
|
111
|
-
"checksum" => "
|
111
|
+
"checksum" => "0a94fcee8eb1f8fd06fce3eacffbcf9f2a52f5cde040796e19a589176525db4b",
|
112
112
|
"filename" => "appsignal-x86_64-linux-musl-all-dynamic.tar.gz"
|
113
113
|
}
|
114
114
|
},
|
115
115
|
"aarch64-linux-musl" => {
|
116
116
|
"static" => {
|
117
|
-
"checksum" => "
|
117
|
+
"checksum" => "c29aab31f4ca59efb1483f48c0cb3c27d799347b81655a28f24c146b55aa7db6",
|
118
118
|
"filename" => "appsignal-aarch64-linux-musl-all-static.tar.gz"
|
119
119
|
},
|
120
120
|
"dynamic" => {
|
121
|
-
"checksum" => "
|
121
|
+
"checksum" => "4b77ea0c1f50ada6e5f6ed693002e56db1e34e0e9d5fdb4ac80fc52fd51099b8",
|
122
122
|
"filename" => "appsignal-aarch64-linux-musl-all-dynamic.tar.gz"
|
123
123
|
}
|
124
124
|
},
|
125
125
|
"x86_64-freebsd" => {
|
126
126
|
"static" => {
|
127
|
-
"checksum" => "
|
127
|
+
"checksum" => "a3598e9df1b6b5970aabbbccbe4e77c2372d2320cd87bfa20f32fca53b8505e4",
|
128
128
|
"filename" => "appsignal-x86_64-freebsd-all-static.tar.gz"
|
129
129
|
},
|
130
130
|
"dynamic" => {
|
131
|
-
"checksum" => "
|
131
|
+
"checksum" => "4cbfd5e16776c8ea4308ee7f3a096c5cc137f2506f8a05d9c8504e3483fcd8ac",
|
132
132
|
"filename" => "appsignal-x86_64-freebsd-all-dynamic.tar.gz"
|
133
133
|
}
|
134
134
|
},
|
135
135
|
"amd64-freebsd" => {
|
136
136
|
"static" => {
|
137
|
-
"checksum" => "
|
137
|
+
"checksum" => "a3598e9df1b6b5970aabbbccbe4e77c2372d2320cd87bfa20f32fca53b8505e4",
|
138
138
|
"filename" => "appsignal-x86_64-freebsd-all-static.tar.gz"
|
139
139
|
},
|
140
140
|
"dynamic" => {
|
141
|
-
"checksum" => "
|
141
|
+
"checksum" => "4cbfd5e16776c8ea4308ee7f3a096c5cc137f2506f8a05d9c8504e3483fcd8ac",
|
142
142
|
"filename" => "appsignal-x86_64-freebsd-all-dynamic.tar.gz"
|
143
143
|
}
|
144
144
|
}
|
data/ext/base.rb
CHANGED
@@ -190,6 +190,9 @@ def store_download_version_on_report
|
|
190
190
|
end
|
191
191
|
|
192
192
|
def http_proxy
|
193
|
+
proxy = try_http_proxy_value(ENV.fetch("APPSIGNAL_HTTP_PROXY", nil))
|
194
|
+
return [proxy, nil] if proxy
|
195
|
+
|
193
196
|
proxy, error =
|
194
197
|
begin
|
195
198
|
[try_http_proxy_value(Gem.configuration[:http_proxy]), nil]
|
data/lib/appsignal/config.rb
CHANGED
@@ -8,7 +8,7 @@ require "tmpdir"
|
|
8
8
|
|
9
9
|
module Appsignal
|
10
10
|
class Config
|
11
|
-
include Appsignal::Utils::
|
11
|
+
include Appsignal::Utils::StdoutAndLoggerMessage
|
12
12
|
|
13
13
|
DEFAULT_CONFIG = {
|
14
14
|
:activejob_report_errors => "all",
|
@@ -320,20 +320,29 @@ module Appsignal
|
|
320
320
|
end
|
321
321
|
|
322
322
|
def log_file_path
|
323
|
+
return @log_file_path if defined? @log_file_path
|
324
|
+
|
323
325
|
path = config_hash[:log_path] || (root_path && File.join(root_path, "log"))
|
324
|
-
|
326
|
+
if path && File.writable?(path)
|
327
|
+
@log_file_path = File.join(File.realpath(path), "appsignal.log")
|
328
|
+
return @log_file_path
|
329
|
+
end
|
325
330
|
|
326
331
|
system_tmp_dir = self.class.system_tmp_dir
|
327
332
|
if File.writable? system_tmp_dir
|
328
333
|
$stdout.puts "appsignal: Unable to log to '#{path}'. Logging to " \
|
329
|
-
"'#{system_tmp_dir}' instead.
|
330
|
-
"permissions for the application's (log)
|
331
|
-
|
334
|
+
"'#{system_tmp_dir}' instead. " \
|
335
|
+
"Please check the permissions for the application's (log) " \
|
336
|
+
"directory."
|
337
|
+
@log_file_path = File.join(system_tmp_dir, "appsignal.log")
|
332
338
|
else
|
333
339
|
$stdout.puts "appsignal: Unable to log to '#{path}' or the " \
|
334
340
|
"'#{system_tmp_dir}' fallback. Please check the permissions " \
|
335
341
|
"for the application's (log) directory."
|
342
|
+
@log_file_path = nil
|
336
343
|
end
|
344
|
+
|
345
|
+
@log_file_path
|
337
346
|
end
|
338
347
|
|
339
348
|
def valid?
|
@@ -476,7 +485,7 @@ module Appsignal
|
|
476
485
|
def maintain_backwards_compatibility
|
477
486
|
return unless config_hash.key?(:working_dir_path)
|
478
487
|
|
479
|
-
|
488
|
+
stdout_and_logger_warning \
|
480
489
|
"The `working_dir_path` option is deprecated, please use " \
|
481
490
|
"`working_directory_path` instead and specify the " \
|
482
491
|
"full path to the working directory",
|
@@ -542,7 +551,7 @@ module Appsignal
|
|
542
551
|
config[:send_session_data] = true # Set default value
|
543
552
|
end
|
544
553
|
else
|
545
|
-
|
554
|
+
stdout_and_logger_warning "The `skip_session_data` config option is " \
|
546
555
|
"deprecated. Please use `send_session_data` instead.",
|
547
556
|
logger
|
548
557
|
# Not configured by user
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module Appsignal
|
4
4
|
module Helpers
|
5
5
|
module Instrumentation # rubocop:disable Metrics/ModuleLength
|
6
|
-
include Appsignal::Utils::
|
6
|
+
include Appsignal::Utils::StdoutAndLoggerMessage
|
7
7
|
|
8
8
|
# Creates an AppSignal transaction for the given block.
|
9
9
|
#
|
@@ -207,7 +207,7 @@ module Appsignal
|
|
207
207
|
)
|
208
208
|
if tags
|
209
209
|
call_location = caller(1..1).first
|
210
|
-
|
210
|
+
stdout_and_logger_warning \
|
211
211
|
"The tags argument for `Appsignal.send_error` is deprecated. " \
|
212
212
|
"Please use the block method to set tags instead.\n\n" \
|
213
213
|
" Appsignal.send_error(error) do |transaction|\n" \
|
@@ -217,7 +217,7 @@ module Appsignal
|
|
217
217
|
end
|
218
218
|
if namespace
|
219
219
|
call_location = caller(1..1).first
|
220
|
-
|
220
|
+
stdout_and_logger_warning \
|
221
221
|
"The namespace argument for `Appsignal.send_error` is deprecated. " \
|
222
222
|
"Please use the block method to set the namespace instead.\n\n" \
|
223
223
|
" Appsignal.send_error(error) do |transaction|\n" \
|
@@ -300,7 +300,7 @@ module Appsignal
|
|
300
300
|
def set_error(exception, tags = nil, namespace = nil)
|
301
301
|
if tags
|
302
302
|
call_location = caller(1..1).first
|
303
|
-
|
303
|
+
stdout_and_logger_warning \
|
304
304
|
"The tags argument for `Appsignal.set_error` is deprecated. " \
|
305
305
|
"Please use the block method to set tags instead.\n\n" \
|
306
306
|
" Appsignal.set_error(error) do |transaction|\n" \
|
@@ -310,7 +310,7 @@ module Appsignal
|
|
310
310
|
end
|
311
311
|
if namespace
|
312
312
|
call_location = caller(1..1).first
|
313
|
-
|
313
|
+
stdout_and_logger_warning \
|
314
314
|
"The namespace argument for `Appsignal.set_error` is deprecated. " \
|
315
315
|
"Please use the block method to set the namespace instead.\n\n" \
|
316
316
|
" Appsignal.set_error(error) do |transaction|\n" \
|
@@ -15,7 +15,7 @@ module Appsignal
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def set_host_gauge(_key, _value)
|
18
|
-
Appsignal::Utils::
|
18
|
+
Appsignal::Utils::StdoutAndLoggerMessage.warning \
|
19
19
|
"The `set_host_gauge` method has been deprecated. " \
|
20
20
|
"Calling this method has no effect. " \
|
21
21
|
"Please remove method call in the following file to remove " \
|
@@ -23,7 +23,7 @@ module Appsignal
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def set_process_gauge(_key, _value)
|
26
|
-
Appsignal::Utils::
|
26
|
+
Appsignal::Utils::StdoutAndLoggerMessage.warning \
|
27
27
|
"The `set_process_gauge` method has been deprecated. " \
|
28
28
|
"Calling this method has no effect. " \
|
29
29
|
"Please remove method call in the following file to remove " \
|
data/lib/appsignal/hooks/gvl.rb
CHANGED
@@ -16,7 +16,7 @@ module Appsignal
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def install
|
19
|
-
Appsignal::
|
19
|
+
Appsignal::Probes.register :gvl, Appsignal::Probes::GvlProbe
|
20
20
|
::GVLTools::GlobalTimer.enable if Appsignal.config[:enable_gvl_global_timer]
|
21
21
|
::GVLTools::WaitingThreads.enable if Appsignal.config[:enable_gvl_waiting_threads]
|
22
22
|
end
|
data/lib/appsignal/hooks/mri.rb
CHANGED
@@ -11,7 +11,7 @@ module Appsignal
|
|
11
11
|
|
12
12
|
def install
|
13
13
|
require "appsignal/integrations/sidekiq"
|
14
|
-
Appsignal::
|
14
|
+
Appsignal::Probes.register :sidekiq, Appsignal::Probes::SidekiqProbe
|
15
15
|
|
16
16
|
::Sidekiq.configure_server do |config|
|
17
17
|
config.error_handlers <<
|
data/lib/appsignal/hooks.rb
CHANGED
@@ -76,7 +76,7 @@ module Appsignal
|
|
76
76
|
when :SidekiqPlugin
|
77
77
|
require "appsignal/integrations/sidekiq"
|
78
78
|
callers = caller
|
79
|
-
Appsignal::Utils::
|
79
|
+
Appsignal::Utils::StdoutAndLoggerMessage.warning \
|
80
80
|
"The constant Appsignal::Hooks::SidekiqPlugin has been deprecated. " \
|
81
81
|
"Please update the constant name to Appsignal::Integrations::SidekiqMiddleware " \
|
82
82
|
"in the following file to remove this message.\n#{callers.first}"
|
data/lib/appsignal/probes.rb
CHANGED
@@ -2,6 +2,274 @@
|
|
2
2
|
|
3
3
|
module Appsignal
|
4
4
|
module Probes
|
5
|
+
class ProbeCollection
|
6
|
+
def initialize
|
7
|
+
@probes = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
# @return [Integer] Number of probes that are registered.
|
11
|
+
def count
|
12
|
+
probes.count
|
13
|
+
end
|
14
|
+
|
15
|
+
# Clears all probes from the list.
|
16
|
+
# @return [void]
|
17
|
+
def clear
|
18
|
+
probes.clear
|
19
|
+
end
|
20
|
+
|
21
|
+
# Fetch a probe using its name.
|
22
|
+
# @param key [Symbol/String] The name of the probe to fetch.
|
23
|
+
# @return [Object] Returns the registered probe.
|
24
|
+
def [](key)
|
25
|
+
probes[key]
|
26
|
+
end
|
27
|
+
|
28
|
+
# @deprecated Use {Appsignal::Probes.register} instead.
|
29
|
+
def register(name, probe)
|
30
|
+
Appsignal::Utils::StdoutAndLoggerMessage.warning(
|
31
|
+
"The method 'Appsignal::Probes.probes.register' is deprecated. " \
|
32
|
+
"Use 'Appsignal::Probes.register' instead."
|
33
|
+
)
|
34
|
+
Appsignal::Probes.register(name, probe)
|
35
|
+
end
|
36
|
+
|
37
|
+
# @api private
|
38
|
+
def internal_register(name, probe)
|
39
|
+
if probes.key?(name)
|
40
|
+
logger.debug "A probe with the name `#{name}` is already " \
|
41
|
+
"registered. Overwriting the entry with the new probe."
|
42
|
+
end
|
43
|
+
probes[name] = probe
|
44
|
+
end
|
45
|
+
|
46
|
+
# @api private
|
47
|
+
def unregister(name)
|
48
|
+
probes.delete(name)
|
49
|
+
end
|
50
|
+
|
51
|
+
# @api private
|
52
|
+
def each(&block)
|
53
|
+
probes.each(&block)
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
attr_reader :probes
|
59
|
+
|
60
|
+
def logger
|
61
|
+
Appsignal.internal_logger
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class << self
|
66
|
+
# @api private
|
67
|
+
def mutex
|
68
|
+
@mutex ||= Thread::Mutex.new
|
69
|
+
end
|
70
|
+
|
71
|
+
# @see ProbeCollection
|
72
|
+
# @return [ProbeCollection] Returns list of probes.
|
73
|
+
def probes
|
74
|
+
@probes ||= ProbeCollection.new
|
75
|
+
end
|
76
|
+
|
77
|
+
# Register a new minutely probe.
|
78
|
+
#
|
79
|
+
# Supported probe types are:
|
80
|
+
#
|
81
|
+
# - Lambda - A lambda is an object that listens to a `call` method call.
|
82
|
+
# This `call` method is called every minute.
|
83
|
+
# - Class - A class object is an object that listens to a `new` and
|
84
|
+
# `call` method call. The `new` method is called when the minutely
|
85
|
+
# probe thread is started to initialize all probes. This allows probes
|
86
|
+
# to load dependencies once beforehand. Their `call` method is called
|
87
|
+
# every minute.
|
88
|
+
# - Class instance - A class instance object is an object that listens to
|
89
|
+
# a `call` method call. The `call` method is called every minute.
|
90
|
+
#
|
91
|
+
# @example Register a new probe
|
92
|
+
# Appsignal::Probes.register :my_probe, lambda {}
|
93
|
+
#
|
94
|
+
# @example Overwrite an existing registered probe
|
95
|
+
# Appsignal::Probes.register :my_probe, lambda {}
|
96
|
+
# Appsignal::Probes.register :my_probe, lambda { puts "hello" }
|
97
|
+
#
|
98
|
+
# @example Add a lambda as a probe
|
99
|
+
# Appsignal::Probes.register :my_probe, lambda { puts "hello" }
|
100
|
+
# # "hello" # printed every minute
|
101
|
+
#
|
102
|
+
# @example Add a probe instance
|
103
|
+
# class MyProbe
|
104
|
+
# def initialize
|
105
|
+
# puts "started"
|
106
|
+
# end
|
107
|
+
#
|
108
|
+
# def call
|
109
|
+
# puts "called"
|
110
|
+
# end
|
111
|
+
# end
|
112
|
+
#
|
113
|
+
# Appsignal::Probes.register :my_probe, MyProbe.new
|
114
|
+
# # "started" # printed immediately
|
115
|
+
# # "called" # printed every minute
|
116
|
+
#
|
117
|
+
# @example Add a probe class
|
118
|
+
# class MyProbe
|
119
|
+
# def initialize
|
120
|
+
# # Add things that only need to be done on start up for this probe
|
121
|
+
# require "some/library/dependency"
|
122
|
+
# @cache = {} # initialize a local cache variable
|
123
|
+
# puts "started"
|
124
|
+
# end
|
125
|
+
#
|
126
|
+
# def call
|
127
|
+
# puts "called"
|
128
|
+
# end
|
129
|
+
# end
|
130
|
+
#
|
131
|
+
# Appsignal::Probes.register :my_probe, MyProbe
|
132
|
+
# Appsignal::Probes.start # This is called for you
|
133
|
+
# # "started" # Printed on Appsignal::Probes.start
|
134
|
+
# # "called" # Repeated every minute
|
135
|
+
#
|
136
|
+
# @param name [Symbol/String] Name of the probe. Can be used with
|
137
|
+
# {ProbeCollection#[]}. This name will be used in errors in the log and
|
138
|
+
# allows overwriting of probes by registering new ones with the same
|
139
|
+
# name.
|
140
|
+
# @param probe [Object] Any object that listens to the `call` method will
|
141
|
+
# be used as a probe.
|
142
|
+
# @return [void]
|
143
|
+
def register(name, probe)
|
144
|
+
probes.internal_register(name, probe)
|
145
|
+
|
146
|
+
initialize_probe(name, probe) if started?
|
147
|
+
end
|
148
|
+
|
149
|
+
# Unregister a probe that's registered with {register}.
|
150
|
+
# Can also be used to unregister automatically registered probes by the
|
151
|
+
# gem.
|
152
|
+
#
|
153
|
+
# @example Unregister probes
|
154
|
+
# # First register a probe
|
155
|
+
# Appsignal::Probes.register :my_probe, lambda {}
|
156
|
+
#
|
157
|
+
# # Then unregister a probe if needed
|
158
|
+
# Appsignal::Probes.unregister :my_probe
|
159
|
+
#
|
160
|
+
# @param name [Symbol/String] Name of the probe used to {register} the
|
161
|
+
# probe.
|
162
|
+
# @return [void]
|
163
|
+
def unregister(name)
|
164
|
+
probes.unregister(name)
|
165
|
+
|
166
|
+
uninitialize_probe(name)
|
167
|
+
end
|
168
|
+
|
169
|
+
# @api private
|
170
|
+
def start
|
171
|
+
stop
|
172
|
+
@started = true
|
173
|
+
@thread = Thread.new do
|
174
|
+
# Advise multi-threaded app servers to ignore this thread
|
175
|
+
# for the purposes of fork safety warnings
|
176
|
+
if Thread.current.respond_to?(:thread_variable_set)
|
177
|
+
Thread.current.thread_variable_set(:fork_safe, true)
|
178
|
+
end
|
179
|
+
|
180
|
+
sleep initial_wait_time
|
181
|
+
initialize_probes
|
182
|
+
loop do
|
183
|
+
logger = Appsignal.internal_logger
|
184
|
+
mutex.synchronize do
|
185
|
+
logger.debug("Gathering minutely metrics with #{probe_instances.count} probes")
|
186
|
+
probe_instances.each do |name, probe|
|
187
|
+
logger.debug("Gathering minutely metrics with '#{name}' probe")
|
188
|
+
probe.call
|
189
|
+
rescue => ex
|
190
|
+
logger.error "Error in minutely probe '#{name}': #{ex}"
|
191
|
+
logger.debug ex.backtrace.join("\n")
|
192
|
+
end
|
193
|
+
end
|
194
|
+
sleep wait_time
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
# Returns if the probes thread has been started. If the value is false or
|
200
|
+
# nil, it has not been started yet.
|
201
|
+
#
|
202
|
+
# @return [Boolean, nil]
|
203
|
+
def started?
|
204
|
+
@started
|
205
|
+
end
|
206
|
+
|
207
|
+
# Stop the minutely probes mechanism. Stop the thread and clear all probe
|
208
|
+
# instances.
|
209
|
+
def stop
|
210
|
+
defined?(@thread) && @thread.kill
|
211
|
+
@started = false
|
212
|
+
probe_instances.clear
|
213
|
+
end
|
214
|
+
|
215
|
+
# @api private
|
216
|
+
def wait_time
|
217
|
+
60 - Time.now.sec
|
218
|
+
end
|
219
|
+
|
220
|
+
private
|
221
|
+
|
222
|
+
def initial_wait_time
|
223
|
+
remaining_seconds = 60 - Time.now.sec
|
224
|
+
return remaining_seconds if remaining_seconds > 30
|
225
|
+
|
226
|
+
remaining_seconds + 60
|
227
|
+
end
|
228
|
+
|
229
|
+
def initialize_probes
|
230
|
+
probes.each do |name, probe|
|
231
|
+
initialize_probe(name, probe)
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
def initialize_probe(name, probe)
|
236
|
+
if probe.respond_to? :new
|
237
|
+
instance = probe.new
|
238
|
+
klass = probe
|
239
|
+
else
|
240
|
+
instance = probe
|
241
|
+
klass = instance.class
|
242
|
+
end
|
243
|
+
unless dependencies_present?(klass)
|
244
|
+
Appsignal.internal_logger.debug "Skipping '#{name}' probe, " \
|
245
|
+
"#{klass}.dependency_present? returned falsy"
|
246
|
+
return
|
247
|
+
end
|
248
|
+
mutex.synchronize do
|
249
|
+
probe_instances[name] = instance
|
250
|
+
end
|
251
|
+
rescue => error
|
252
|
+
logger = Appsignal.internal_logger
|
253
|
+
logger.error "Error while initializing minutely probe '#{name}': #{error}"
|
254
|
+
logger.debug error.backtrace.join("\n")
|
255
|
+
end
|
256
|
+
|
257
|
+
def uninitialize_probe(name)
|
258
|
+
mutex.synchronize do
|
259
|
+
probe_instances.delete(name)
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
def dependencies_present?(probe)
|
264
|
+
return true unless probe.respond_to? :dependencies_present?
|
265
|
+
|
266
|
+
probe.dependencies_present?
|
267
|
+
end
|
268
|
+
|
269
|
+
def probe_instances
|
270
|
+
@probe_instances ||= {}
|
271
|
+
end
|
272
|
+
end
|
5
273
|
end
|
6
274
|
end
|
7
275
|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Appsignal
|
4
|
+
module Utils
|
5
|
+
# @api private
|
6
|
+
module StdoutAndLoggerMessage
|
7
|
+
def self.warning(message, logger = Appsignal.internal_logger)
|
8
|
+
Kernel.warn "appsignal WARNING: #{message}"
|
9
|
+
logger.warn message
|
10
|
+
end
|
11
|
+
|
12
|
+
def stdout_and_logger_warning(message, logger = Appsignal.internal_logger)
|
13
|
+
Appsignal::Utils::StdoutAndLoggerMessage.warning(message, logger)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/appsignal/utils.rb
CHANGED
data/lib/appsignal/version.rb
CHANGED