munin_passenger 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cd4851916ebee9fa861409169457d111a73ffd2ba8601f94baac9656be2df3d5
4
- data.tar.gz: 5d65009a959ae947020602d57a84d97e7464f604cc0be371285a99177f357dd1
3
+ metadata.gz: 1e199f4682f3a32c4c4dc201db8bfee7bdf35c95265b404bcb6795649350f5f8
4
+ data.tar.gz: 9a9416d20a210a07462ac2bf9ceef5a83c30937245aba39d7ec025cddfd7b8d1
5
5
  SHA512:
6
- metadata.gz: 699faab7cf106fbd9243e0ab513ba43a7f78479f3dfcdedefab1f88364aa863eb360eaeb2d0dbc6f12d5521178a4463b6113c61642919e6af2941146cc7334fb
7
- data.tar.gz: 6467c039f53a061b6d4324c2b79b09eac0a32c8678f0933d31a05c130690bb9ede1852d90b3011a8f28e2c7e2b3ab1d62df4ef778041c07044b983a6e165704c
6
+ metadata.gz: 8a7678599187c76596d5fdad01a9595600bae3fdfdee7e9ac57ace8e9c88673e7401bf984945e2c05639190d6a65fadf5c381776ca23e7cd0b3d189521cdccb9
7
+ data.tar.gz: 1c70eaaa7f5ae9b8a4986b8bf924f21168c476274433c653da5c127ea017050675eff48e1a17643645e14508a57b643add5ebb3058d71a94fbd63a7adeeeae4f
data/Vagrantfile CHANGED
@@ -129,7 +129,7 @@ server {
129
129
  }
130
130
  EOF
131
131
  sudo rm -f /etc/nginx/sites-enabled/default
132
- sudo ln -s /etc/nginx/sites-available/rails /etc/nginx/sites-enabled/
132
+ sudo ln -sf /etc/nginx/sites-available/rails /etc/nginx/sites-enabled/
133
133
 
134
134
  # munin
135
135
  sudo add-apt-repository -y ppa:hawq/munin
@@ -141,7 +141,7 @@ server {
141
141
  root /var/cache/munin/www;
142
142
  }
143
143
  EOF
144
- sudo ln -s /etc/nginx/sites-available/munin /etc/nginx/sites-enabled/
144
+ sudo ln -sf /etc/nginx/sites-available/munin /etc/nginx/sites-enabled/
145
145
 
146
146
  # postgres
147
147
  sudo apt-get install -y postgresql postgresql-contrib
@@ -1,9 +1,43 @@
1
+ require 'json'
1
2
  require 'nokogiri'
2
3
  require 'ostruct'
3
4
 
4
5
  module MuninPassenger
5
6
  module Collect
6
7
 
8
+ def self.default_state_file
9
+ {
10
+ 'pses' => []
11
+ }
12
+ end
13
+
14
+ def self.read_state_file
15
+ filename = ENV['MUNIN_STATEFILE']
16
+ if filename and File.exist?(filename)
17
+ begin
18
+ JSON.parse(File.open(filename, 'r') {|f| f.read})
19
+ rescue
20
+ $stderr.puts "WARN: Couldn't open munin statefile at #{filename}: #{$!.message}"
21
+ default_state_file
22
+ end
23
+ else
24
+ default_state_file
25
+ end
26
+ end
27
+
28
+ def self.write_state_file(state)
29
+ filename = ENV['MUNIN_STATEFILE']
30
+ if filename
31
+ begin
32
+ File.open(filename, 'w') do |f|
33
+ f.write state.to_json
34
+ end
35
+ rescue
36
+ $stderr.puts "WARN: Error writing to statefile at #{filename}: #{$!.message}"
37
+ end
38
+ end
39
+ end
40
+
7
41
  def self.parse_stats(f)
8
42
  Nokogiri::XML(f) do |config|
9
43
  config.strict.
@@ -26,23 +60,74 @@ module MuninPassenger
26
60
  end
