appsignal 4.0.5 → 4.0.7
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 +20 -0
- data/Rakefile +9 -9
- data/appsignal.gemspec +22 -1
- data/build_matrix.yml +2 -1
- data/ext/agent.rb +27 -27
- data/lib/appsignal/check_in/scheduler.rb +3 -4
- data/lib/appsignal/check_in.rb +1 -1
- data/lib/appsignal/config.rb +1 -3
- data/lib/appsignal/integrations/que.rb +8 -2
- data/lib/appsignal/integrations/resque.rb +1 -6
- data/lib/appsignal/utils/hash_sanitizer.rb +4 -0
- data/lib/appsignal/version.rb +1 -1
- metadata +2 -191
- data/.github/ISSUE_TEMPLATE/bug_report.md +0 -31
- data/.github/ISSUE_TEMPLATE/chore.md +0 -14
- data/.github/workflows/ci.yml +0 -3150
- data/.github/workflows/create_release_from_tag.yml +0 -62
- data/.gitignore +0 -35
- data/.gitmodules +0 -3
- data/.rspec +0 -4
- data/.yardopts +0 -8
- data/benchmark.rake +0 -139
- data/gemfiles/capistrano2.gemfile +0 -6
- data/gemfiles/capistrano3.gemfile +0 -7
- data/gemfiles/dry-monitor.gemfile +0 -5
- data/gemfiles/grape.gemfile +0 -5
- data/gemfiles/hanami-2.0.gemfile +0 -7
- data/gemfiles/hanami-2.1.gemfile +0 -7
- data/gemfiles/http5.gemfile +0 -5
- data/gemfiles/no_dependencies.gemfile +0 -10
- data/gemfiles/padrino.gemfile +0 -7
- data/gemfiles/psych-3.gemfile +0 -5
- data/gemfiles/psych-4.gemfile +0 -5
- data/gemfiles/que.gemfile +0 -5
- data/gemfiles/rails-6.0.gemfile +0 -10
- data/gemfiles/rails-6.1.gemfile +0 -11
- data/gemfiles/rails-7.0.gemfile +0 -11
- data/gemfiles/rails-7.1.gemfile +0 -11
- data/gemfiles/rails-7.2.gemfile +0 -11
- data/gemfiles/redis-4.gemfile +0 -5
- data/gemfiles/redis-5.gemfile +0 -6
- data/gemfiles/resque-2.gemfile +0 -6
- data/gemfiles/sequel.gemfile +0 -10
- data/gemfiles/sinatra.gemfile +0 -5
- data/gemfiles/webmachine1.gemfile +0 -7
- data/gemfiles/webmachine2.gemfile +0 -6
- data/mono.yml +0 -16
- data/spec/.rubocop.yml +0 -7
- data/spec/lib/appsignal/auth_check_spec.rb +0 -84
- data/spec/lib/appsignal/capistrano2_spec.rb +0 -227
- data/spec/lib/appsignal/capistrano3_spec.rb +0 -284
- data/spec/lib/appsignal/check_in/cron_spec.rb +0 -202
- data/spec/lib/appsignal/check_in/scheduler_spec.rb +0 -443
- data/spec/lib/appsignal/cli/demo_spec.rb +0 -46
- data/spec/lib/appsignal/cli/diagnose/paths_spec.rb +0 -16
- data/spec/lib/appsignal/cli/diagnose/utils_spec.rb +0 -86
- data/spec/lib/appsignal/cli/diagnose_spec.rb +0 -1553
- data/spec/lib/appsignal/cli/helpers_spec.rb +0 -179
- data/spec/lib/appsignal/cli/install_spec.rb +0 -848
- data/spec/lib/appsignal/cli_spec.rb +0 -56
- data/spec/lib/appsignal/config_spec.rb +0 -1380
- data/spec/lib/appsignal/demo_spec.rb +0 -83
- data/spec/lib/appsignal/environment_spec.rb +0 -190
- data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +0 -60
- data/spec/lib/appsignal/event_formatter/active_record/instantiation_formatter_spec.rb +0 -21
- data/spec/lib/appsignal/event_formatter/active_record/sql_formatter_spec.rb +0 -21
- data/spec/lib/appsignal/event_formatter/elastic_search/search_formatter_spec.rb +0 -52
- data/spec/lib/appsignal/event_formatter/faraday/request_formatter_spec.rb +0 -21
- data/spec/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter_spec.rb +0 -84
- data/spec/lib/appsignal/event_formatter/rom/sql_formatter_spec.rb +0 -22
- data/spec/lib/appsignal/event_formatter/sequel/sql_formatter_spec.rb +0 -30
- data/spec/lib/appsignal/event_formatter/view_component/render_formatter_spec.rb +0 -41
- data/spec/lib/appsignal/event_formatter_spec.rb +0 -193
- data/spec/lib/appsignal/extension/jruby_spec.rb +0 -46
- data/spec/lib/appsignal/extension_install_failure_spec.rb +0 -20
- data/spec/lib/appsignal/extension_spec.rb +0 -178
- data/spec/lib/appsignal/garbage_collection_spec.rb +0 -98
- data/spec/lib/appsignal/hooks/action_cable_spec.rb +0 -345
- data/spec/lib/appsignal/hooks/action_mailer_spec.rb +0 -55
- data/spec/lib/appsignal/hooks/active_support_notifications/finish_with_state_shared_examples.rb +0 -23
- data/spec/lib/appsignal/hooks/active_support_notifications/instrument_shared_examples.rb +0 -99
- data/spec/lib/appsignal/hooks/active_support_notifications/start_finish_shared_examples.rb +0 -47
- data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +0 -47
- data/spec/lib/appsignal/hooks/activejob_spec.rb +0 -650
- data/spec/lib/appsignal/hooks/at_exit_spec.rb +0 -105
- data/spec/lib/appsignal/hooks/celluloid_spec.rb +0 -40
- data/spec/lib/appsignal/hooks/data_mapper_spec.rb +0 -40
- data/spec/lib/appsignal/hooks/delayed_job_spec.rb +0 -38
- data/spec/lib/appsignal/hooks/dry_monitor_spec.rb +0 -83
- data/spec/lib/appsignal/hooks/excon_spec.rb +0 -67
- data/spec/lib/appsignal/hooks/gvl_spec.rb +0 -145
- data/spec/lib/appsignal/hooks/http_spec.rb +0 -37
- data/spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb +0 -46
- data/spec/lib/appsignal/hooks/mri_spec.rb +0 -23
- data/spec/lib/appsignal/hooks/net_http_spec.rb +0 -18
- data/spec/lib/appsignal/hooks/passenger_spec.rb +0 -30
- data/spec/lib/appsignal/hooks/puma_spec.rb +0 -80
- data/spec/lib/appsignal/hooks/que_spec.rb +0 -19
- data/spec/lib/appsignal/hooks/rake_spec.rb +0 -144
- data/spec/lib/appsignal/hooks/redis_client_spec.rb +0 -218
- data/spec/lib/appsignal/hooks/redis_spec.rb +0 -124
- data/spec/lib/appsignal/hooks/resque_spec.rb +0 -27
- data/spec/lib/appsignal/hooks/sequel_spec.rb +0 -44
- data/spec/lib/appsignal/hooks/shoryuken_spec.rb +0 -29
- data/spec/lib/appsignal/hooks/sidekiq_spec.rb +0 -115
- data/spec/lib/appsignal/hooks/unicorn_spec.rb +0 -63
- data/spec/lib/appsignal/hooks/webmachine_spec.rb +0 -24
- data/spec/lib/appsignal/hooks_spec.rb +0 -124
- data/spec/lib/appsignal/integrations/data_mapper_spec.rb +0 -74
- data/spec/lib/appsignal/integrations/delayed_job_plugin_spec.rb +0 -454
- data/spec/lib/appsignal/integrations/http_spec.rb +0 -111
- data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +0 -154
- data/spec/lib/appsignal/integrations/net_http_spec.rb +0 -33
- data/spec/lib/appsignal/integrations/object_spec.rb +0 -347
- data/spec/lib/appsignal/integrations/puma_spec.rb +0 -150
- data/spec/lib/appsignal/integrations/que_spec.rb +0 -152
- data/spec/lib/appsignal/integrations/railtie_spec.rb +0 -457
- data/spec/lib/appsignal/integrations/resque_spec.rb +0 -155
- data/spec/lib/appsignal/integrations/shoryuken_spec.rb +0 -165
- data/spec/lib/appsignal/integrations/sidekiq_spec.rb +0 -640
- data/spec/lib/appsignal/integrations/webmachine_spec.rb +0 -136
- data/spec/lib/appsignal/loaders/grape_spec.rb +0 -12
- data/spec/lib/appsignal/loaders/hanami_spec.rb +0 -92
- data/spec/lib/appsignal/loaders/padrino_spec.rb +0 -273
- data/spec/lib/appsignal/loaders/sinatra_spec.rb +0 -44
- data/spec/lib/appsignal/loaders_spec.rb +0 -144
- data/spec/lib/appsignal/logger_spec.rb +0 -205
- data/spec/lib/appsignal/marker_spec.rb +0 -51
- data/spec/lib/appsignal/probes/gvl_spec.rb +0 -164
- data/spec/lib/appsignal/probes/mri_spec.rb +0 -162
- data/spec/lib/appsignal/probes/sidekiq_spec.rb +0 -333
- data/spec/lib/appsignal/probes_spec.rb +0 -411
- data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +0 -370
- data/spec/lib/appsignal/rack/body_wrapper_spec.rb +0 -319
- data/spec/lib/appsignal/rack/event_handler_spec.rb +0 -441
- data/spec/lib/appsignal/rack/grape_middleware_spec.rb +0 -201
- data/spec/lib/appsignal/rack/hanami_middleware_spec.rb +0 -36
- data/spec/lib/appsignal/rack/instrumentation_middleware_spec.rb +0 -38
- data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +0 -126
- data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +0 -217
- data/spec/lib/appsignal/rack_spec.rb +0 -243
- data/spec/lib/appsignal/sample_data_spec.rb +0 -238
- data/spec/lib/appsignal/span_spec.rb +0 -141
- data/spec/lib/appsignal/system_spec.rb +0 -126
- data/spec/lib/appsignal/transaction_spec.rb +0 -2111
- data/spec/lib/appsignal/transmitter_spec.rb +0 -198
- data/spec/lib/appsignal/utils/data_spec.rb +0 -166
- data/spec/lib/appsignal/utils/hash_sanitizer_spec.rb +0 -182
- data/spec/lib/appsignal/utils/integration_logger_spec.rb +0 -21
- data/spec/lib/appsignal/utils/integration_memory_logger_spec.rb +0 -153
- data/spec/lib/appsignal/utils/json_spec.rb +0 -44
- data/spec/lib/appsignal/utils/query_params_sanitizer_spec.rb +0 -192
- data/spec/lib/appsignal_spec.rb +0 -1919
- data/spec/lib/puma/appsignal_spec.rb +0 -334
- data/spec/spec_helper.rb +0 -173
- data/spec/support/fixtures/generated_config.yml +0 -24
- data/spec/support/fixtures/projects/broken/config/appsignal.yml +0 -1
- data/spec/support/fixtures/projects/valid/config/appsignal.yml +0 -57
- data/spec/support/fixtures/projects/valid/log/.gitkeep +0 -0
- data/spec/support/fixtures/projects/valid_with_rails_app/config/application.rb +0 -16
- data/spec/support/fixtures/projects/valid_with_rails_app/config/appsignal.yml +0 -56
- data/spec/support/fixtures/projects/valid_with_rails_app/config/environment.rb +0 -10
- data/spec/support/fixtures/projects/valid_with_rails_app/log/.gitkeep +0 -0
- data/spec/support/fixtures/uploaded_file.txt +0 -0
- data/spec/support/hanami/hanami_app.rb +0 -29
- data/spec/support/helpers/action_mailer_helpers.rb +0 -25
- data/spec/support/helpers/activejob_helpers.rb +0 -27
- data/spec/support/helpers/api_request_helper.rb +0 -20
- data/spec/support/helpers/cli_helpers.rb +0 -40
- data/spec/support/helpers/config_helpers.rb +0 -66
- data/spec/support/helpers/dependency_helper.rb +0 -150
- data/spec/support/helpers/directory_helper.rb +0 -27
- data/spec/support/helpers/env_helpers.rb +0 -41
- data/spec/support/helpers/environment_metdata_helper.rb +0 -16
- data/spec/support/helpers/example_exception.rb +0 -13
- data/spec/support/helpers/example_standard_error.rb +0 -13
- data/spec/support/helpers/loader_helper.rb +0 -21
- data/spec/support/helpers/log_helpers.rb +0 -36
- data/spec/support/helpers/rails_helper.rb +0 -28
- data/spec/support/helpers/std_streams_helper.rb +0 -94
- data/spec/support/helpers/system_helpers.rb +0 -8
- data/spec/support/helpers/take_at_most_helper.rb +0 -21
- data/spec/support/helpers/time_helpers.rb +0 -11
- data/spec/support/helpers/transaction_helpers.rb +0 -122
- data/spec/support/helpers/wait_for_helper.rb +0 -39
- data/spec/support/matchers/contains_log.rb +0 -26
- data/spec/support/matchers/have_colorized_text.rb +0 -28
- data/spec/support/matchers/transaction.rb +0 -200
- data/spec/support/mocks/appsignal_mock.rb +0 -18
- data/spec/support/mocks/dummy_app.rb +0 -20
- data/spec/support/mocks/fake_gc_profiler.rb +0 -19
- data/spec/support/mocks/fake_gvl_tools.rb +0 -28
- data/spec/support/mocks/hash_like.rb +0 -10
- data/spec/support/mocks/mock_probe.rb +0 -13
- data/spec/support/mocks/puma_mock.rb +0 -43
- data/spec/support/shared_examples/instrument.rb +0 -48
- data/spec/support/stubs/appsignal/loaders/loader_stub.rb +0 -7
- data/spec/support/stubs/delayed_job.rb +0 -0
- data/spec/support/stubs/sidekiq/api.rb +0 -4
- data/spec/support/testing.rb +0 -194
- data/support/bundler_wrapper +0 -12
- data/support/install_deps +0 -33
@@ -1,205 +0,0 @@
|
|
1
|
-
describe Appsignal::Logger do
|
2
|
-
let(:log_stream) { StringIO.new }
|
3
|
-
let(:logs) { log_contents(log_stream) }
|
4
|
-
let(:logger) { Appsignal::Logger.new("group", :level => ::Logger::DEBUG) }
|
5
|
-
|
6
|
-
before do
|
7
|
-
Appsignal.internal_logger = test_logger(log_stream)
|
8
|
-
end
|
9
|
-
|
10
|
-
it "should not create a logger with a nil group" do
|
11
|
-
expect do
|
12
|
-
Appsignal::Logger.new(nil)
|
13
|
-
end.to raise_error(TypeError)
|
14
|
-
end
|
15
|
-
|
16
|
-
describe "#add" do
|
17
|
-
it "should log with a level and message" do
|
18
|
-
expect(Appsignal::Extension).to receive(:log)
|
19
|
-
.with("group", 3, 0, "Log message", instance_of(Appsignal::Extension::Data))
|
20
|
-
logger.add(::Logger::INFO, "Log message")
|
21
|
-
end
|
22
|
-
|
23
|
-
it "does not log a message that's not a String" do
|
24
|
-
expect(Appsignal::Extension).to_not receive(:log)
|
25
|
-
logger.add(::Logger::INFO, 123)
|
26
|
-
logger.add(::Logger::INFO, {})
|
27
|
-
logger.add(::Logger::INFO, [])
|
28
|
-
expect(logs)
|
29
|
-
.to contains_log(:warn, "Logger message was ignored, because it was not a String: 123")
|
30
|
-
expect(logs)
|
31
|
-
.to contains_log(:warn, "Logger message was ignored, because it was not a String: []")
|
32
|
-
expect(logs)
|
33
|
-
.to contains_log(:warn, "Logger message was ignored, because it was not a String: {}")
|
34
|
-
end
|
35
|
-
|
36
|
-
it "should log with a block" do
|
37
|
-
expect(Appsignal::Extension).to receive(:log)
|
38
|
-
.with("group", 3, 0, "Log message", instance_of(Appsignal::Extension::Data))
|
39
|
-
logger.add(::Logger::INFO) do
|
40
|
-
"Log message"
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
it "should log with a level, message and group" do
|
45
|
-
expect(Appsignal::Extension).to receive(:log)
|
46
|
-
.with("other_group", 3, 0, "Log message", instance_of(Appsignal::Extension::Data))
|
47
|
-
logger.add(::Logger::INFO, "Log message", "other_group")
|
48
|
-
end
|
49
|
-
|
50
|
-
it "should log when using `group` for the log message" do
|
51
|
-
expect(Appsignal::Extension).to receive(:log)
|
52
|
-
.with("group", 3, 0, "Log message", instance_of(Appsignal::Extension::Data))
|
53
|
-
logger.add(::Logger::INFO, nil, "Log message")
|
54
|
-
end
|
55
|
-
|
56
|
-
context "with info log level" do
|
57
|
-
let(:logger) { Appsignal::Logger.new("group", :level => ::Logger::INFO) }
|
58
|
-
|
59
|
-
it "should skip logging if the level is too low" do
|
60
|
-
expect(Appsignal::Extension).not_to receive(:log)
|
61
|
-
logger.add(::Logger::DEBUG, "Log message")
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
context "with a format set" do
|
66
|
-
let(:logger) { Appsignal::Logger.new("group", :format => Appsignal::Logger::LOGFMT) }
|
67
|
-
|
68
|
-
it "should log and pass the format flag" do
|
69
|
-
expect(Appsignal::Extension).to receive(:log)
|
70
|
-
.with("group", 3, 1, "Log message", instance_of(Appsignal::Extension::Data))
|
71
|
-
logger.add(::Logger::INFO, "Log message")
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
context "with a formatter set" do
|
76
|
-
before do
|
77
|
-
logger.formatter = proc do |_level, _timestamp, _appname, message|
|
78
|
-
"formatted: '#{message}'"
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
it "should log with a level, message and group" do
|
83
|
-
expect(Appsignal::Extension).to receive(:log).with(
|
84
|
-
"other_group",
|
85
|
-
3,
|
86
|
-
0,
|
87
|
-
"formatted: 'Log message'",
|
88
|
-
instance_of(Appsignal::Extension::Data)
|
89
|
-
)
|
90
|
-
logger.add(::Logger::INFO, "Log message", "other_group")
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
describe "#silence" do
|
96
|
-
it "calls the given block" do
|
97
|
-
num = 1
|
98
|
-
|
99
|
-
logger.silence do
|
100
|
-
num += 1
|
101
|
-
end
|
102
|
-
|
103
|
-
expect(num).to eq(2)
|
104
|
-
expect(Appsignal::Extension).not_to receive(:log)
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
[
|
109
|
-
["debug", 2, ::Logger::INFO],
|
110
|
-
["info", 3, ::Logger::WARN],
|
111
|
-
["warn", 5, ::Logger::ERROR],
|
112
|
-
["error", 6, ::Logger::FATAL],
|
113
|
-
["fatal", 7, nil]
|
114
|
-
].each do |method|
|
115
|
-
describe "##{method[0]}" do
|
116
|
-
it "should log with a message" do
|
117
|
-
expect(Appsignal::Utils::Data).to receive(:generate)
|
118
|
-
.with({ :attribute => "value" })
|
119
|
-
.and_call_original
|
120
|
-
expect(Appsignal::Extension).to receive(:log)
|
121
|
-
.with("group", method[1], 0, "Log message", instance_of(Appsignal::Extension::Data))
|
122
|
-
|
123
|
-
logger.send(method[0], "Log message", :attribute => "value")
|
124
|
-
end
|
125
|
-
|
126
|
-
it "should log with a block" do
|
127
|
-
expect(Appsignal::Utils::Data).to receive(:generate)
|
128
|
-
.with({})
|
129
|
-
.and_call_original
|
130
|
-
expect(Appsignal::Extension).to receive(:log)
|
131
|
-
.with("group", method[1], 0, "Log message", instance_of(Appsignal::Extension::Data))
|
132
|
-
|
133
|
-
logger.send(method[0]) do
|
134
|
-
"Log message"
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
it "should return with a nil message" do
|
139
|
-
expect(Appsignal::Extension).not_to receive(:log)
|
140
|
-
logger.send(method[0])
|
141
|
-
end
|
142
|
-
|
143
|
-
if method[2]
|
144
|
-
context "with a lower log level" do
|
145
|
-
let(:logger) { Appsignal::Logger.new("group", :level => method[2]) }
|
146
|
-
|
147
|
-
it "should skip logging if the level is too low" do
|
148
|
-
expect(Appsignal::Extension).not_to receive(:log)
|
149
|
-
logger.send(method[0], "Log message")
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
context "with a formatter set" do
|
155
|
-
before do
|
156
|
-
Timecop.freeze(Time.local(2023))
|
157
|
-
logger.formatter = logger.formatter = proc do |_level, timestamp, _appname, message|
|
158
|
-
# This line replicates the behaviour of the Ruby default Logger::Formatter
|
159
|
-
# which expects a timestamp object as a second argument
|
160
|
-
# https://github.com/ruby/ruby/blob/master/lib/logger/formatter.rb#L15-L17
|
161
|
-
time = timestamp.strftime("%Y-%m-%dT%H:%M:%S.%6N")
|
162
|
-
"formatted: #{time} '#{message}'"
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
after do
|
167
|
-
Timecop.return
|
168
|
-
end
|
169
|
-
|
170
|
-
it "should log with a level, message and group" do
|
171
|
-
expect(Appsignal::Extension).to receive(:log)
|
172
|
-
.with(
|
173
|
-
"group",
|
174
|
-
method[1],
|
175
|
-
0,
|
176
|
-
"formatted: 2023-01-01T00:00:00.000000 'Log message'",
|
177
|
-
instance_of(Appsignal::Extension::Data)
|
178
|
-
)
|
179
|
-
logger.send(method[0], "Log message")
|
180
|
-
end
|
181
|
-
end
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
describe "#error with exception object" do
|
186
|
-
it "logs the exception class and its message" do
|
187
|
-
error =
|
188
|
-
begin
|
189
|
-
raise ExampleStandardError, "oh no!"
|
190
|
-
rescue => e
|
191
|
-
# This makes the exception include a backtrace, so we can assert it's NOT included
|
192
|
-
e
|
193
|
-
end
|
194
|
-
expect(Appsignal::Extension).to receive(:log)
|
195
|
-
.with(
|
196
|
-
"group",
|
197
|
-
6,
|
198
|
-
0,
|
199
|
-
"ExampleStandardError: oh no!",
|
200
|
-
instance_of(Appsignal::Extension::Data)
|
201
|
-
)
|
202
|
-
logger.error(error)
|
203
|
-
end
|
204
|
-
end
|
205
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
describe Appsignal::Marker do
|
2
|
-
let(:config) { build_config }
|
3
|
-
let(:marker) do
|
4
|
-
described_class.new(
|
5
|
-
{
|
6
|
-
:revision => "503ce0923ed177a3ce000005",
|
7
|
-
:repository => "main",
|
8
|
-
:user => "batman",
|
9
|
-
:rails_env => "production"
|
10
|
-
},
|
11
|
-
config
|
12
|
-
)
|
13
|
-
end
|
14
|
-
let(:out_stream) { std_stream }
|
15
|
-
let(:output) { out_stream.read }
|
16
|
-
|
17
|
-
describe "#transmit" do
|
18
|
-
def stub_marker_request
|
19
|
-
stub_api_request config, "markers", marker.marker_data
|
20
|
-
end
|
21
|
-
|
22
|
-
def run
|
23
|
-
capture_stdout(out_stream) { marker.transmit }
|
24
|
-
end
|
25
|
-
|
26
|
-
context "when request is valid" do
|
27
|
-
before { stub_marker_request.to_return(:status => 200) }
|
28
|
-
|
29
|
-
it "outputs success" do
|
30
|
-
run
|
31
|
-
expect(output).to include \
|
32
|
-
"Notifying AppSignal of deploy with: revision: 503ce0923ed177a3ce000005, user: batman",
|
33
|
-
"AppSignal has been notified of this deploy!"
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
context "when request is invalid" do
|
38
|
-
before { stub_marker_request.to_return(:status => 500) }
|
39
|
-
|
40
|
-
it "outputs failure" do
|
41
|
-
run
|
42
|
-
expect(output).to include \
|
43
|
-
"Notifying AppSignal of deploy with: revision: 503ce0923ed177a3ce000005, user: batman",
|
44
|
-
"Something went wrong while trying to notify AppSignal: 500 at " \
|
45
|
-
"#{config[:endpoint]}/1/markers"
|
46
|
-
expect(output).to_not include \
|
47
|
-
"AppSignal has been notified of this deploy!"
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
@@ -1,164 +0,0 @@
|
|
1
|
-
describe Appsignal::Probes::GvlProbe do
|
2
|
-
let(:appsignal_mock) { AppsignalMock.new(:hostname => hostname) }
|
3
|
-
let(:probe) { described_class.new(:appsignal => appsignal_mock, :gvl_tools => FakeGVLTools) }
|
4
|
-
|
5
|
-
let(:hostname) { "some-host" }
|
6
|
-
|
7
|
-
around do |example|
|
8
|
-
real_program_name = $PROGRAM_NAME
|
9
|
-
example.run
|
10
|
-
ensure
|
11
|
-
$PROGRAM_NAME = real_program_name
|
12
|
-
end
|
13
|
-
|
14
|
-
def gauges_for(metric)
|
15
|
-
gauges = appsignal_mock.gauges.select do |gauge|
|
16
|
-
gauge[0] == metric
|
17
|
-
end
|
18
|
-
|
19
|
-
gauges.map do |gauge|
|
20
|
-
gauge.drop(1)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
after { FakeGVLTools.reset }
|
25
|
-
|
26
|
-
it "gauges the global timer delta" do
|
27
|
-
FakeGVLTools::GlobalTimer.monotonic_time = 100_000_000
|
28
|
-
probe.call
|
29
|
-
|
30
|
-
expect(gauges_for("gvl_global_timer")).to be_empty
|
31
|
-
|
32
|
-
FakeGVLTools::GlobalTimer.monotonic_time = 300_000_000
|
33
|
-
probe.call
|
34
|
-
|
35
|
-
expect(gauges_for("gvl_global_timer")).to eq [
|
36
|
-
[200, {
|
37
|
-
:hostname => hostname,
|
38
|
-
:process_name => "rspec",
|
39
|
-
:process_id => Process.pid
|
40
|
-
}],
|
41
|
-
[200, { :hostname => hostname }]
|
42
|
-
]
|
43
|
-
end
|
44
|
-
|
45
|
-
context "when the delta is negative" do
|
46
|
-
it "does not gauge the global timer delta" do
|
47
|
-
FakeGVLTools::GlobalTimer.monotonic_time = 300_000_000
|
48
|
-
probe.call
|
49
|
-
|
50
|
-
expect(gauges_for("gvl_global_timer")).to be_empty
|
51
|
-
|
52
|
-
FakeGVLTools::GlobalTimer.monotonic_time = 0
|
53
|
-
probe.call
|
54
|
-
|
55
|
-
expect(gauges_for("gvl_global_timer")).to be_empty
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
context "when the delta is zero" do
|
60
|
-
it "does not gauge the global timer delta" do
|
61
|
-
FakeGVLTools::GlobalTimer.monotonic_time = 300_000_000
|
62
|
-
probe.call
|
63
|
-
|
64
|
-
expect(gauges_for("gvl_global_timer")).to be_empty
|
65
|
-
|
66
|
-
probe.call
|
67
|
-
|
68
|
-
expect(gauges_for("gvl_global_timer")).to be_empty
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
context "when the waiting threads count is enabled" do
|
73
|
-
before do
|
74
|
-
FakeGVLTools::WaitingThreads.enabled = true
|
75
|
-
end
|
76
|
-
|
77
|
-
it "gauges the waiting threads count" do
|
78
|
-
FakeGVLTools::WaitingThreads.count = 3
|
79
|
-
probe.call
|
80
|
-
|
81
|
-
expect(gauges_for("gvl_waiting_threads")).to eq [
|
82
|
-
[3, {
|
83
|
-
:hostname => hostname,
|
84
|
-
:process_name => "rspec",
|
85
|
-
:process_id => Process.pid
|
86
|
-
}],
|
87
|
-
[3, { :hostname => hostname }]
|
88
|
-
]
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
context "when the waiting threads count is disabled" do
|
93
|
-
before do
|
94
|
-
FakeGVLTools::WaitingThreads.enabled = false
|
95
|
-
end
|
96
|
-
|
97
|
-
it "does not gauge the waiting threads count" do
|
98
|
-
FakeGVLTools::WaitingThreads.count = 3
|
99
|
-
probe.call
|
100
|
-
|
101
|
-
expect(gauges_for("gvl_waiting_threads")).to be_empty
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
context "when the process name is a custom value" do
|
106
|
-
before do
|
107
|
-
FakeGVLTools::WaitingThreads.enabled = true
|
108
|
-
end
|
109
|
-
|
110
|
-
it "uses only the first word as the process name" do
|
111
|
-
$PROGRAM_NAME = "sidekiq 7.1.6 app [0 of 5 busy]"
|
112
|
-
probe.call
|
113
|
-
|
114
|
-
expect(gauges_for("gvl_waiting_threads")).to eq [
|
115
|
-
[0, {
|
116
|
-
:hostname => hostname,
|
117
|
-
:process_name => "sidekiq",
|
118
|
-
:process_id => Process.pid
|
119
|
-
}],
|
120
|
-
[0, { :hostname => hostname }]
|
121
|
-
]
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
context "when the process name is a path" do
|
126
|
-
before do
|
127
|
-
FakeGVLTools::WaitingThreads.enabled = true
|
128
|
-
end
|
129
|
-
|
130
|
-
it "uses only the binary name as the process name" do
|
131
|
-
$PROGRAM_NAME = "/foo/folder with spaces/bin/rails"
|
132
|
-
probe.call
|
133
|
-
|
134
|
-
expect(gauges_for("gvl_waiting_threads")).to eq [
|
135
|
-
[0, {
|
136
|
-
:hostname => hostname,
|
137
|
-
:process_name => "rails",
|
138
|
-
:process_id => Process.pid
|
139
|
-
}],
|
140
|
-
[0, { :hostname => hostname }]
|
141
|
-
]
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
context "when the process name is an empty string" do
|
146
|
-
before do
|
147
|
-
FakeGVLTools::WaitingThreads.enabled = true
|
148
|
-
end
|
149
|
-
|
150
|
-
it "uses [unknown process] as the process name" do
|
151
|
-
$PROGRAM_NAME = ""
|
152
|
-
probe.call
|
153
|
-
|
154
|
-
expect(gauges_for("gvl_waiting_threads")).to eq [
|
155
|
-
[0, {
|
156
|
-
:hostname => hostname,
|
157
|
-
:process_name => "[unknown process]",
|
158
|
-
:process_id => Process.pid
|
159
|
-
}],
|
160
|
-
[0, { :hostname => hostname }]
|
161
|
-
]
|
162
|
-
end
|
163
|
-
end
|
164
|
-
end
|
@@ -1,162 +0,0 @@
|
|
1
|
-
describe Appsignal::Probes::MriProbe do
|
2
|
-
let(:appsignal_mock) { AppsignalMock.new(:hostname => hostname) }
|
3
|
-
let(:gc_profiler_mock) { instance_double("Appsignal::GarbageCollectionProfiler") }
|
4
|
-
let(:probe) do
|
5
|
-
described_class.new(:appsignal => appsignal_mock, :gc_profiler => gc_profiler_mock)
|
6
|
-
end
|
7
|
-
|
8
|
-
describe ".dependencies_present?" do
|
9
|
-
if DependencyHelper.running_jruby?
|
10
|
-
it "should not be present" do
|
11
|
-
expect(described_class.dependencies_present?).to be_falsy
|
12
|
-
end
|
13
|
-
else
|
14
|
-
it "should be present" do
|
15
|
-
expect(described_class.dependencies_present?).to be_truthy
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
unless DependencyHelper.running_jruby?
|
21
|
-
describe "#call" do
|
22
|
-
let(:hostname) { nil }
|
23
|
-
before do
|
24
|
-
allow(gc_profiler_mock).to receive(:total_time)
|
25
|
-
allow(GC::Profiler).to receive(:enabled?).and_return(true)
|
26
|
-
end
|
27
|
-
|
28
|
-
it "should track vm cache metrics" do
|
29
|
-
probe.call
|
30
|
-
if DependencyHelper.ruby_3_2_or_newer?
|
31
|
-
expect_gauge_value("ruby_vm", :tags => { :metric => :constant_cache_invalidations })
|
32
|
-
expect_gauge_value("ruby_vm", :tags => { :metric => :constant_cache_misses })
|
33
|
-
else
|
34
|
-
expect_gauge_value("ruby_vm", :tags => { :metric => :class_serial })
|
35
|
-
expect_gauge_value("ruby_vm", :tags => { :metric => :global_constant_state })
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
it "tracks thread counts" do
|
40
|
-
probe.call
|
41
|
-
expect_gauge_value("thread_count")
|
42
|
-
end
|
43
|
-
|
44
|
-
it "tracks GC time between measurements" do
|
45
|
-
expect(gc_profiler_mock).to receive(:total_time).and_return(10, 15)
|
46
|
-
probe.call
|
47
|
-
probe.call
|
48
|
-
expect_gauge_value("gc_time", 5)
|
49
|
-
end
|
50
|
-
|
51
|
-
context "when GC total time overflows" do
|
52
|
-
it "skips one report" do
|
53
|
-
expect(gc_profiler_mock).to receive(:total_time).and_return(10, 15, 0, 10)
|
54
|
-
probe.call # Normal call, create a cache
|
55
|
-
probe.call # Report delta value based on cached value
|
56
|
-
probe.call # The value overflows and reports no value. Then stores 0 in the cache
|
57
|
-
probe.call # Report new value based on cache of 0
|
58
|
-
expect_gauges([["gc_time", 5], ["gc_time", 10]])
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
context "when GC profiling is disabled" do
|
63
|
-
it "does not report a gc_time metric" do
|
64
|
-
allow(GC::Profiler).to receive(:enabled?).and_return(false)
|
65
|
-
expect(gc_profiler_mock).to_not receive(:total_time)
|
66
|
-
probe.call # Normal call, create a cache
|
67
|
-
probe.call # Report delta value based on cached value
|
68
|
-
metrics = appsignal_mock.gauges.map { |(key)| key }
|
69
|
-
expect(metrics).to_not include("gc_time")
|
70
|
-
end
|
71
|
-
|
72
|
-
it "does not report a gc_time metric while temporarily disabled" do
|
73
|
-
# While enabled
|
74
|
-
allow(GC::Profiler).to receive(:enabled?).and_return(true)
|
75
|
-
expect(gc_profiler_mock).to receive(:total_time).and_return(10, 15)
|
76
|
-
probe.call # Normal call, create a cache
|
77
|
-
probe.call # Report delta value based on cached value
|
78
|
-
expect_gauges([["gc_time", 5]])
|
79
|
-
|
80
|
-
# While disabled
|
81
|
-
allow(GC::Profiler).to receive(:enabled?).and_return(false)
|
82
|
-
probe.call # Call twice to make sure any caches resets wouldn't mess up the assertion
|
83
|
-
probe.call
|
84
|
-
# Does not include any newly reported metrics
|
85
|
-
expect_gauges([["gc_time", 5]])
|
86
|
-
|
87
|
-
# When enabled after being disabled for a while, it only reports the
|
88
|
-
# newly reported time since it was renabled
|
89
|
-
allow(GC::Profiler).to receive(:enabled?).and_return(true)
|
90
|
-
expect(gc_profiler_mock).to receive(:total_time).and_return(25)
|
91
|
-
probe.call
|
92
|
-
expect_gauges([["gc_time", 5], ["gc_time", 10]])
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
it "tracks GC run count" do
|
97
|
-
expect(GC).to receive(:count).and_return(10, 15)
|
98
|
-
expect(GC).to receive(:stat).and_return(
|
99
|
-
{ :minor_gc_count => 10, :major_gc_count => 10 },
|
100
|
-
:minor_gc_count => 16, :major_gc_count => 17
|
101
|
-
)
|
102
|
-
probe.call
|
103
|
-
probe.call
|
104
|
-
expect_gauge_value("gc_count", 5, :tags => { :metric => :gc_count })
|
105
|
-
expect_gauge_value("gc_count", 6, :tags => { :metric => :minor_gc_count })
|
106
|
-
expect_gauge_value("gc_count", 7, :tags => { :metric => :major_gc_count })
|
107
|
-
end
|
108
|
-
|
109
|
-
it "tracks object allocation" do
|
110
|
-
expect(GC).to receive(:stat).and_return(
|
111
|
-
{ :total_allocated_objects => 10 },
|
112
|
-
:total_allocated_objects => 15
|
113
|
-
)
|
114
|
-
# Only tracks delta value so the needs to be called twice
|
115
|
-
probe.call
|
116
|
-
probe.call
|
117
|
-
expect_gauge_value("allocated_objects", 5)
|
118
|
-
end
|
119
|
-
|
120
|
-
it "tracks heap slots" do
|
121
|
-
probe.call
|
122
|
-
expect_gauge_value("heap_slots", :tags => { :metric => :heap_live })
|
123
|
-
expect_gauge_value("heap_slots", :tags => { :metric => :heap_free })
|
124
|
-
end
|
125
|
-
|
126
|
-
context "with custom hostname" do
|
127
|
-
let(:hostname) { "my hostname" }
|
128
|
-
|
129
|
-
it "reports custom hostname tag value" do
|
130
|
-
probe.call
|
131
|
-
expect_gauge_value("heap_slots",
|
132
|
-
:tags => { :metric => :heap_live, :hostname => hostname })
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
def expect_gauge_value(expected_key, expected_value = nil, tags: {})
|
139
|
-
expected_tags = { :hostname => Socket.gethostname }.merge(tags)
|
140
|
-
expect(appsignal_mock.gauges).to satisfy do |gauges|
|
141
|
-
gauges.any? do |distribution_value|
|
142
|
-
key, value, tags = distribution_value
|
143
|
-
next unless key == expected_key
|
144
|
-
next unless expected_value ? expected_value == value : !value.nil?
|
145
|
-
next unless tags == expected_tags
|
146
|
-
|
147
|
-
true
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
def expect_gauges(expected_metrics)
|
153
|
-
default_tags = { :hostname => Socket.gethostname }
|
154
|
-
keys = expected_metrics.map { |(key)| key }
|
155
|
-
metrics = expected_metrics.map do |metric|
|
156
|
-
key, value, tags = metric
|
157
|
-
[key, value, default_tags.merge(tags || {})]
|
158
|
-
end
|
159
|
-
found_gauges = appsignal_mock.gauges.select { |(key)| keys.include? key }
|
160
|
-
expect(found_gauges).to eq(metrics)
|
161
|
-
end
|
162
|
-
end
|