appsignal 3.0.3 → 3.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.semaphore/semaphore.yml +64 -199
  3. data/CHANGELOG.md +47 -19
  4. data/README.md +9 -3
  5. data/appsignal.gemspec +16 -3
  6. data/build_matrix.yml +16 -24
  7. data/ext/agent.yml +17 -17
  8. data/ext/base.rb +12 -1
  9. data/gemfiles/capistrano2.gemfile +0 -1
  10. data/gemfiles/capistrano3.gemfile +0 -1
  11. data/gemfiles/grape.gemfile +0 -1
  12. data/gemfiles/no_dependencies.gemfile +4 -1
  13. data/gemfiles/rails-3.2.gemfile +2 -0
  14. data/gemfiles/rails-4.2.gemfile +6 -0
  15. data/gemfiles/resque-2.gemfile +0 -4
  16. data/gemfiles/sequel-435.gemfile +0 -1
  17. data/gemfiles/sequel.gemfile +0 -1
  18. data/gemfiles/sinatra.gemfile +0 -1
  19. data/lib/appsignal/config.rb +1 -0
  20. data/lib/appsignal/hooks.rb +2 -1
  21. data/lib/appsignal/hooks/excon.rb +19 -0
  22. data/lib/appsignal/hooks/puma.rb +1 -16
  23. data/lib/appsignal/integrations/excon.rb +20 -0
  24. data/lib/appsignal/integrations/padrino.rb +1 -1
  25. data/lib/appsignal/integrations/railtie.rb +1 -1
  26. data/lib/appsignal/integrations/redis.rb +8 -5
  27. data/lib/appsignal/integrations/sinatra.rb +1 -1
  28. data/lib/appsignal/probes.rb +0 -1
  29. data/lib/appsignal/version.rb +1 -1
  30. data/lib/puma/plugin/appsignal.rb +146 -17
  31. data/mono.yml +16 -0
  32. data/spec/lib/appsignal/cli/diagnose_spec.rb +1 -0
  33. data/spec/lib/appsignal/hooks/excon_spec.rb +74 -0
  34. data/spec/lib/appsignal/hooks/puma_spec.rb +0 -46
  35. data/spec/lib/appsignal/hooks/redis_spec.rb +34 -10
  36. data/spec/lib/appsignal/hooks_spec.rb +4 -1
  37. data/spec/lib/puma/appsignal_spec.rb +244 -68
  38. data/support/install_deps +9 -8
  39. metadata +8 -6
  40. data/lib/appsignal/probes/puma.rb +0 -61
  41. data/spec/lib/appsignal/probes/puma_spec.rb +0 -180
data/support/install_deps CHANGED
@@ -2,25 +2,26 @@
2
2
 
3
3
  set -eu
4
4
 
5
- gem_args="--no-verbose"
6
- if [[ $(ruby --version) != "ruby 1.9.3"* ]]; then
7
- gem_args+=" --no-document"
8
- fi
5
+ gem_args="--no-verbose --no-document"
9
6
 
10
7
  case "${_RUBYGEMS_VERSION-"latest"}" in
11
8
  "latest")
12
- gem update $gem_args --system
9
+ echo "Updating rubygems"
10
+ retry --times 5 --sleep 5 gem update $gem_args --system
13
11
  ;;
14
12
  *)
15
- gem update $gem_args --system $_RUBYGEMS_VERSION
13
+ echo "Updating rubygems to $_RUBYGEMS_VERSION}"
14
+ retry --times 5 --sleep 5 gem update $gem_args --system $_RUBYGEMS_VERSION
16
15
  ;;
17
16
  esac
18
17
 
19
18
  case "${_BUNDLER_VERSION-"latest"}" in
20
19
  "latest")
21
- gem update bundler $gem_args
20
+ echo "Updating bundler"
21
+ retry --times 5 --sleep 5 gem update bundler $gem_args
22
22
  ;;
23
23
  *)
24
- gem install bundler $gem_args --version $_BUNDLER_VERSION
24
+ echo "Updating bundler to $_BUNDLER_VERSION"
25
+ retry --times 5 --sleep 5 gem install bundler $gem_args --version $_BUNDLER_VERSION
25
26
  ;;