27
61
 
28
62
  def self.get_ps_stats(doc)
29
- ret = []
63
+ state = read_state_file
64
+ slots_by_pid = {}
65
+ state['pses'].each_with_index do |pid, i|
66
+ slots_by_pid[pid] = i if pid
67
+ end
68
+ ret = [nil] * state['pses'].size # Need at least as many workers as the most we've seen.
69
+ curr_pses = []
30
70
  now = Time.now
31
71
  doc.xpath('//info/supergroups/supergroup').each do |x_supergroup|
32
72
  x_supergroup.xpath('./group').each do |x_group|
33
73
  x_group.xpath('./processes/process').each do |x_ps|
74
+ pid = x_ps.xpath('pid').first.text
34
75
  ps = OpenStruct.new
35
- ps.pid = x_ps.xpath('pid').first.text
76
+ ps.active = true
77
+ ps.pid = pid
36
78
  ps.sessions = x_ps.xpath('sessions').first.text.to_i
37
79
  ps.last_used = (now - Time.at(x_ps.xpath('last_used').first.text.to_i / 1000 / 1000).to_i).to_i # in seconds
38
80
  ps.ram = x_ps.xpath('real_memory').first.text.to_i # in KB
39
81
  ps.cpu = x_ps.xpath('cpu').first.text.to_i # in %
40
82
  ps.uptime = (now - Time.at(x_ps.xpath('spawn_start_time').first.text.to_i / 1000 / 1000).to_i).to_i # in seconds
41
83
  ps.processed = x_ps.xpath('processed').first.text.to_i # in requests
42
- ret << ps
84
+ ps.last_seen = now.to_i
85
+ curr_pses << ps
43
86
  end
44
87
  end
45
88
  end
89
+ # This is all a little tricky,
90
+ # but if we name each metric after the pid,
91
+ # munin will throw away the history when passenger is restarted and the pids change.
92
+ # So instead we have "worker1", "worker2", etc.,
93
+ # and we show the current pid in parentheses.
94
+ # Each time we collect info, we keep a pid in the same slot as before.
95
+ # If a pid goes away, we free that slot.
96
+ # If it's the first we've seen a pid,
97
+ # we give it the first free slot.
98
+ new_pses = []
99
+ curr_pses.each do |ps|
100
+ i = slots_by_pid[ps.pid]
101
+ if i
102
+ ret[i] = ps
103
+ else
104
+ new_pses << ps
105
+ end
106
+ end
107
+ new_pses.each do |ps|
108
+ i = ret.index{|x| x == nil}
109
+ if i
110
+ ret[i] = ps
111
+ else
112
+ ret << ps
113
+ end
114
+ end
115
+ state['pses'] = ret.map do |ps|
116
+ if ps
117
+ {
118
+ 'pid' => ps.pid,
119
+ 'last_seen' => ps.last_seen,
120
+ }
121
+ else
122
+ nil
123
+ end
124
+ end
125
+ write_state_file(state)
126
+ # Now if there are still nils,
127
+ # it means we are running than fewer workers than before.
128
+ # Preserve those slots,
129
+ # but the graphing code will have to watch out
130
+ # and note that they have no process currently.
46
131
  ret
47
132
  end
48
133
 
@@ -30,9 +30,10 @@ graph_vlabel Requests
30
30
  _group_#{escape_group(g.name)}_queue.label #{g.name}
31
31
  EOF
32
32
  end
33
- pses.each do |ps|
33
+ pses.each_with_index do |ps, i|
34
+ pidstr = ps ? "(PID #{ps.pid})" : "(no PID)"
34
35
  ret += <<-EOF
35
- _pid_#{ps.pid}_sessions.label PID #{ps.pid}
36
+ _worker_#{i + 1}_sessions.label Worker #{i + 1} #{pidstr}
36
37
  EOF
37
38
  end
38
39
  ret
