sensu-plugins-process-checks 2.4.0 → 2.5.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 +4 -4
- data/CHANGELOG.md +14 -3
- data/README.md +32 -0
- data/bin/metrics-per-process.py +108 -43
- data/lib/sensu-plugins-process-checks/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2d2298603cc93f7fa246cfae47fe4abf183fbe12
|
|
4
|
+
data.tar.gz: 0df7445dde46ef1df869d6f35470c78b3cf00859
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 19dc7d11cd249a108ef10e6e52001754f1d560d5dbdcd85566107b6d2a2479982a08b81daeec8870c3fb125f4da9f3e5f5cf1b28ab70ce657909339e26c3d480
|
|
7
|
+
data.tar.gz: 02e090d85944b1dda4eadb8e500f838c0ca42a84e479127632571c45666a10be5d5d253549b9cdaa613c71b9c5d1ed42c0c3e37c02852685a627fc6a18ee0040
|
data/CHANGELOG.md
CHANGED
|
@@ -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
|
|
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.
|
|
143
|
-
[2.
|
|
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
|
data/bin/metrics-per-process.py
CHANGED
|
@@ -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
|
|
111
|
-
|
|
112
|
+
def additional_stats(process_handler, metrics_regexp):
|
|
113
|
+
stats = {}
|
|
112
114
|
|
|
113
|
-
|
|
115
|
+
if metrics_regexp.match('cpu.user'):
|
|
116
|
+
stats['cpu.user'] = process_handler.cpu_times().user
|
|
114
117
|
|
|
115
|
-
|
|
116
|
-
|
|
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
|
-
|
|
122
|
-
stats
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
stats
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
stats
|
|
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
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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
|
-
|
|
153
|
-
if
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
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()
|
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
|
+
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-
|
|
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.
|
|
239
|
+
rubygems_version: 2.6.13
|
|
240
240
|
signing_key:
|
|
241
241
|
specification_version: 4
|
|
242
242
|
summary: Sensu plugins for checking running processes
|