appsignal 3.0.6-java → 3.0.10-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.
@@ -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