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/spec/lib/appsignal_spec.rb
CHANGED
@@ -87,7 +87,7 @@ describe Appsignal do
|
|
87
87
|
end
|
88
88
|
|
89
89
|
it "should start minutely" do
|
90
|
-
expect(Appsignal::
|
90
|
+
expect(Appsignal::Probes).to receive(:start)
|
91
91
|
Appsignal.start
|
92
92
|
end
|
93
93
|
end
|
@@ -98,7 +98,7 @@ describe Appsignal do
|
|
98
98
|
end
|
99
99
|
|
100
100
|
it "should not start minutely" do
|
101
|
-
expect(Appsignal::
|
101
|
+
expect(Appsignal::Probes).to_not receive(:start)
|
102
102
|
Appsignal.start
|
103
103
|
end
|
104
104
|
end
|
@@ -151,13 +151,20 @@ describe Appsignal do
|
|
151
151
|
end
|
152
152
|
|
153
153
|
describe ".stop" do
|
154
|
-
it "
|
154
|
+
it "calls stop on the extension" do
|
155
155
|
expect(Appsignal.internal_logger).to receive(:debug).with("Stopping appsignal")
|
156
156
|
expect(Appsignal::Extension).to receive(:stop)
|
157
157
|
Appsignal.stop
|
158
158
|
expect(Appsignal.active?).to be_falsy
|
159
159
|
end
|
160
160
|
|
161
|
+
it "stops the minutely probes" do
|
162
|
+
Appsignal::Probes.start
|
163
|
+
expect(Appsignal::Probes.started?).to be_truthy
|
164
|
+
Appsignal.stop
|
165
|
+
expect(Appsignal::Probes.started?).to be_falsy
|
166
|
+
end
|
167
|
+
|
161
168
|
context "with context specified" do
|
162
169
|
it "should log the context" do
|
163
170
|
expect(Appsignal.internal_logger).to receive(:debug).with("Stopping appsignal (something)")
|
@@ -1121,7 +1128,14 @@ describe Appsignal do
|
|
1121
1128
|
let(:log_path) { File.join(tmp_dir, "log") }
|
1122
1129
|
let(:log_file) { File.join(log_path, "appsignal.log") }
|
1123
1130
|
|
1124
|
-
before
|
1131
|
+
before do
|
1132
|
+
FileUtils.mkdir_p(log_path)
|
1133
|
+
# Clear state from previous test
|
1134
|
+
Appsignal.internal_logger = nil
|
1135
|
+
if Appsignal.instance_variable_defined?(:@in_memory_log)
|
1136
|
+
Appsignal.remove_instance_variable(:@in_memory_log)
|
1137
|
+
end
|
1138
|
+
end
|
1125
1139
|
after { FileUtils.rm_rf(log_path) }
|
1126
1140
|
|
1127
1141
|
def initialize_config
|
@@ -1130,6 +1144,7 @@ describe Appsignal do
|
|
1130
1144
|
:log_path => log_path
|
1131
1145
|
)
|
1132
1146
|
Appsignal.internal_logger.error("Log in memory")
|
1147
|
+
expect(Appsignal.in_memory_log.string).to_not be_empty
|
1133
1148
|
end
|
1134
1149
|
|
1135
1150
|
context "when the log path is writable" do
|
@@ -1154,6 +1169,10 @@ describe Appsignal do
|
|
1154
1169
|
it "amends in memory log to log file" do
|
1155
1170
|
expect(log_file_contents).to include "[ERROR] appsignal: Log in memory"
|
1156
1171
|
end
|
1172
|
+
|
1173
|
+
it "clears the in memory log after writing to the new logger" do
|
1174
|
+
expect(Appsignal.in_memory_log.string).to be_empty
|
1175
|
+
end
|
1157
1176
|
end
|
1158
1177
|
|
1159
1178
|
context "when the log file is not writable" do
|
@@ -1178,8 +1197,11 @@ describe Appsignal do
|
|
1178
1197
|
expect(output).to include "[ERROR] appsignal: Log in memory"
|
1179
1198
|
end
|
1180
1199
|
|
1200
|
+
it "clears the in memory log after writing to the new logger" do
|
1201
|
+
expect(Appsignal.in_memory_log.string).to be_empty
|
1202
|
+
end
|
1203
|
+
|
1181
1204
|
it "outputs a warning" do
|
1182
|
-
puts output
|
1183
1205
|
expect(output).to include \
|
1184
1206
|
"[WARN] appsignal: Unable to start internal logger with log path '#{log_file}'.",
|
1185
1207
|
"[WARN] appsignal: Permission denied"
|
@@ -1237,6 +1259,10 @@ describe Appsignal do
|
|
1237
1259
|
it "amends in memory log to stdout" do
|
1238
1260
|
expect(output).to include "[ERROR] appsignal: Log in memory"
|
1239
1261
|
end
|
1262
|
+
|
1263
|
+
it "clears the in memory log after writing to the new logger" do
|
1264
|
+
expect(Appsignal.in_memory_log.string).to be_empty
|
1265
|
+
end
|
1240
1266
|
end
|
1241
1267
|
|
1242
1268
|
describe "#logger#level" do
|
@@ -32,10 +32,14 @@ RSpec.describe "Puma plugin" do
|
|
32
32
|
# StatsD server used for these tests.
|
33
33
|
# Open a UDPSocket and listen for messages sent by the AppSignal Puma plugin.
|
34
34
|
class StatsdServer
|
35
|
+
def initialize(statsd_port)
|
36
|
+
@statsd_port = statsd_port
|
37
|
+
end
|
38
|
+
|
35
39
|
def start
|
36
40
|
stop
|
37
41
|
@socket = UDPSocket.new
|
38
|
-
@socket.bind("127.0.0.1",
|
42
|
+
@socket.bind("127.0.0.1", @statsd_port)
|
39
43
|
|
40
44
|
loop do
|
41
45
|
# Listen for messages and track them on the messages Array.
|
@@ -115,13 +119,15 @@ RSpec.describe "Puma plugin" do
|
|
115
119
|
|
116
120
|
def run_plugin(stats_data, plugin, &block)
|
117
121
|
Puma._set_stats = stats_data
|
118
|
-
|
122
|
+
ENV["APPSIGNAL_STATSD_PORT"] = "8126"
|
123
|
+
@statsd = StatsdServer.new(ENV.fetch("APPSIGNAL_STATSD_PORT"))
|
119
124
|
@server_thread = Thread.new { @statsd.start }
|
120
125
|
@server_thread.abort_on_exception = true
|
121
126
|
@client_thread = Thread.new { start_plugin(plugin) }
|
122
127
|
@client_thread.abort_on_exception = true
|
123
128
|
wait_for(:puma_client_wait, &block)
|
124
129
|
ensure
|
130
|
+
ENV["APPSIGNAL_STATSD_PORT"] = nil
|
125
131
|
Puma._set_stats = nil
|
126
132
|
# Stop all threads in test and stop listening on the UDPSocket
|
127
133
|
@client_thread.kill if defined?(@client_thread) && @client_thread
|
data/spec/spec_helper.rb
CHANGED
@@ -171,11 +171,11 @@ RSpec.configure do |config|
|
|
171
171
|
def stop_minutely_probes
|
172
172
|
thread =
|
173
173
|
begin
|
174
|
-
Appsignal::
|
174
|
+
Appsignal::Probes.class_variable_get(:@@thread) # Fetch old thread
|
175
175
|
rescue NameError
|
176
176
|
nil
|
177
177
|
end
|
178
|
-
Appsignal::
|
178
|
+
Appsignal::Probes.stop
|
179
179
|
thread&.join # Wait for old thread to exit
|
180
180
|
end
|
181
181
|
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: 3.7.
|
4
|
+
version: 3.7.2
|
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-
|
13
|
+
date: 2024-05-06 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rack
|
@@ -277,7 +277,6 @@ files:
|
|
277
277
|
- lib/appsignal/integrations/webmachine.rb
|
278
278
|
- lib/appsignal/logger.rb
|
279
279
|
- lib/appsignal/marker.rb
|
280
|
-
- lib/appsignal/minutely.rb
|
281
280
|
- lib/appsignal/probes.rb
|
282
281
|
- lib/appsignal/probes/gvl.rb
|
283
282
|
- lib/appsignal/probes/helpers.rb
|
@@ -293,12 +292,12 @@ files:
|
|
293
292
|
- lib/appsignal/transmitter.rb
|
294
293
|
- lib/appsignal/utils.rb
|
295
294
|
- lib/appsignal/utils/data.rb
|
296
|
-
- lib/appsignal/utils/deprecation_message.rb
|
297
295
|
- lib/appsignal/utils/hash_sanitizer.rb
|
298
296
|
- lib/appsignal/utils/integration_logger.rb
|
299
297
|
- lib/appsignal/utils/json.rb
|
300
298
|
- lib/appsignal/utils/query_params_sanitizer.rb
|
301
299
|
- lib/appsignal/utils/rails_helper.rb
|
300
|
+
- lib/appsignal/utils/stdout_and_logger_message.rb
|
302
301
|
- lib/appsignal/version.rb
|
303
302
|
- lib/puma/plugin/appsignal.rb
|
304
303
|
- lib/sequel/extensions/appsignal_integration.rb
|
@@ -378,10 +377,10 @@ files:
|
|
378
377
|
- spec/lib/appsignal/integrations/webmachine_spec.rb
|
379
378
|
- spec/lib/appsignal/logger_spec.rb
|
380
379
|
- spec/lib/appsignal/marker_spec.rb
|
381
|
-
- spec/lib/appsignal/minutely_spec.rb
|
382
380
|
- spec/lib/appsignal/probes/gvl_spec.rb
|
383
381
|
- spec/lib/appsignal/probes/mri_spec.rb
|
384
382
|
- spec/lib/appsignal/probes/sidekiq_spec.rb
|
383
|
+
- spec/lib/appsignal/probes_spec.rb
|
385
384
|
- spec/lib/appsignal/rack/generic_instrumentation_spec.rb
|
386
385
|
- spec/lib/appsignal/rack/rails_instrumentation_spec.rb
|
387
386
|
- spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb
|
@@ -467,7 +466,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
467
466
|
- !ruby/object:Gem::Version
|
468
467
|
version: '0'
|
469
468
|
requirements: []
|
470
|
-
rubygems_version: 3.
|
469
|
+
rubygems_version: 3.5.9
|
471
470
|
signing_key:
|
472
471
|
specification_version: 4
|
473
472
|
summary: Logs performance and exception data from your app to appsignal.com
|
data/lib/appsignal/minutely.rb
DELETED
@@ -1,206 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Appsignal
|
4
|
-
class Minutely
|
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
|
-
# Register a new minutely probe.
|
29
|
-
#
|
30
|
-
# Supported probe types are:
|
31
|
-
#
|
32
|
-
# - Lambda - A lambda is an object that listens to a `call` method call.
|
33
|
-
# This `call` method is called every minute.
|
34
|
-
# - Class - A class object is an object that listens to a `new` and
|
35
|
-
# `call` method call. The `new` method is called when the Minutely
|
36
|
-
# probe thread is started to initialize all probes. This allows probes
|
37
|
-
# to load dependencies once beforehand. Their `call` method is called
|
38
|
-
# every minute.
|
39
|
-
# - Class instance - A class instance object is an object that listens to
|
40
|
-
# a `call` method call. The `call` method is called every minute.
|
41
|
-
#
|
42
|
-
# @example Register a new probe
|
43
|
-
# Appsignal::Minutely.probes.register :my_probe, lambda {}
|
44
|
-
#
|
45
|
-
# @example Overwrite an existing registered probe
|
46
|
-
# Appsignal::Minutely.probes.register :my_probe, lambda {}
|
47
|
-
# Appsignal::Minutely.probes.register :my_probe, lambda { puts "hello" }
|
48
|
-
#
|
49
|
-
# @example Add a lambda as a probe
|
50
|
-
# Appsignal::Minutely.probes.register :my_probe, lambda { puts "hello" }
|
51
|
-
# # "hello" # printed every minute
|
52
|
-
#
|
53
|
-
# @example Add a probe instance
|
54
|
-
# class MyProbe
|
55
|
-
# def initialize
|
56
|
-
# puts "started"
|
57
|
-
# end
|
58
|
-
#
|
59
|
-
# def call
|
60
|
-
# puts "called"
|
61
|
-
# end
|
62
|
-
# end
|
63
|
-
#
|
64
|
-
# Appsignal::Minutely.probes.register :my_probe, MyProbe.new
|
65
|
-
# # "started" # printed immediately
|
66
|
-
# # "called" # printed every minute
|
67
|
-
#
|
68
|
-
# @example Add a probe class
|
69
|
-
# class MyProbe
|
70
|
-
# def initialize
|
71
|
-
# # Add things that only need to be done on start up for this probe
|
72
|
-
# require "some/library/dependency"
|
73
|
-
# @cache = {} # initialize a local cache variable
|
74
|
-
# puts "started"
|
75
|
-
# end
|
76
|
-
#
|
77
|
-
# def call
|
78
|
-
# puts "called"
|
79
|
-
# end
|
80
|
-
# end
|
81
|
-
#
|
82
|
-
# Appsignal::Minutely.probes.register :my_probe, MyProbe
|
83
|
-
# Appsignal::Minutely.start # This is called for you
|
84
|
-
# # "started" # Printed on Appsignal::Minutely.start
|
85
|
-
# # "called" # Repeated every minute
|
86
|
-
#
|
87
|
-
# @param name [Symbol/String] Name of the probe. Can be used with {[]}.
|
88
|
-
# This name will be used in errors in the log and allows overwriting of
|
89
|
-
# probes by registering new ones with the same name.
|
90
|
-
# @param probe [Object] Any object that listens to the `call` method will
|
91
|
-
# be used as a probe.
|
92
|
-
# @return [void]
|
93
|
-
def register(name, probe)
|
94
|
-
if probes.key?(name)
|
95
|
-
logger.debug "A probe with the name `#{name}` is already " \
|
96
|
-
"registered. Overwriting the entry with the new probe."
|
97
|
-
end
|
98
|
-
probes[name] = probe
|
99
|
-
end
|
100
|
-
|
101
|
-
# @api private
|
102
|
-
def each(&block)
|
103
|
-
probes.each(&block)
|
104
|
-
end
|
105
|
-
|
106
|
-
private
|
107
|
-
|
108
|
-
attr_reader :probes
|
109
|
-
|
110
|
-
def logger
|
111
|
-
Appsignal.internal_logger
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
class << self
|
116
|
-
# @see ProbeCollection
|
117
|
-
# @return [ProbeCollection] Returns list of probes.
|
118
|
-
def probes
|
119
|
-
@probes ||= ProbeCollection.new
|
120
|
-
end
|
121
|
-
|
122
|
-
# @api private
|
123
|
-
def start
|
124
|
-
stop
|
125
|
-
@thread = Thread.new do
|
126
|
-
# Advise multi-threaded app servers to ignore this thread
|
127
|
-
# for the purposes of fork safety warnings
|
128
|
-
if Thread.current.respond_to?(:thread_variable_set)
|
129
|
-
Thread.current.thread_variable_set(:fork_safe, true)
|
130
|
-
end
|
131
|
-
|
132
|
-
sleep initial_wait_time
|
133
|
-
initialize_probes
|
134
|
-
loop do
|
135
|
-
logger = Appsignal.internal_logger
|
136
|
-
logger.debug("Gathering minutely metrics with #{probe_instances.count} probes")
|
137
|
-
probe_instances.each do |name, probe|
|
138
|
-
logger.debug("Gathering minutely metrics with '#{name}' probe")
|
139
|
-
probe.call
|
140
|
-
rescue => ex
|
141
|
-
logger.error "Error in minutely probe '#{name}': #{ex}"
|
142
|
-
logger.debug ex.backtrace.join("\n")
|
143
|
-
end
|
144
|
-
sleep wait_time
|
145
|
-
end
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
# @api private
|
150
|
-
def stop
|
151
|
-
defined?(@thread) && @thread.kill
|
152
|
-
probe_instances.clear
|
153
|
-
end
|
154
|
-
|
155
|
-
# @api private
|
156
|
-
def wait_time
|
157
|
-
60 - Time.now.sec
|
158
|
-
end
|
159
|
-
|
160
|
-
private
|
161
|
-
|
162
|
-
def initial_wait_time
|
163
|
-
remaining_seconds = 60 - Time.now.sec
|
164
|
-
return remaining_seconds if remaining_seconds > 30
|
165
|
-
|
166
|
-
remaining_seconds + 60
|
167
|
-
end
|
168
|
-
|
169
|
-
def initialize_probes
|
170
|
-
probes.each do |name, probe|
|
171
|
-
initialize_probe(name, probe)
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
def initialize_probe(name, probe)
|
176
|
-
if probe.respond_to? :new
|
177
|
-
instance = probe.new
|
178
|
-
klass = probe
|
179
|
-
else
|
180
|
-
instance = probe
|
181
|
-
klass = instance.class
|
182
|
-
end
|
183
|
-
unless dependencies_present?(klass)
|
184
|
-
Appsignal.internal_logger.debug "Skipping '#{name}' probe, " \
|
185
|
-
"#{klass}.dependency_present? returned falsy"
|
186
|
-
return
|
187
|
-
end
|
188
|
-
probe_instances[name] = instance
|
189
|
-
rescue => error
|
190
|
-
logger = Appsignal.internal_logger
|
191
|
-
logger.error "Error while initializing minutely probe '#{name}': #{error}"
|
192
|
-
logger.debug error.backtrace.join("\n")
|
193
|
-
end
|
194
|
-
|
195
|
-
def dependencies_present?(probe)
|
196
|
-
return true unless probe.respond_to? :dependencies_present?
|
197
|
-
|
198
|
-
probe.dependencies_present?
|
199
|
-
end
|
200
|
-
|
201
|
-
def probe_instances
|
202
|
-
@probe_instances ||= {}
|
203
|
-
end
|
204
|
-
end
|
205
|
-
end
|
206
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Appsignal
|
4
|
-
module Utils
|
5
|
-
module DeprecationMessage
|
6
|
-
def self.message(message, logger = Appsignal.internal_logger)
|
7
|
-
Kernel.warn "appsignal WARNING: #{message}"
|
8
|
-
logger.warn message
|
9
|
-
end
|
10
|
-
|
11
|
-
def deprecation_message(message, logger = Appsignal.internal_logger)
|
12
|
-
Appsignal::Utils::DeprecationMessage.message(message, logger)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|