26
27
  esac
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.0.3
4
+ version: 3.0.7
5
5
  platform: ruby
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: 2021-04-21 00:00:00.000000000 Z
13
+ date: 2021-06-15 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rack
@@ -210,6 +210,7 @@ files:
210
210
  - lib/appsignal/hooks/celluloid.rb
211
211
  - lib/appsignal/hooks/data_mapper.rb
212
212
  - lib/appsignal/hooks/delayed_job.rb
213
+ - lib/appsignal/hooks/excon.rb
213
214
  - lib/appsignal/hooks/mongo_ruby_driver.rb
214
215
  - lib/appsignal/hooks/net_http.rb
215
216
  - lib/appsignal/hooks/passenger.rb
@@ -229,6 +230,7 @@ files:
229
230
  - lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb
230
231
  - lib/appsignal/integrations/data_mapper.rb
231
232
  - lib/appsignal/integrations/delayed_job_plugin.rb
233
+ - lib/appsignal/integrations/excon.rb
232
234
  - lib/appsignal/integrations/grape.rb
233
235
  - lib/appsignal/integrations/mongo_ruby_driver.rb
234
236
  - lib/appsignal/integrations/net_http.rb
@@ -247,7 +249,6 @@ files:
247
249
  - lib/appsignal/marker.rb
248
250
  - lib/appsignal/minutely.rb
249
251
  - lib/appsignal/probes.rb
250
- - lib/appsignal/probes/puma.rb
251
252
  - lib/appsignal/probes/sidekiq.rb
252
253
  - lib/appsignal/rack/generic_instrumentation.rb
253
254
  - lib/appsignal/rack/rails_instrumentation.rb
@@ -266,6 +267,7 @@ files:
266
267
  - lib/appsignal/version.rb
267
268
  - lib/puma/plugin/appsignal.rb
268
269
  - lib/sequel/extensions/appsignal_integration.rb
270
+ - mono.yml
269
271
  - resources/appsignal.yml.erb
270
272
  - resources/cacert.pem
271
273
  - spec/.rubocop.yml
@@ -304,6 +306,7 @@ files:
304
306
  - spec/lib/appsignal/hooks/celluloid_spec.rb
305
307
  - spec/lib/appsignal/hooks/data_mapper_spec.rb
306
308
  - spec/lib/appsignal/hooks/delayed_job_spec.rb
309
+ - spec/lib/appsignal/hooks/excon_spec.rb
307
310
  - spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb
308
311
  - spec/lib/appsignal/hooks/net_http_spec.rb
309
312
  - spec/lib/appsignal/hooks/passenger_spec.rb
@@ -331,7 +334,6 @@ files:
331
334
  - spec/lib/appsignal/logger_spec.rb
332
335
  - spec/lib/appsignal/marker_spec.rb
333
336
  - spec/lib/appsignal/minutely_spec.rb
334
- - spec/lib/appsignal/probes/puma_spec.rb
335
337
  - spec/lib/appsignal/probes/sidekiq_spec.rb
336
338
  - spec/lib/appsignal/rack/generic_instrumentation_spec.rb
337
339
  - spec/lib/appsignal/rack/rails_instrumentation_spec.rb
@@ -411,7 +413,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
411
413
  - !ruby/object:Gem::Version
412
414
  version: '0'
413
415
  requirements: []
414
- rubygems_version: 3.2.16
416
+ rubygems_version: 3.2.17
415
417
  signing_key:
416
418
  specification_version: 4
417
419
  summary: Logs performance and exception data from your app to appsignal.com
@@ -452,6 +454,7 @@ test_files:
452
454
  - spec/lib/appsignal/hooks/celluloid_spec.rb
453
455
  - spec/lib/appsignal/hooks/data_mapper_spec.rb
454
456
  - spec/lib/appsignal/hooks/delayed_job_spec.rb
457
+ - spec/lib/appsignal/hooks/excon_spec.rb
455
458
  - spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb
456
459
  - spec/lib/appsignal/hooks/net_http_spec.rb
457
460
  - spec/lib/appsignal/hooks/passenger_spec.rb
@@ -479,7 +482,6 @@ test_files:
479
482
  - spec/lib/appsignal/logger_spec.rb