@@ -46,9 +47,10 @@ _pid_#{ps.pid}_sessions.label PID #{ps.pid}
46
47
  _group_#{escape_group(g.name)}_queue.value #{g.queue}
47
48
  EOF
48
49
  end
49
- pses.each do |ps|
50
+ pses.each_with_index do |ps, i|
51
+ next unless ps
50
52
  ret += <<-EOF
51
- _pid_#{ps.pid}_sessions.value #{ps.sessions}
53
+ _worker_#{i + 1}_sessions.value #{ps.sessions}
52
54
  EOF
53
55
  end
54
56
  ret
@@ -66,9 +68,10 @@ graph_category passenger
66
68
  graph_title Passenger memory usage
67
69
  graph_vlabel Bytes
68
70
  EOF
69
- pses.each do |ps|
71
+ pses.each_with_index do |ps, i|
72
+ pidstr = ps ? "(PID #{ps.pid})" : "(no PID)"
70
73
  ret += <<-EOF
71
- _pid_#{ps.pid}_ram.label PID #{ps.pid}
74
+ _worker_#{i + 1}_ram.label Worker #{i + 1} #{pidstr}
72
75
  EOF
73
76
  end
74
77
  ret
@@ -77,9 +80,10 @@ _pid_#{ps.pid}_ram.label PID #{ps.pid}
77
80
  def self.ram_values
78
81
  groups, pses = get_stats
79
82
  ret = ''
80
- pses.each do |ps|
83
+ pses.each_with_index do |ps, i|
84
+ next unless ps
81
85
  ret += <<-EOF
82
- _pid_#{ps.pid}_ram.value #{ps.ram * 1024}
86
+ _worker_#{i + 1}_ram.value #{ps.ram * 1024}
83
87
  EOF
84
88
  end
85
89
  ret
@@ -97,9 +101,10 @@ graph_category passenger
97
101
  graph_title Passenger CPU
98
102
  graph_vlabel %
99
103
  EOF
100
- pses.each do |ps|
104
+ pses.each_with_index do |ps, i|
105
+ pidstr = ps ? "(PID #{ps.pid})" : "(no PID)"
101
106
  ret += <<-EOF
102
- _pid_#{ps.pid}_cpu.label PID #{ps.pid}
107
+ _worker_#{i + 1}_cpu.label Worker #{i + 1} #{pidstr}
103
108
  EOF
104
109
  end
105
110
  ret
@@ -108,9 +113,10 @@ _pid_#{ps.pid}_cpu.label PID #{ps.pid}
108
113
  def self.cpu_values
109
114
  groups, pses = get_stats
110
115
  ret = ''
111
- pses.each do |ps|
116
+ pses.each_with_index do |ps, i|
117
+ next unless ps
112
118
  ret += <<-EOF
113
- _pid_#{ps.pid}_cpu.value #{ps.cpu}
119
+ _worker_#{i + 1}_cpu.value #{ps.cpu}
114
120
  EOF
115
121
  end
116
122
  ret
@@ -128,9 +134,10 @@ graph_category passenger
128
134
  graph_title Requests processed
129
135
  graph_vlabel Requests
130
136
  EOF
131
- pses.each do |ps|
137
+ pses.each_with_index do |ps, i|
138
+ pidstr = ps ? "(PID #{ps.pid})" : "(no PID)"
132
139
  ret += <<-EOF
133
- _pid_#{ps.pid}_processed.label PID #{ps.pid}
140
+ _worker_#{i + 1}_processed.label Worker #{i + 1} #{pidstr}
134
141
  EOF
135
142
  end
136
143
  ret
@@ -139,9 +146,10 @@ _pid_#{ps.pid}_processed.label PID #{ps.pid}
139
146
  def self.processed_values
140
147
  groups, pses = get_stats
141
148
  ret = ''
142
- pses.each do |ps|
149
+ pses.each_with_index do |ps, i|
150
+ next unless ps
143
151
  ret += <<-EOF
