sensu-plugins-process-checks 2.4.0 → 2.5.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
  SHA1:
3
- metadata.gz: e4c1e16b051ae71d9479b95387e22c504ab7a7f0
4
- data.tar.gz: 43d7d36c527666e51220a43a05c26793ea420397
3
+ metadata.gz: 2d2298603cc93f7fa246cfae47fe4abf183fbe12
4
+ data.tar.gz: 0df7445dde46ef1df869d6f35470c78b3cf00859
5
5
  SHA512:
6
- metadata.gz: 4d4cca0b109f96d84089aa5855841a9bc50e8214949c883092850c16d43ada5af4912ec5da7f7cac1915ee81fe2c9e34e46e9731f0b379d5f61c6836ed621829
7
- data.tar.gz: 512a08cd43764730059955e144f7dd3772ae9944b517a7bc5ac969ad5b07be2d6b7a8e136a73ff8693436b6e442638a34a17c758209cff2c1dd62be80164b791
6
+ metadata.gz: 19dc7d11cd249a108ef10e6e52001754f1d560d5dbdcd85566107b6d2a2479982a08b81daeec8870c3fb125f4da9f3e5f5cf1b28ab70ce657909339e26c3d480
7
+ data.tar.gz: 02e090d85944b1dda4eadb8e500f838c0ca42a84e479127632571c45666a10be5d5d253549b9cdaa613c71b9c5d1ed42c0c3e37c02852685a627fc6a18ee0040
@@ -1,11 +1,21 @@
1
1
  # Change Log