480
483
  - spec/lib/appsignal/marker_spec.rb
481
484
  - spec/lib/appsignal/minutely_spec.rb
482
- - spec/lib/appsignal/probes/puma_spec.rb
483
485
  - spec/lib/appsignal/probes/sidekiq_spec.rb
484
486
  - spec/lib/appsignal/rack/generic_instrumentation_spec.rb
485
487
  - spec/lib/appsignal/rack/rails_instrumentation_spec.rb
@@ -1,61 +0,0 @@
1
- module Appsignal
2
- module Probes
3
- class PumaProbe
4
- def initialize
5
- @hostname = Appsignal.config[:hostname] || Socket.gethostname
6
- end
7
-
8
- # @api private
9
- def call
10
- puma_stats = fetch_puma_stats
11
- return unless puma_stats
12
-
13
- stats = JSON.parse puma_stats, :symbolize_names => true
14
- counts = {}
15
- count_keys = [:backlog, :running, :pool_capacity, :max_threads]
16
-
17
- if stats[:worker_status] # Multiple workers
18
- stats[:worker_status].each do |worker|
19
- stat = worker[:last_status]
20
- count_keys.each do |key|
21
- count_if_present counts, key, stat
22
- end
23
- end
24
-
25
- gauge(:workers, stats[:workers], :type => :count)
26
- gauge(:workers, stats[:booted_workers], :type => :booted)
27
- gauge(:workers, stats[:old_workers], :type => :old)
28
- else # Single worker
29
- count_keys.each do |key|
30
- count_if_present counts, key, stats
31
- end
32
- end
33
-
34
- gauge(:connection_backlog, counts[:backlog]) if counts[:backlog]
35
- gauge(:pool_capacity, counts[:pool_capacity]) if counts[:pool_capacity]
36
- gauge(:threads, counts[:running], :type => :running) if counts[:running]
37
- gauge(:threads, counts[:max_threads], :type => :max) if counts[:max_threads]
38
- end
39
-
40
- private
41
-
42
- attr_reader :hostname
43
-
44
- def gauge(field, count, tags = {})
45
- Appsignal.set_gauge("puma_#{field}", count, tags.merge(:hostname => hostname))
46
- end
47
-
48
- def count_if_present(counts, key, stats)
49
- stat_value = stats[key]
50
- return unless stat_value
51
- counts[key] ||= 0
52
- counts[key] += stat_value
53
- end
54
-
55
- def fetch_puma_stats
56
- ::Puma.stats
57
- rescue NoMethodError # rubocop:disable Lint/HandleExceptions
58
- end
59
- end
60
- end
61
- end
@@ -1,180 +0,0 @@
1
- require "appsignal/probes/puma"
2
-
3
- describe Appsignal::Probes::PumaProbe do
4
- before(:context) do
5
- Appsignal.config = project_fixture_config
6
- end
7
- after(:context) do
8
- Appsignal.config = nil
9
- end
10
-
11
- let(:probe) { described_class.new }
12
-
13
- describe "hostname" do
14
- it "returns the socket hostname" do
15
- expect(probe.send(:hostname)).to eql(Socket.gethostname)
16
- end
17
-
18
- context "with overridden hostname" do
19
- around do |sample|
20
- Appsignal.config[:hostname] = "frontend1"
21
- sample.run
22
- Appsignal.config[:hostname] = nil
23
- end
24
- it "returns the configured host" do
25
- expect(probe.send(:hostname)).to eql("frontend1")
26
- end
27
- end
28
- end
29
-
30
- describe "#call" do
31
- let(:expected_default_tags) { { :hostname => Socket.gethostname } }
32
-
33
- context "with multiple worker stats" do
34
- before(:context) do
35
- class Puma
36
- def self.stats
37
- {
38
- "workers" => 2,
39
- "booted_workers" => 2,
40
- "old_workers" => 0,
41
- "worker_status" => [
42
- {
43
- "last_status" => {
44
- "backlog" => 0,
45
- "running" => 5,
46
- "pool_capacity" => 5,
47
- "max_threads" => 5
48
- }
49
- },
50
- {
51
- "last_status" => {
52
- "backlog" => 0,
53
- "running" => 5,
54
- "pool_capacity" => 5,
55
- "max_threads" => 5
56
- }
57
- }
58
- ]
59
- }.to_json
60
- end
61
- end
62
- end
63
- after(:context) { Object.send(:remove_const, :Puma) }
64
-
65
- it "calls `puma_gauge` with the (summed) worker metrics" do
66
- expect_gauge(:workers, 2, :type => :count)
67
- expect_gauge(:workers, 2, :type => :booted)
68
- expect_gauge(:workers, 0, :type => :old)
69
-
70
- expect_gauge(:connection_backlog, 0)
71
- expect_gauge(:pool_capacity, 10)
72
- expect_gauge(:threads, 10, :type => :running)
73
- expect_gauge(:threads, 10, :type => :max)
74
-
75
- probe.call
76
- end
77
- end
78
-
79
- context "with single worker stats" do
80
- before(:context) do
81
- class Puma
82
- def self.stats
83
- {
84
- "backlog" => 0,
85
- "running" => 5,
86
- "pool_capacity" => 5,
87
- "max_threads" => 5
88
- }.to_json
89
- end
90
- end
91
- end
92
- after(:context) { Object.send(:remove_const, :Puma) }
93
-
94
- it "calls `puma_gauge` with the (summed) worker metrics" do
95
- expect_gauge(:connection_backlog, 0)
96
- expect_gauge(:pool_capacity, 5)
97
- expect_gauge(:threads, 5, :type => :running)
98
- expect_gauge(:threads, 5, :type => :max)
99
- probe.call
100
- end
101
- end
102
-
103
- context "without stats" do
104
- before(:context) do
105
- class Puma
106
- def self.stats
107
- end
108
- end
109
- end
110
- after(:context) { Object.send(:remove_const, :Puma) }
111
-
112
- context "when it returns nil" do
113
- it "does not track metrics" do
114
- expect(probe).to_not receive(:puma_gauge)
115
- probe.call
116
- end
117
- end
118
-
119
- # Puma.stats raises a NoMethodError on a nil object on the first call.
120
- context "when it returns a NoMethodError on the first call" do
121
- let(:log) { StringIO.new }
122
-
123
- it "ignores the first call and tracks the second call" do
124
- use_logger_with log do
125
- expect(Puma).to receive(:stats)
126
- .and_raise(NoMethodError.new("undefined method `stats' for nil:NilClass"))
127
- probe.call
128
-
129
- expect(Puma).to receive(:stats).and_return({
130
- "backlog" => 1,
131
- "running" => 5,
132
- "pool_capacity" => 4,
133
- "max_threads" => 6
134
- }.to_json)
135
-
136
- expect_gauge(:connection_backlog, 1)
137
- expect_gauge(:pool_capacity, 4)
138
- expect_gauge(:threads, 5, :type => :running)
139
- expect_gauge(:threads, 6, :type => :max)
140
- probe.call
141
- end
142
-
143
- expect(log_contents(log)).to_not contains_log(:error, "Error in minutely probe 'puma'")
144
- end
145
- end
146
-
147
- context "when it does not have a complete stats payload" do
148
- let(:log) { StringIO.new }
149
-
150
- it "tracks whatever metrics we do have" do
151
- use_logger_with log do
152
- expect(Puma).to receive(:stats).and_return({
153
- "backlog" => 1,
154
- "running" => 5
155
- }.to_json)
156
-
157
- expect_gauge(:connection_backlog, 1)
158
- expect_no_gauge(:pool_capacity)
159
- expect_gauge(:threads, 5, :type => :running)
160
- expect_no_gauge(:threads, :type => :max)
161
- probe.call
162
- end
163
-
164
- expect(log_contents(log)).to_not contains_log(:error, "Error in minutely probe 'puma'")
165
- end
166
- end
167
- end
168
-
169
- def expect_gauge(key, value, tags = {})
170
- expect(Appsignal).to receive(:set_gauge)
171
- .with("puma_#{key}", value, expected_default_tags.merge(tags))
172
- .and_call_original
173
- end
174
-
175
- def expect_no_gauge(key, tags = {})
176
- expect(Appsignal).to_not receive(:set_gauge)
177
- .with("puma_#{key}", anything, tags)
178
- end
179
- end
180
- end