144
- _pid_#{ps.pid}_processed.value #{ps.processed}
152
+ _worker_#{i + 1}_processed.value #{ps.processed}
145
153
  EOF
146
154
  end
147
155
  ret
@@ -159,9 +167,10 @@ graph_category passenger
159
167
  graph_title Uptime
160
168
  graph_vlabel Hours
161
169
  EOF
162
- pses.each do |ps|
170
+ pses.each_with_index do |ps, i|
171
+ pidstr = ps ? "(PID #{ps.pid})" : "(no PID)"
163
172
  ret += <<-EOF
164
- _pid_#{ps.pid}_uptime.label PID #{ps.pid}
173
+ _worker_#{i + 1}_uptime.label Worker #{i + 1} #{pidstr}
165
174
  EOF
166
175
  end
167
176
  ret
@@ -170,9 +179,10 @@ _pid_#{ps.pid}_uptime.label PID #{ps.pid}
170
179
  def self.uptime_values
171
180
  groups, pses = get_stats
172
181
  ret = ''
173
- pses.each do |ps|
182
+ pses.each_with_index do |ps, i|
183
+ next unless ps
174
184
  ret += <<-EOF
175
- _pid_#{ps.pid}_uptime.value #{ps.uptime.to_f / 60 / 60}
185
+ _worker_#{i + 1}_uptime.value #{ps.uptime.to_f / 60 / 60}
176
186
  EOF
177
187
  end
178
188
  ret
@@ -190,9 +200,10 @@ graph_category passenger
190
200
  graph_title Last used
191
201
  graph_vlabel Seconds
192
202
  EOF
193
- pses.each do |ps|
203
+ pses.each_with_index do |ps, i|
204
+ pidstr = ps ? "(PID #{ps.pid})" : "(no PID)"
194
205
  ret += <<-EOF
195
- _pid_#{ps.pid}_last_used.label PID #{ps.pid}
206
+ _worker_#{i + 1}_last_used.label Worker #{i + 1} #{pidstr}
196
207
  EOF
197
208
  end
198
209
  ret
@@ -201,9 +212,10 @@ _pid_#{ps.pid}_last_used.label PID #{ps.pid}
201
212
  def self.last_used_values
202
213
  groups, pses = get_stats
203
214
  ret = ''
204
- pses.each do |ps|
215
+ pses.each_with_index do |ps, i|
216
+ next unless ps
205
217
  ret += <<-EOF
206
- _pid_#{ps.pid}_last_used.value #{ps.last_used}
218
+ _worker_#{i + 1}_last_used.value #{ps.last_used}
207
219
  EOF
208
220
  end
209
221
  ret
@@ -1,3 +1,3 @@
1
1
  module MuninPassenger
2
- VERSION = '1.0.0'
2
+ VERSION = '1.1.0'
3
3
  end
@@ -30,5 +30,6 @@ Gem::Specification.new do |s|
30
30
  s.add_development_dependency 'rubocop'
31
31
 
32
32
  s.add_dependency 'nokogiri'
33
+ s.add_dependency 'json'
33
34
  end
34
35
 
@@ -10,20 +10,20 @@ graph_category passenger
10
10
  graph_title Passenger queue
11
11
  graph_vlabel Requests
12
12
  _group__vagrant_example__production__queue.label /vagrant/example (production)
13
- _pid_4510_sessions.label PID 4510
14
- _pid_4529_sessions.label PID 4529
15
- _pid_4548_sessions.label PID 4548
16
- _pid_4567_sessions.label PID 4567
13
+ _worker_1_sessions.label Worker 1 (PID 4510)
14
+ _worker_2_sessions.label Worker 2 (PID 4529)
15
+ _worker_3_sessions.label Worker 3 (PID 4548)
16
+ _worker_4_sessions.label Worker 4 (PID 4567)
17
17
  EOF
18
18
  end
19
19
 
20
20
  it "gives the queue values" do
