munin_passenger 1.0.0 → 1.1.0

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 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