2
2
  This project adheres to [Semantic Versioning](http://semver.org/).
3
3
 
4
- This CHANGELOG follows the format listed at [Keep A Changelog](http://keepachangelog.com/)
4
+ This CHANGELOG follows the format listed [here](https://github.com/sensu-plugins/community/blob/master/HOW_WE_CHANGELOG.md)
5
5
 
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [2.5.0] - 2017-10-04
10
+ ### Added
11
+ - metric-per-processes.py: Add metrics filter (@rthouvenin)
12
+
13
+ ### Changed
14
+ - updated changelog guidelines (@majormoses)
15
+
16
+ ### Fixed
17
+ - spelling in PR template (@majormoses)
18
+
9
19
  ## [2.4.0] - 2017-07-18
10
20
  ### Added
11
21
  - ruby 2.4 testing (@majormoses)
@@ -139,8 +149,9 @@ This CHANGELOG follows the format listed at [Keep A Changelog](http://keepachang
139
149
  - built against 1.9.3, 2.0, 2.1
140
150
  - cryptographically signed
141
151
 
142
- [Unreleased]: https://github.com/sensu-plugins/sensu-plugins-process-checks/compare/2.3.0...HEAD
143
- [2.4.0]: https://github.com/sensu-plugins/sensu-plugins-process-checks/compare/2.3.0...
152
+ [Unreleased]: https://github.com/sensu-plugins/sensu-plugins-process-checks/compare/2.5.0...HEAD
153
+ [2.5.0]: https://github.com/sensu-plugins/sensu-plugins-process-checks/compare/2.4.0...2.5.0
154
+ [2.4.0]: https://github.com/sensu-plugins/sensu-plugins-process-checks/compare/2.3.0...2.4.0
144
155
  [2.3.0]: https://github.com/sensu-plugins/sensu-plugins-process-checks/compare/2.2.0...2.3.0
145
156
  [2.2.0]: https://github.com/sensu-plugins/sensu-plugins-process-checks/compare/2.1.0...2.2.0
146
157
  [2.1.0]: https://github.com/sensu-plugins/sensu-plugins-process-checks/compare/2.0.0...2.1.0
data/README.md CHANGED
@@ -26,8 +26,40 @@
26
26
 
27
27
  ## Usage
28
28
 
29
+ Check if an arbitrary process seems to be running or not. Our arbitrary process in this example is called `gutrot`.
30
+ Usage of `check-process.rb` would look something similar to the following:
31
+
32
+ $ /opt/sensu/embedded/bin/ruby /opt/sensu/embedded/bin/check-process.rb -p gutrot
33
+ CheckProcess OK: Found 3 matching processes; cmd /gutrot/
34
+
35
+ The `-p` argument is for a pattern to match against the list of running processes reported by `ps`.
36
+
37
+ Example configuration at `/etc/sensu/conf.d/check_gutrot_running.json`:
38
+
39
+ {
40
+ "checks": {
41
+ "check_gutrot_running": {
42
+ "command": "check-process.rb -p gutrot",
43
+ "standalone": true,
44
+ "interval": 60,
45
+ "handlers": ["default"]
46
+ }
47
+ }
48
+ }
49
+
50
+ The check is named `check_gutrot_running` and it runs `check-process.rb -p gutrot` every `60` seconds (interval)
51
+ then lets the `default` handler handle the result.
52
+
29
53
  ## Installation
30
54
 
31
55
  [Installation and Setup](http://sensu-plugins.io/docs/installation_instructions.html)
32
56
 
57
+ Quick install after following the steps above:
58
+
59
+ $ sensu-install process-checks
60
+
61
+ The checks will be installed at:
62
+
63
+ /opt/sensu/embedded/bin/
64
+
33
65
  ## Notes
@@ -16,7 +16,7 @@
16
16
  #
17
17
  # USAGE:
18
18
  #
19
- # metrics-per-process.py -n <process_name> | -p <path_to_process_pid_file> [-s <graphite_scheme>]
19
+ # metrics-per-process.py -n <process_name> | -p <path_to_process_pid_file> [-s <graphite_scheme>] [-m <metrics_regexes>]
20
20
  #
21
21
  # NOTES:
22
22
  # The plugin requires to read files in the /proc file system, make sure the owner
@@ -66,6 +66,7 @@
66
66
  import os
67
67
  import optparse
68
68
  import psutil
69
+ import re
69
70
  import sys
70
71
  import time
71
72
 
@@ -89,6 +90,7 @@ TCP_CONN_STATUSES = [
89
90
  'CLOSING',
90
91
  'NONE'
91
92
  ]
93
+ MEMORY_STATS = ['rss', 'vms', 'shared', 'text', 'lib', 'data', 'dirty']
92
94
 
93
95
  def find_pids_from_name(process_name):
94
96
  '''Find process PID from name using /proc/<pids>/comm'''
@@ -107,60 +109,115 @@ def find_pids_from_name(process_name):
107
109
  pass
108
110
  return pids
109
111
 
110
- def stats_per_pid(pid):
111
- '''Gets process stats using psutil module
112
+ def additional_stats(process_handler, metrics_regexp):
113
+ stats = {}
112
114
 
113
- details at http://pythonhosted.org/psutil/#process-class'''
115
+ if metrics_regexp.match('cpu.user'):
116
+ stats['cpu.user'] = process_handler.cpu_times().user
114
117
 
115
- stats = {}
116
- process_handler = psutil.Process(pid)
118
+ if metrics_regexp.match('cpu.system'):
119
+ stats['cpu.system'] = process_handler.cpu_times().system
120
+
121
+ if metrics_regexp.match('cpu.percent'):
122
+ stats['cpu.percent'] = process_handler.cpu_percent()
123
+
124
+ if metrics_regexp.match('threads'):
125
+ stats['threads'] = process_handler.num_threads()
126
+
127
+ if metrics_regexp.match('memory.percent'):
128
+ stats['memory.percent'] = process_handler.memory_percent()
129
+
130
+ if metrics_regexp.match('fds'):
131
+ stats['fds'] = process_handler.num_fds()
132
+
133
+ if metrics_regexp.match('ctx_switches.voluntary'):
134
+ stats['ctx_switches.voluntary'] = process_handler.num_ctx_switches().voluntary
135
+
136
+ if metrics_regexp.match('ctx_switches.involuntary'):
137
+ stats['ctx_switches.involuntary'] = process_handler.num_ctx_switches().involuntary
138
+
139
+ if metrics_regexp.match('io_counters.read_count'):
140
+ stats['io_counters.read_count'] = process_handler.io_counters().read_count
141
+
142
+ if metrics_regexp.match('io_counters.write_count'):
143
+ stats['io_counters.write_count'] = process_handler.io_counters().write_count
144
+
145
+ if metrics_regexp.match('io_counters.read_bytes'):
146
+ stats['io_counters.read_bytes'] = process_handler.io_counters().read_bytes
147
+
148
+ if metrics_regexp.match('io_counters.write_bytes'):
149
+ stats['io_counters.write_bytes'] = process_handler.io_counters().write_bytes
150
+
151
+ return stats
152
+
153
+ # Memory info
154
+ def memory_stats(process_handler, metrics_regexp):
117
155
  if psutil.version_info < (4,0,0):
118
156
  process_memory_info = process_handler.memory_info_ex()
119
157
  else:
120
158
  process_memory_info = process_handler.memory_info()
121
- stats['cpu.user'] = process_handler.cpu_times().user
122
- stats['cpu.system'] = process_handler.cpu_times().system
123
- stats['cpu.percent'] = process_handler.cpu_percent()
124
- stats['threads'] = process_handler.num_threads()
125
- stats['memory.rss'] = process_memory_info.rss
126
- stats['memory.vms'] = process_memory_info.vms
127
- stats['memory.shared'] = process_memory_info.shared
128
- stats['memory.text'] = process_memory_info.text
129
- stats['memory.lib'] = process_memory_info.lib
130
- stats['memory.data'] = process_memory_info.data
131
- stats['memory.dirty'] = process_memory_info.dirty
132
- stats['memory.percent'] = process_handler.memory_percent()
133
- stats['fds'] = process_handler.num_fds()
134
- stats['ctx_switches.voluntary'] = process_handler.num_ctx_switches().voluntary
135
- stats['ctx_switches.involuntary'] = process_handler.num_ctx_switches().involuntary
136
- stats['io_counters.read_count'] = process_handler.io_counters().read_count
137
- stats['io_counters.write_count'] = process_handler.io_counters().write_count
138
- stats['io_counters.read_bytes'] = process_handler.io_counters().read_bytes
139
- stats['io_counters.write_bytes'] = process_handler.io_counters().write_bytes
140
- # TCP/UDP/Unix Socket Connections
141
- tcp_conns = process_handler.connections(kind='tcp')
159
+
160
+ stats = {}
161
+ for stat in MEMORY_STATS:
162
+ if metrics_regexp.match('memory.' + stat):
163
+ stats['memory.' + stat] = getattr(process_memory_info, stat)
164
+
165
+ return stats
166
+
167
+ # TCP/UDP/Unix Socket Connections
168
+ def connection_stats(process_handler, metrics_regexp):
169
+ tcp_stats = ['total'] + [s.lower() for s in TCP_CONN_STATUSES]
170
+ tcp_conns = None
171
+ tcp_conns_count = {}
172
+ for stat in tcp_stats:
173
+ if metrics_regexp.match('conns.tcp.' + stat):
174
+ if tcp_conns is None:
175
+ tcp_conns = process_handler.connections(kind='tcp')
176
+
177
+ stats = {}
142
178
  if tcp_conns:
143
179
  stats['conns.tcp.total'] = len(tcp_conns)
144
- tcp_conns_count = {}
145
180
  for tcp_status in TCP_CONN_STATUSES:
146
- tcp_conns_count['conns.tcp.' + tcp_status.lower()] = 0
147
- for conn in tcp_conns:
148
- if conn.status == tcp_status:
149
- tcp_conns_count['conns.tcp.' + tcp_status.lower()] = tcp_conns_count[
150
- 'conns.tcp.' + tcp_status.lower()] + 1
181
+ stat = 'conns.tcp.' + tcp_status.lower()
182
+ if metrics_regexp.match(stat):
183
+ tcp_conns_count[stat] = 0
184
+ for conn in tcp_conns:
185
+ if conn.status == tcp_status:
186
+ tcp_conns_count[stat] = tcp_conns_count[stat] + 1
151
187
  stats.update(tcp_conns_count)
152
- udp_conns = process_handler.connections(kind='udp')
153
- if udp_conns:
154
- stats['conns.udp.total'] = len(udp_conns)
155
- unix_conns = process_handler.connections(kind='unix')
156
- if unix_conns:
157
- stats['conns.unix_sockets.total'] = len(unix_conns)
188
+
189
+ if metrics_regexp.match('conns.udp.total'):
190
+ udp_conns = process_handler.connections(kind='udp')
191
+ if udp_conns:
192
+ stats['conns.udp.total'] = len(udp_conns)
193
+
194
+ if metrics_regexp.match('conns.unix_sockets.total'):
195
+ unix_conns = process_handler.connections(kind='unix')
196
+ if unix_conns:
197
+ stats['conns.unix_sockets.total'] = len(unix_conns)
198
+
199
+ return stats
200
+
201
+ def stats_per_pid(pid, metrics_regexes):
202
+ '''Gets process stats using psutil module
203
+
204
+ Returns only the stats with a name that matches one of the metrics_regexes
205
+ details at http://pythonhosted.org/psutil/#process-class'''
206
+
207
+ stats = {}
208
+ process_handler = psutil.Process(pid)
209
+
210
+ for metrics_regexp in metrics_regexes:
211
+ stats.update(memory_stats(process_handler, metrics_regexp))
212
+ stats.update(connection_stats(process_handler, metrics_regexp))
213
+ stats.update(additional_stats(process_handler, metrics_regexp))
214
+
158
215
  return stats
159
216
 
160
- def multi_pid_process_stats(pids):
217
+ def multi_pid_process_stats(pids, metrics_regexes):
161
218
  stats = {'total_processes': len(pids)}
162
219
  for pid in pids:
163
- stats = Counter(stats) + Counter(stats_per_pid(pid))
220
+ stats = Counter(stats) + Counter(stats_per_pid(pid, metrics_regexes))
164
221
  return stats
165
222
 
166
223
  def recursive_dict_sum(dictionnary):
@@ -208,6 +265,12 @@ def main():
208
265
  dest = 'graphite_scheme',
209
266
  metavar = 'GRAPHITE_SCHEME')
210
267
 
268
+ parser.add_option('-m', '--metrics-regexes',
269
+ help = 'comma-separated list of regexes used to match the metric names to collect, default to .*',
270
+ default = '.*',
271
+ dest = 'metrics_regexes',
272
+ metavar = 'METRICS_REGEXES')
273
+
211
274
  (options, args) = parser.parse_args()
212
275
 
213
276
  if options.process_name and options.process_pid_file:
@@ -218,13 +281,15 @@ def main():
218
281
  print 'A process name or a process pid file path is needed'
219
282
  sys.exit(1)
220
283
 
284
+ options.metrics_regexes = [re.compile(regex) for regex in options.metrics_regexes.split(',')]
285
+
221
286
  if options.process_name:
222
287
  pids = find_pids_from_name(options.process_name)
223
- graphite_printer(multi_pid_process_stats(pids), options.graphite_scheme)
288
+ graphite_printer(multi_pid_process_stats(pids, options.metrics_regexes), options.graphite_scheme)
224
289
 
225
290
  if options.process_pid_file:
226
291
  pid = get_pid_from_pid_file(options.process_pid_file)
227
- graphite_printer(stats_per_pid(pid), options.graphite_scheme)
292
+ graphite_printer(stats_per_pid(pid, options.metrics_regexes), options.graphite_scheme)
228
293
  #
229
294
  if __name__ == '__main__':
230
295
  main()
@@ -1,7 +1,7 @@
1
1
  module SensuPluginsProcessChecks
2
2
  module Version
3
3
  MAJOR = 2
4
- MINOR = 4
4
+ MINOR = 5
5
5
  PATCH = 0
6
6
 
7
7
  VER_STRING = [MAJOR, MINOR, PATCH].compact.join('.')
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sensu-plugins-process-checks
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.0
4
+ version: 2.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sensu-Plugins and contributors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-18 00:00:00.000000000 Z
11
+ date: 2017-10-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: english
@@ -236,7 +236,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
236
236
  version: '0'
237
237
  requirements: []
238
238
  rubyforge_project:
239
- rubygems_version: 2.4.5
239
+ rubygems_version: 2.6.13
240
240
  signing_key:
241
241
  specification_version: 4
242
242
  summary: Sensu plugins for checking running processes