21
21
  expect(MuninPassenger::Graphs.queue_values).to eq <<-EOF
22
22
  _group__vagrant_example__production__queue.value 4
23
- _pid_4510_sessions.value 1
24
- _pid_4529_sessions.value 1
25
- _pid_4548_sessions.value 1
26
- _pid_4567_sessions.value 1
23
+ _worker_1_sessions.value 1
24
+ _worker_2_sessions.value 1
25
+ _worker_3_sessions.value 1
26
+ _worker_4_sessions.value 1
27
27
  EOF
28
28
  end
29
29
 
@@ -32,19 +32,19 @@ _pid_4567_sessions.value 1
32
32
  graph_category passenger
33
33
  graph_title Passenger memory usage
34
34
  graph_vlabel Bytes
35
- _pid_4510_ram.label PID 4510
36
- _pid_4529_ram.label PID 4529
37
- _pid_4548_ram.label PID 4548
38
- _pid_4567_ram.label PID 4567
35
+ _worker_1_ram.label Worker 1 (PID 4510)
36
+ _worker_2_ram.label Worker 2 (PID 4529)
37
+ _worker_3_ram.label Worker 3 (PID 4548)
38
+ _worker_4_ram.label Worker 4 (PID 4567)
39
39
  EOF
40
40
  end
41
41
 
42
42
  it "gives the ram values" do
43
43
  expect(MuninPassenger::Graphs.ram_values).to eq <<-EOF
44
- _pid_4510_ram.value #{40400 * 1024}
45
- _pid_4529_ram.value #{24396 * 1024}
46
- _pid_4548_ram.value #{24268 * 1024}
47
- _pid_4567_ram.value #{23872 * 1024}
44
+ _worker_1_ram.value #{40400 * 1024}
45
+ _worker_2_ram.value #{24396 * 1024}
46
+ _worker_3_ram.value #{24268 * 1024}
47
+ _worker_4_ram.value #{23872 * 1024}
48
48
  EOF
49
49
  end
50
50
 
@@ -53,19 +53,19 @@ _pid_4567_ram.value #{23872 * 1024}
53
53
  graph_category passenger
54
54
  graph_title Passenger CPU
55
55
  graph_vlabel %
56
- _pid_4510_cpu.label PID 4510
57
- _pid_4529_cpu.label PID 4529
58
- _pid_4548_cpu.label PID 4548
59
- _pid_4567_cpu.label PID 4567
56
+ _worker_1_cpu.label Worker 1 (PID 4510)
57
+ _worker_2_cpu.label Worker 2 (PID 4529)
58
+ _worker_3_cpu.label Worker 3 (PID 4548)
59
+ _worker_4_cpu.label Worker 4 (PID 4567)
60
60
  EOF
61
61
  end
62
62
 
63
63
  it "gives the cpu values" do
64
64
  expect(MuninPassenger::Graphs.cpu_values).to eq <<-EOF
65
- _pid_4510_cpu.value 2
66
- _pid_4529_cpu.value 3
67
- _pid_4548_cpu.value 2
68
- _pid_4567_cpu.value 2
65
+ _worker_1_cpu.value 2
66
+ _worker_2_cpu.value 3
67
+ _worker_3_cpu.value 2
68
+ _worker_4_cpu.value 2
69
69
  EOF
70
70
  end
71
71
 
@@ -74,19 +74,19 @@ _pid_4567_cpu.value 2
74
74
  graph_category passenger
75
75
  graph_title Requests processed
76
76
  graph_vlabel Requests
77
- _pid_4510_processed.label PID 4510
78
- _pid_4529_processed.label PID 4529
79
- _pid_4548_processed.label PID 4548
80
- _pid_4567_processed.label PID 4567
77
+ _worker_1_processed.label Worker 1 (PID 4510)
78
+ _worker_2_processed.label Worker 2 (PID 4529)
79
+ _worker_3_processed.label Worker 3 (PID 4548)
80
+ _worker_4_processed.label Worker 4 (PID 4567)
81
81
  EOF
