-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathspectrum2_
executable file
·255 lines (234 loc) · 7.64 KB
/
spectrum2_
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# NOTE: This plugin is a direct copy of
# https://github.com/hanzz/libtransport/blob/master/munin/spectrum2_
# Although this plugin lists me, Mathias Ertl <[email protected]>, as author, this
# is a copy-paste error. I authored the plugin for spectrum1.
#
# Wildcard-plugin to monitor spectrum transport usage through an XMPP-connection
# sending Statistics Gathering (XEP-0039 [1]) packets. Depending on the suffix,
# the plugin monitors one specific characteristic of one or more spectrum
# instances.
#
# Current suffixes are:
# spectrum_uptime (monitor uptime of transports)
# spectrum_registered (how many users are registered to the transport)
# spectrum_online (how many users are online)
# spectarm_contacts_registered
# spectrum_contacts_online (same as above, only for the legacy network)
# spectrum_messages (how many messages have been sent over this transport)
# spectrum_memory (how much memory the transport consumes)
#
# Configuration:
# You need to configure this plugin (just like any other plugin) in
# plugin-conf.d/munin-node.
# You have to configure the plugin to run as user and group "spectrum".
#
# By default, the plugin monitors all instances configured in a config-file
# in /etc/spectrum2/transports. If you do not want to monitor all instances,
# you can give an explicit listing of the corresponding instances
# with the environment variable "jids".
#
# Here is an example of a configuration. Note again that you can ommit both
# env.cfgs and env.base:
#
# [spectrum_*]
# user spectrum
# group spectrum
# env.jids xmpp.example.com,irc.example.com
#
# Author:
# Mathias Ertl <[email protected]>
#
# Changelog:
# 2.0: Port to config_interface local socket
# 1.1: Suffixes that aggregate multiple values no longer show the individual
# values by default. This can be overridden by setting the "verbose"
# env-variable to any non-empty string.
# 1.0: Initial version
#
# [1] http://xmpp.org/extensions/xep-0039.html
#
# Copyright (c) 2009 Mathias Ertl.
#
# Permission to use, copy, and modify this software with or without fee
# is hereby granted, provided that this entire notice is included in
# all source code copies of any software which is or includes a copy or
# modification of this software.
#
# THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
# IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
# REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
# MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
# PURPOSE.
#
# Magic markers
#%# family=auto
#%# capabilities=autoconf suggest
import sys
from subprocess import *
# autoconf and suggest handling:
if len( sys.argv ) > 1:
if sys.argv[1] == 'autoconf':
print( 'yes' )
sys.exit( 0 )
elif sys.argv[1] == 'suggest':
print( """uptime
registered
online
contacts_total
contacts_online
messages
messages_sec
memory""" )
sys.exit(0)
import os, re
# filter forbidden characters for munin fieldnames
def handle_field( string ):
for regexp in [ '^[^A-Za-z_]', '[^A-Za-z0-9_]' ]:
string = re.compile( regexp ).sub( '_', string )
return string
# get runtime variables
suffix = sys.argv[0].partition('_')[2]
verbose = os.environ.get( 'verbose' )
jids = []
base = os.environ.get( 'base', '/etc/spectrum' )
if 'jids' in os.environ.keys():
jids = os.environ.get( 'jids' ).split(',')
else:
proc = Popen(['spectrum2_manager', 'list'], text=True, stdout=PIPE, stderr=PIPE)
out, err = proc.communicate()
jids = out.split('\n')[:-1]
# set variables based on wildcard
if suffix == 'uptime':
stat = { 'uptime': None }
title = "Uptime"
vlabel = "days"
info = ''
transformer = lambda value: float(value)/60.0/60.0/24.0
elif suffix == 'backends_count':
stat = { "backends_count": None }
title = "Backends count"
vlabel = "backends"
info = 'Total number of backends.'
elif suffix == 'crashed_backends_count':
stat = { "crashed_backends_count": None }
title = "Crashed backends count"
vlabel = "backends"
info = 'Total number of backends.'
elif suffix == 'online':
stat = { 'online_users_count': None }
title = "Online users"
vlabel = "users"
info = 'Number of users that currently use the spectrum transports.'
elif suffix == 'messages':
stat = { 'messages_from_xmpp': 'from_xmpp', 'messages_to_xmpp': 'to_xmpp' }
title = "Messages send over transport"
vlabel = "messages"
info = 'Total messages send over spectrum since the last restart.'
elif suffix == 'messages_sec':
stat = { 'messages_from_xmpp': 'from_xmpp', 'messages_to_xmpp': 'to_xmpp' }
title = "Messages send over transport per second"
vlabel = "messages/sec"
info = 'Messages send per second over spectrum transports.'
elif suffix == 'memory':
stat = { 'used_memory': None }
title = "Memory usage of transports"
vlabel = "megabytes"
transformer = lambda value: float(value)/1024.0
info = 'Memory usage of spectrum transports.'
elif suffix == 'average_memory_per_user':
stat = { 'average_memory_per_user': None }
title = "Average memory usage per user"
vlabel = "kilobytes"
#transformer = lambda value: float(value)/1024.0
info = 'Memory usage of spectrum transports.'
# handle config
if len( sys.argv ) > 1 and sys.argv[1] == 'config':
print( """graph_title %s
graph_args --base 1000 -l 0
graph_scale no
graph_vlabel %s
graph_category spectrum2
graph_info %s""" %(title, vlabel, info) )
for jid in jids:
if len(stat) > 1:
# plugin monitors more than one field
label = jid + ' total'
fieldname = handle_field( label )
print( '%s.label %s' %(fieldname, label) )
if suffix == 'messages_sec':
print( '%s.type DERIVE' %(fieldname) )
print( '%s.min 0' %(fieldname) )
# to not print individual fields if verbose is not set:
if not verbose:
continue
for name, field_suffix in stat.iteritems():
label = jid
if field_suffix:
label += ' ' + field_suffix
fieldname = handle_field( label )
print( '%s.label %s' %(fieldname, label) )
if suffix == 'messages_sec':
print( '%s.type DERIVE' %(fieldname) )
print( '%s.min 0' %(fieldname) )
sys.exit(0)
# callback to handle incoming packets
def handler_fetch( packet ):
jid = str( packet.getFrom() )
total = None
for child in packet.getChildren()[0].getChildren():
label = jid
value = child.getAttr( 'value' )
if len( stat ) > 1:
if total == None:
total = int( value )
else:
total += int( value )
if not verbose:
continue
field_suffix = stat[ child.getAttr( 'name' ) ]
if field_suffix:
label += ' ' + field_suffix
fieldname = handle_field( label )
if 'transformer' in globals():
value = transformer(value)
print( '%s.value %s' %(fieldname, value) )
if total != None:
fieldname = handle_field( jid + ' total' )
if 'transformer' in globals():
total = transformer( total )
print( '%s.value %s' %(fieldname, total) )
for jid in jids:
total = None
label = jid
for name in stat.keys():
proc = Popen(['spectrum2_manager', jid, name], text=True, stdout=PIPE, stderr=PIPE)
out, err = proc.communicate()
out = out.replace('\n', '')
value = 0
try:
value = int(out)
except:
print( "Error: %s" % (value))
continue
if len( stat ) > 1:
if total == None:
total = int( value )
else:
total += int( value )
if not verbose:
continue
field_suffix = stat[ name ]
if field_suffix:
label += ' ' + field_suffix
fieldname = handle_field( label )
if 'transformer' in globals():
value = transformer(value)
print( '%s.value %s' %(fieldname, value) )
if total != None:
fieldname = handle_field( jid + ' total' )
if 'transformer' in globals():
total = transformer( total )
print( '%s.value %s' %(fieldname, total) )