sensu-plugins-process-checks 0.0.5 → 0.0.6
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
- checksums.yaml.gz.sig +1 -2
- data.tar.gz.sig +2 -1
- data/CHANGELOG.md +8 -1
- data/bin/metrics-per-process.py +220 -0
- data/bin/metrics-processes-threads-count.rb +1 -0
- data/lib/sensu-plugins-process-checks/version.rb +1 -1
- metadata +3 -2
- metadata.gz.sig +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d660f3baaa8a58c1e650df9362856dfae1f9ba6d
|
4
|
+
data.tar.gz: 51a2c180c7739e02928afc398aa9b02e140538a2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6d616ff7316378223b2886efb642cc0b82f68ed3d5891d4712e581bc524e0fe9069e940a71859a9a2d80df690695f174a723867c0e2e6d007e24dc578322b63b
|
7
|
+
data.tar.gz: 46aa8151e54b798bb722d81e00db1d74a1ee5c118520d78fc472ddd07c75c1f042de2712ff278d3a1f569bfa6687186f864826abdd2df132566f684564db484c
|
checksums.yaml.gz.sig
CHANGED
@@ -1,2 +1 @@
|
|
1
|
-
|
2
|
-
����Z�ì�C�Z��D����[Q�i��^�5:��sJ���U7R/�w_E��f��t�N�h�d�Uv\��������lKy�[�R{ĪVu�94x>y�,�eZ<ԄF�j!�K�>4��ͳy�����ʅ���c�~P�8�ʆ�C-��'���ZJ,�.:�����LV{@�28��k����X北�E' ��Q��Wn���|禱V�Z�
|
1
|
+
N,%H���ڝ��.`����,�� �(z�ʗ��C`C�����^;W$���~�oe��n���H�W�e�PP^Fx�v�2q:�UΎ�2J�ؚ�d�� ��Yf� �`n�jL3,䛬����+.ꙧ 8�/�c����Q�'\W���#�V�ñ߂b�����\͉��ģ(]�@�e�t�ih��ב��-����2�F�Iܠ�Lr �\�OO�D|
|
data.tar.gz.sig
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
|
1
|
+
'�A媛��v�F�&Y1�m"�
|
2
|
+
���q��U]#����Y��{D$�H�����
|
data/CHANGELOG.md
CHANGED
@@ -4,7 +4,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|
4
4
|
This CHANGELOG follows the format listed at [Keep A Changelog](http://keepachangelog.com/)
|
5
5
|
|
6
6
|
## Unreleased
|
7
|
-
|
7
|
+
|
8
|
+
## [0.0.6] - 2015-08-24
|
9
|
+
### Fixed
|
10
|
+
- require 'socket' in metrics-processes-threads-count
|
8
11
|
|
9
12
|
## [0.0.5] - 2015-07-14
|
10
13
|
### Fixed
|
@@ -13,6 +16,10 @@ This CHANGELOG follows the format listed at [Keep A Changelog](http://keepachang
|
|
13
16
|
### Changed
|
14
17
|
rename process-uptime metrics.sh -> metrics-process-uptime.sh
|
15
18
|
|
19
|
+
## [0.1.0] - 2015-08-11
|
20
|
+
### Added
|
21
|
+
- Add metrics-per-process.py plugin (require python psutil module)
|
22
|
+
|
16
23
|
## [0.0.4] - 2015-07-14
|
17
24
|
### Changed
|
18
25
|
- updated sensu-plugin gem to 1.2.0
|
@@ -0,0 +1,220 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
#
|
3
|
+
# metrics-per-process.py
|
4
|
+
#
|
5
|
+
# DESCRIPTION:
|
6
|
+
#
|
7
|
+
# OUTPUT:
|
8
|
+
# graphite plain text protocol
|
9
|
+
#
|
10
|
+
# PLATFORMS:
|
11
|
+
# Linux
|
12
|
+
#
|
13
|
+
# DEPENDENCIES:
|
14
|
+
# Python 2.7+ (untested on Python3, should work though)
|
15
|
+
# Python module: psutil https://pypi.python.org/pypi/psutil
|
16
|
+
#
|
17
|
+
# USAGE:
|
18
|
+
#
|
19
|
+
# metrics-per-process.py -n <process_name> | -p <path_to_process_pid_file> [-s <graphite_scheme>]
|
20
|
+
#
|
21
|
+
# NOTES:
|
22
|
+
# The plugin requires to read files in the /proc file system, make sure the owner
|
23
|
+
# of the sensu-client process can read /proc/<PIDS>/*
|
24
|
+
# When using a pid file make sure the owner of the sensu-client process can read
|
25
|
+
# it, normally a pid file lives in /var/run/ and only contains the process ID
|
26
|
+
#
|
27
|
+
# It gets extended stats (mem, cpu, threads, file descriptors, connections,
|
28
|
+
# i/o counters) from a process name or a process PID file path. If a process
|
29
|
+
# name is provided and multiple processes are running with that name then the
|
30
|
+
# stats are a sum of all the process with that name. When providing a PID file
|
31
|
+
# then a single process is being instrumented
|
32
|
+
|
33
|
+
# Sample output using sshd
|
34
|
+
#
|
35
|
+
# Using sshd as a process name (which finds all processes answering to name
|
36
|
+
# 'sshd' in /proc/<PIDS>/comm and then summing the stats)
|
37
|
+
#
|
38
|
+
# per_process_stats.io_counters.read_count 63513 1439159262
|
39
|
+
# per_process_stats.conns.tcp.total 10 1439159262
|
40
|
+
# per_process_stats.ctx_switches.voluntary 22171 1439159262
|
41
|
+
# per_process_stats.ctx_switches.involuntary 8631 1439159262
|
42
|
+
# per_process_stats.io_counters.write_bytes 212992 1439159262
|
43
|
+
# per_process_stats.memory.shared 20590592 1439159262
|
44
|
+
# per_process_stats.conns.unix_sockets.total 20 1439159262
|
45
|
+
# per_process_stats.memory.percent 0.478190140105 1439159262
|
46
|
+
# per_process_stats.memory.text 6746112 1439159262
|
47
|
+
# per_process_stats.memory.rss 29450240 1439159262
|
48
|
+
# per_process_stats.cpu.user 2.38 1439159262
|
49
|
+
# per_process_stats.fds 89 1439159262
|
50
|
+
# per_process_stats.memory.vms 945082368 1439159262
|
51
|
+
# per_process_stats.threads 9 1439159262
|
52
|
+
# per_process_stats.conns.tcp.established 8 1439159262
|
53
|
+
# per_process_stats.total_processes 9 1439159262
|
54
|
+
# per_process_stats.conns.tcp.listen 2 1439159262
|
55
|
+
# per_process_stats.cpu.system 3.8 1439159262
|
56
|
+
# per_process_stats.io_counters.write_count 24409 1439159262
|
57
|
+
# per_process_stats.io_counters.read_bytes 7811072 1439159262
|
58
|
+
# per_process_stats.memory.data 7778304 1439159262
|
59
|
+
#
|
60
|
+
# LICENSE:
|
61
|
+
# Jaime Gago contact@jaimegago.com
|
62
|
+
# Released under the same terms as Sensu (the MIT license); see LICENSE
|
63
|
+
# for details.
|
64
|
+
#
|
65
|
+
|
66
|
+
import os
|
67
|
+
import optparse
|
68
|
+
import psutil
|
69
|
+
import sys
|
70
|
+
import time
|
71
|
+
from collections import Counter
|
72
|
+
|
73
|
+
|
74
|
+
PROC_ROOT_DIR = '/proc/'
|
75
|
+
TCP_CONN_STATUSES = [
|
76
|
+
'ESTABLISHED',
|
77
|
+
'SYN_SENT',
|
78
|
+
'SYN_RECV',
|
79
|
+
'FIN_WAIT1',
|
80
|
+
'FIN_WAIT2',
|
81
|
+
'TIME_WAIT',
|
82
|
+
'CLOSE',
|
83
|
+
'CLOSE_WAIT',
|
84
|
+
'LAST_ACK',
|
85
|
+
'LISTEN',
|
86
|
+
'CLOSING',
|
87
|
+
'NONE'
|
88
|
+
]
|
89
|
+
|
90
|
+
def find_pids_from_name(process_name):
|
91
|
+
'''Find process PID from name using /proc/<pids>/comm'''
|
92
|
+
|
93
|
+
pids_in_proc = [ pid for pid in os.listdir(PROC_ROOT_DIR) if pid.isdigit() ]
|
94
|
+
pids = []
|
95
|
+
for pid in pids_in_proc:
|
96
|
+
path = PROC_ROOT_DIR + pid
|
97
|
+
if 'comm' in os.listdir(path):
|
98
|
+
file_handler = open(path + '/comm', 'r')
|
99
|
+
if file_handler.read().rstrip() == process_name:
|
100
|
+
pids.append(int(pid))
|
101
|
+
return pids
|
102
|
+
|
103
|
+
def stats_per_pid(pid):
|
104
|
+
'''Gets process stats using psutil module
|
105
|
+
|
106
|
+
details at http://pythonhosted.org/psutil/#process-class'''
|
107
|
+
|
108
|
+
stats = {}
|
109
|
+
process_handler = psutil.Process(pid)
|
110
|
+
stats['cpu.user'] = process_handler.cpu_times().user
|
111
|
+
stats['cpu.system'] = process_handler.cpu_times().system
|
112
|
+
stats['cpu.percent'] = process_handler.cpu_percent()
|
113
|
+
stats['threads'] = process_handler.num_threads()
|
114
|
+
stats['memory.rss'] = process_handler.memory_info_ex().rss
|
115
|
+
stats['memory.vms'] = process_handler.memory_info_ex().vms
|
116
|
+
stats['memory.shared'] = process_handler.memory_info_ex().shared
|
117
|
+
stats['memory.text'] = process_handler.memory_info_ex().text
|
118
|
+
stats['memory.lib'] = process_handler.memory_info_ex().lib
|
119
|
+
stats['memory.data'] = process_handler.memory_info_ex().data
|
120
|
+
stats['memory.dirty'] = process_handler.memory_info_ex().dirty
|
121
|
+
stats['memory.percent'] = process_handler.memory_percent()
|
122
|
+
stats['fds'] = process_handler.num_fds()
|
123
|
+
stats['ctx_switches.voluntary'] = process_handler.num_ctx_switches().voluntary
|
124
|
+
stats['ctx_switches.involuntary'] = process_handler.num_ctx_switches().involuntary
|
125
|
+
stats['io_counters.read_count'] = process_handler.io_counters().read_count
|
126
|
+
stats['io_counters.write_count'] = process_handler.io_counters().write_count
|
127
|
+
stats['io_counters.read_bytes'] = process_handler.io_counters().read_bytes
|
128
|
+
stats['io_counters.write_bytes'] = process_handler.io_counters().write_bytes
|
129
|
+
# TCP/UDP/Unix Socket Connections
|
130
|
+
tcp_conns = process_handler.connections(kind='tcp')
|
131
|
+
if tcp_conns:
|
132
|
+
stats['conns.tcp.total'] = len(tcp_conns)
|
133
|
+
tcp_conns_count = {}
|
134
|
+
for tcp_status in TCP_CONN_STATUSES:
|
135
|
+
tcp_conns_count['conns.tcp.' + tcp_status.lower()] = 0
|
136
|
+
for conn in tcp_conns:
|
137
|
+
if conn.status == tcp_status:
|
138
|
+
tcp_conns_count['conns.tcp.' + tcp_status.lower()] = tcp_conns_count[
|
139
|
+
'conns.tcp.' + tcp_status.lower()] + 1
|
140
|
+
stats.update(tcp_conns_count)
|
141
|
+
udp_conns = process_handler.connections(kind='udp')
|
142
|
+
if udp_conns:
|
143
|
+
stats['conns.udp.total'] = len(udp_conns)
|
144
|
+
unix_conns = process_handler.connections(kind='unix')
|
145
|
+
if unix_conns:
|
146
|
+
stats['conns.unix_sockets.total'] = len(unix_conns)
|
147
|
+
return stats
|
148
|
+
|
149
|
+
def multi_pid_process_stats(pids):
|
150
|
+
stats = {'total_processes': len(pids)}
|
151
|
+
for pid in pids:
|
152
|
+
stats = Counter(stats) + Counter(stats_per_pid(pid))
|
153
|
+
return stats
|
154
|
+
|
155
|
+
def recursive_dict_sum(dictionnary):
|
156
|
+
sum_dict = Counter(dictionnary) + Counter(dictionnary)
|
157
|
+
recursive_dict_sum(sum_dict)
|
158
|
+
return sum_dict
|
159
|
+
|
160
|
+
def graphite_printer(stats, graphite_scheme):
|
161
|
+
now = time.time()
|
162
|
+
for stat in stats:
|
163
|
+
print "%s.%s %s %d" % (graphite_scheme, stat, stats[stat], now)
|
164
|
+
|
165
|
+
def get_pid_from_pid_file(pid_file):
|
166
|
+
try:
|
167
|
+
file_handler = open(pid_file, 'r')
|
168
|
+
except Exception as e:
|
169
|
+
print 'could not read: %s' % pid_file
|
170
|
+
print e
|
171
|
+
sys.exit(1)
|
172
|
+
try:
|
173
|
+
pid = [].append(int(file_handler.read().rstrip()))
|
174
|
+
except Exception as e:
|
175
|
+
print 'It seems file : %s, does not use standard pid file convention' % pid_file
|
176
|
+
print 'Pid file typically just contains the PID of the process'
|
177
|
+
print e
|
178
|
+
sys.exit(1)
|
179
|
+
return pid
|
180
|
+
|
181
|
+
def main():
|
182
|
+
parser = optparse.OptionParser()
|
183
|
+
|
184
|
+
parser.add_option('-n', '--process-name',
|
185
|
+
help = 'name of process to collect stats (imcompatible with -p)',
|
186
|
+
dest = 'process_name',
|
187
|
+
metavar = 'PROCESS_NAME')
|
188
|
+
|
189
|
+
parser.add_option('-p', '--pid-file',
|
190
|
+
help = 'path to pid file for process to collect stats (imcompatible with -n)',
|
191
|
+
dest = 'process_pid_file',
|
192
|
+
metavar = 'PROCESS_PID_FILE')
|
193
|
+
|
194
|
+
parser.add_option('-s', '--graphite_scheme',
|
195
|
+
help = 'graphite scheme to prepend, default to <process_stats>',
|
196
|
+
default = 'per_process_stats',
|
197
|
+
dest = 'graphite_scheme',
|
198
|
+
metavar = 'GRAPHITE_SCHEME')
|
199
|
+
|
200
|
+
(options, args) = parser.parse_args()
|
201
|
+
|
202
|
+
if options.process_name and options.process_pid_file:
|
203
|
+
print 'Specify a process name or a process pid file path, but not both'
|
204
|
+
sys.exit(1)
|
205
|
+
|
206
|
+
if not options.process_name and not options.process_pid_file:
|
207
|
+
print 'A process name or a process pid file path is needed'
|
208
|
+
sys.exit(1)
|
209
|
+
|
210
|
+
if options.process_name:
|
211
|
+
pids = find_pids_from_name(options.process_name)
|
212
|
+
graphite_printer(multi_pid_process_stats(pids), options.graphite_scheme)
|
213
|
+
|
214
|
+
if options.process_pid_file:
|
215
|
+
pid = get_pid_from_pid_file(options.process_pid_file)
|
216
|
+
graphite_printer(stats_per_pid(pid), options.graphite_scheme)
|
217
|
+
#
|
218
|
+
if __name__ == '__main__':
|
219
|
+
main()
|
220
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sensu-plugins-process-checks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sensu-Plugins and contributors
|
@@ -30,7 +30,7 @@ cert_chain:
|
|
30
30
|
8sHuVruarogxxKPBzlL2is4EUb6oN/RdpGx2l4254+nyR+abg//Ed27Ym0PkB4lk
|
31
31
|
HP0m8WSjZmFr109pE/sVsM5jtOCvogyujQOjNVGN4gz1wwPr
|
32
32
|
-----END CERTIFICATE-----
|
33
|
-
date: 2015-08-
|
33
|
+
date: 2015-08-27 00:00:00.000000000 Z
|
34
34
|
dependencies:
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
name: english
|
@@ -219,6 +219,7 @@ files:
|
|
219
219
|
- bin/check-process-restart.rb
|
220
220
|
- bin/check-process.rb
|
221
221
|
- bin/check-threads-count.rb
|
222
|
+
- bin/metrics-per-process.py
|
222
223
|
- bin/metrics-process-status.rb
|
223
224
|
- bin/metrics-process-uptime.sh
|
224
225
|
- bin/metrics-processes-threads-count.rb
|
metadata.gz.sig
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
|
1
|
+
dY#)�+�ɾQ��!G���B��˰
|
2
|
+
�hxW,ǃ���ͬ�������=��ó�f��Ȟ����i%ՆW���Cy�s�_�fWqU�
|