82
82
  end
83
83
 
84
84
  it "gives the processed values" do
85
85
  expect(MuninPassenger::Graphs.processed_values).to eq <<-EOF
86
- _pid_4510_processed.value 139
87
- _pid_4529_processed.value 138
88
- _pid_4548_processed.value 138
89
- _pid_4567_processed.value 138
86
+ _worker_1_processed.value 139
87
+ _worker_2_processed.value 138
88
+ _worker_3_processed.value 138
89
+ _worker_4_processed.value 138
90
90
  EOF
91
91
  end
92
92
 
@@ -95,20 +95,20 @@ _pid_4567_processed.value 138
95
95
  graph_category passenger
96
96
  graph_title Uptime
97
97
  graph_vlabel Hours
98
- _pid_4510_uptime.label PID 4510
99
- _pid_4529_uptime.label PID 4529
100
- _pid_4548_uptime.label PID 4548
101
- _pid_4567_uptime.label PID 4567
98
+ _worker_1_uptime.label Worker 1 (PID 4510)
99
+ _worker_2_uptime.label Worker 2 (PID 4529)
100
+ _worker_3_uptime.label Worker 3 (PID 4548)
101
+ _worker_4_uptime.label Worker 4 (PID 4567)
102
102
  EOF
103
103
  end
104
104
 
105
105
  it "gives the uptime values" do
106
106
  Timecop.travel('Thu Sep 13 20:36:38 PDT 2018') do
107
107
  expect(MuninPassenger::Graphs.uptime_values).to eq <<-EOF
108
- _pid_4510_uptime.value 9.369166666666667
109
- _pid_4529_uptime.value 9.368888888888888
110
- _pid_4548_uptime.value 9.368888888888888
111
- _pid_4567_uptime.value 9.368888888888888
108
+ _worker_1_uptime.value 9.369166666666667
109
+ _worker_2_uptime.value 9.368888888888888
110
+ _worker_3_uptime.value 9.368888888888888
111
+ _worker_4_uptime.value 9.368888888888888
112
112
  EOF
113
113
  end
114
114
  end
@@ -118,20 +118,20 @@ _pid_4567_uptime.value 9.368888888888888
118
118
  graph_category passenger
119
119
  graph_title Last used
120
120
  graph_vlabel Seconds
121
- _pid_4510_last_used.label PID 4510
122
- _pid_4529_last_used.label PID 4529
123
- _pid_4548_last_used.label PID 4548
124
- _pid_4567_last_used.label PID 4567
121
+ _worker_1_last_used.label Worker 1 (PID 4510)
122
+ _worker_2_last_used.label Worker 2 (PID 4529)
123
+ _worker_3_last_used.label Worker 3 (PID 4548)
124
+ _worker_4_last_used.label Worker 4 (PID 4567)
125
125
  EOF
126
126
  end
127
127
 
128
128
  it "gives the last_used values" do
129
129
  Timecop.travel('Thu Sep 13 20:36:38 PDT 2018') do
130
130
  expect(MuninPassenger::Graphs.last_used_values).to eq <<-EOF
131
- _pid_4510_last_used.value 33697
132
- _pid_4529_last_used.value 33697
133
- _pid_4548_last_used.value 33697
134
- _pid_4567_last_used.value 33697
131
+ _worker_1_last_used.value 33697
132
+ _worker_2_last_used.value 33697
133
+ _worker_3_last_used.value 33697
134
+ _worker_4_last_used.value 33697
135
135
  EOF
136
136
  end
137
137
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: munin_passenger
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul A. Jungwirth
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-09-19 00:00:00.000000000 Z
11
+ date: 2018-10-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: json
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
111
125
  description: Runs passenger-status to graph CPU, RAM, queue size, requests served,
112
126
  etc.
113
127
  email: pj@illuminatedcomputing.com