1414
1515from string import Template
1616
17- global url , descriptors , last_update , vhost , username , password , url_template , result , result_dict , keyToPath
17+ global descriptors , last_update , vhost , username , password , url_template , result , result_dict , keyToPath
1818
1919log = None
2020
2828keyToPath = {}
2929last_update = None
3030#last_update = {}
31- compiled_results = {"nodes" : None , "queues" : None , "connections" : None , "exchanges" : None }
31+ compiled_results = {"nodes" : None , "queues" : None , "connections" : None , "exchanges" : None , "overview" : None }
3232#Make initial stat test time dict
3333#for stat_type in ('queues', 'connections','exchanges', 'nodes'):
3434# last_update[stat_type] = None
9191
9292EXCHANGE_METRICS = ['rmq_exchange_publish_in_rate' , 'rmq_exchange_publish_out_rate' ]
9393
94+ keyToPath ['rmq_overview_message_stats_publish' ] = "message_stats{0}publish" .format (JSON_PATH_SEPARATOR )
95+ keyToPath ['rmq_overview_message_stats_ack' ] = "message_stats{0}ack" .format (JSON_PATH_SEPARATOR )
96+ keyToPath ['rmq_overview_message_stats_deliver_get' ] = "message_stats{0}deliver_get" .format (JSON_PATH_SEPARATOR )
97+ keyToPath ['rmq_overview_message_stats_deliver' ] = "message_stats{0}deliver" .format (JSON_PATH_SEPARATOR )
98+ keyToPath ['rmq_overview_message_stats_deliver_no_ack' ] = "message_stats{0}deliver_no_ack" .format (JSON_PATH_SEPARATOR )
99+ keyToPath ['rmq_overview_queue_totals_messages' ] = "queue_totals{0}messages" .format (JSON_PATH_SEPARATOR )
100+ keyToPath ['rmq_overview_queue_totals_messages_ready' ] = "queue_totals{0}messages_ready" .format (JSON_PATH_SEPARATOR )
101+ keyToPath ['rmq_overview_queue_totals_messages_unacknowledged' ] = "queue_totals{0}messages_unacknowledged" .format (JSON_PATH_SEPARATOR )
102+ keyToPath ['rmq_overview_object_totals_consumers' ] = "object_totals{0}consumers" .format (JSON_PATH_SEPARATOR )
103+ keyToPath ['rmq_overview_object_totals_queues' ] = "object_totals{0}queues" .format (JSON_PATH_SEPARATOR )
104+ keyToPath ['rmq_overview_object_totals_exchanges' ] = "object_totals{0}exchanges" .format (JSON_PATH_SEPARATOR )
105+ keyToPath ['rmq_overview_object_totals_connections' ] = "object_totals{0}connections" .format (JSON_PATH_SEPARATOR )
106+ keyToPath ['rmq_overview_object_totals_channels' ] = "object_totals{0}channels" .format (JSON_PATH_SEPARATOR )
107+
108+ OVERVIEW_METRICS = ['rmq_overview_message_stats_publish' , 'rmq_overview_message_stats_ack' , 'rmq_overview_message_stats_deliver_get' ,
109+ 'rmq_overview_message_stats_deliver' , 'rmq_overview_message_stats_deliver_no_ack' ,
110+ 'rmq_overview_queue_totals_messages' , 'rmq_overview_queue_totals_messages_ready' ,
111+ 'rmq_overview_queue_totals_messages_unacknowledged' , 'rmq_overview_object_totals_consumers' ,
112+ 'rmq_overview_object_totals_queues' , 'rmq_overview_object_totals_exchanges' ,
113+ 'rmq_overview_object_totals_connections' , 'rmq_overview_object_totals_channels' ]
94114
95115def dig_it_up (obj , path ):
96116 try :
@@ -103,9 +123,8 @@ def dig_it_up(obj, path):
103123 return False
104124
105125
106- def refreshStats (stats = ('nodes' , 'queues' ), vhosts = ['/' ]):
107- global url_template
108- global last_update , url , compiled_results
126+ def refreshStats (stats = ('nodes' , 'queues' , 'overview' ), vhosts = ['/' ]):
127+ global url_template , last_update
109128
110129 now = time .time ()
111130
@@ -119,10 +138,13 @@ def refreshStats(stats=('nodes', 'queues'), vhosts=['/']):
119138 last_update = now
120139 for stat in stats :
121140 for vhost in vhosts :
122- if stat in ('nodes' ):
141+ if stat in ('nodes' , 'overview' ):
123142 vhost = '/'
124143 result_dict = {}
125- urlstring = url_template .safe_substitute (stats = stat , vhost = vhost )
144+ if stat == 'overview' :
145+ urlstring = overview_url
146+ else :
147+ urlstring = url_template .safe_substitute (stats = stat , vhost = vhost )
126148 log .debug ('urlspring: %s' % urlstring )
127149 result = json .load (urllib2 .urlopen (urlstring ))
128150 # Rearrange results so entry is held in a dict keyed by name - queue name, host name, etc.
@@ -131,23 +153,16 @@ def refreshStats(stats=('nodes', 'queues'), vhosts=['/']):
131153 name = entry ['name' ]
132154 result_dict [name ] = entry
133155 compiled_results [(stat , vhost )] = result_dict
156+ elif stat in ("overview" ):
157+ compiled_results [(stat , vhost )] = result
134158
135159 return compiled_results
136160
137-
138- def validatedResult (value ):
139- if not isInstance (value , bool ):
140- return float (value )
141- else :
142- return None
143-
144-
145161def list_queues (vhost ):
146162 global compiled_results
147163 queues = compiled_results [('queues' , vhost )].keys ()
148164 return queues
149165
150-
151166def list_nodes ():
152167 global compiled_results
153168 nodes = compiled_results [('nodes' , '/' )].keys ()
@@ -159,7 +174,6 @@ def list_exchanges(vhost):
159174 exchanges = compiled_results [('exchanges' , vhost )].keys ()
160175 return exchanges
161176
162-
163177def getQueueStat (name ):
164178 refreshStats (stats = STATS , vhosts = vhosts )
165179 # Split a name like "rmq_backing_queue_ack_egress_rate.access"
@@ -206,6 +220,29 @@ def getNodeStat(name):
206220 return float (value )
207221
208222
223+ def getOverviewStat (name ):
224+ refreshStats (stats = STATS , vhosts = vhosts )
225+ # Split a name like "rmq_backing_queue_ack_egress_rate.access"
226+
227+ # handle queue names with . in them
228+
229+ log .debug (name )
230+ stat_name , vhost = name .split (METRIC_TOKEN_SEPARATOR )
231+
232+ vhost = vhost .replace ('-' , '/' ) # decoding vhost from metric name
233+ # Run refreshStats to get the result object
234+ result = compiled_results [('overview' , vhost )]
235+
236+ value = dig_it_up (result , keyToPath [stat_name ])
237+
238+ # Convert Booleans
239+ if value is True :
240+ value = 1
241+ elif value is False :
242+ value = 0
243+
244+ return float (value )
245+
209246def getExchangeStat (name ):
210247 refreshStats (stats = STATS , vhosts = vhosts )
211248 # Split a name like "rmq_backing_queue_ack_egress_rate.access"
@@ -254,7 +291,7 @@ def str2bool(string):
254291
255292def metric_init (params ):
256293 ''' Create the metric definition object '''
257- global descriptors , stats , vhost , username , password , urlstring , url_template , compiled_results , STATS , vhosts , zero_rates_when_idle
294+ global descriptors , stats , vhost , username , password , urlstring , url_template , overview_url , compiled_results , STATS , vhosts , zero_rates_when_idle
258295 if log is None :
259296 setup_logging ('syslog' , params ['syslog_facility' ], params ['log_level' ])
260297 log .info ('received the following params: %r' % params )
@@ -274,6 +311,7 @@ def metric_init(params):
274311 zero_rates_when_idle = str2bool (params ['zero_rates_when_idle' ])
275312
276313 url = 'http://%s:%s/api/$stats/$vhost' % (host , port )
314+ overview_url = 'http://%s:%s/api/overview' % (host , port )
277315 base_url = 'http://%s:%s/api' % (host , port )
278316 password_mgr = urllib2 .HTTPPasswordMgrWithDefaultRealm ()
279317 password_mgr .add_password (None , base_url , username , password )
@@ -357,12 +395,29 @@ def buildExchangeDescriptors():
357395 log .debug (d1 )
358396 descriptors .append (d1 )
359397
398+ def buildOverviewDescriptors ():
399+ for vhost , metric in product (vhosts , OVERVIEW_METRICS ):
400+ name = "{1}{0}{2}" .format (METRIC_TOKEN_SEPARATOR , metric , vhost .replace ('/' , '-' ))
401+ log .debug (name )
402+ d1 = create_desc ({'name' : name .encode ('ascii' , 'ignore' ),
403+ 'call_back' : getOverviewStat ,
404+ 'value_type' : 'float' ,
405+ 'units' : 'N' ,
406+ 'slope' : 'both' ,
407+ 'format' : '%f' ,
408+ 'description' : 'Overview_Metric' ,
409+ 'groups' : 'rabbitmq,overview' })
410+ log .debug (d1 )
411+ descriptors .append (d1 )
412+
360413 if 'queues' in STATS :
361414 buildQueueDescriptors ()
362415 if 'nodes' in STATS :
363416 buildNodeDescriptors ()
364417 if 'exchanges' in STATS :
365418 buildExchangeDescriptors ()
419+ if 'overview' in STATS :
420+ buildOverviewDescriptors ()
366421 # buildTestNodeStat()
367422
368423 return descriptors
@@ -397,15 +452,21 @@ def setup_logging(handlers, facility, level):
397452
398453def parse_args (argv ):
399454 parser = optparse .OptionParser ()
455+ parser .add_option ('--username' ,
456+ action = 'store' , dest = 'username' , default = 'username' ,
457+ help = '' )
458+ parser .add_option ('--password' ,
459+ action = 'store' , dest = 'password' , default = 'password' ,
460+ help = '' )
400461 parser .add_option ('--admin-host' ,
401462 action = 'store' , dest = 'admin_host' , default = 'localhost' ,
402463 help = '' )
403464 parser .add_option ('--admin-port' ,
404465 action = 'store' , dest = 'admin_port' , default = 15672 ,
405466 help = '' )
406467 parser .add_option ('--stats' ,
407- action = 'store' , dest = 'stats' , default = 'nodes,queues,exchanges' ,
408- help = 'csv of which stats to emit, choies: nodes, queues' )
468+ action = 'store' , dest = 'stats' , default = 'nodes,queues,exchanges,overview ' ,
469+ help = 'csv of which stats to emit, choies: nodes, queues, exchanges, overview ' )
409470 parser .add_option ('--vhosts' ,
410471 action = 'store' , dest = 'vhosts' , default = '/' ,
411472 help = 'csv of vhosts' )
@@ -431,7 +492,7 @@ def main(argv):
431492 (opts , args ) = parse_args (argv )
432493 setup_logging (opts .log , opts .log_facility , opts .log_level )
433494 # in config files we use '/' in vhosts names but we should convert '/' to '-' when calculating a metric
434- parameters = {"vhost" : "/" , "username" : "guest" , "password" : "guest" , "metric_group" : "rabbitmq" ,
495+ parameters = {"vhost" : "/" , "username" : opts . username , "password" : opts . password , "metric_group" : "rabbitmq" ,
435496 "zero_rates_when_idle" : "yes" ,
436497 "host" : opts .admin_host , "port" : opts .admin_port ,
437498 "stats" : opts .stats .split (',' ),
0 commit comments