66# all of the legacy compatibility, and favors metrics from SHOW GLOBAL STATUS
77# as opposed to SHOW ENGINE INNODB STATUS where possible.
88#
9- # Configuration:
9+ # Configuration (repeat Module section for multiple instances) :
1010# Import mysql
1111# <Module mysql>
1212# Host localhost
3737 COLLECTD_ENABLED = False
3838import re
3939import MySQLdb
40+ import copy
4041
41- MYSQL_CONFIG = {
42- 'Host' : 'localhost' ,
43- 'Port' : 3306 ,
44- 'User' : 'root' ,
45- 'Password' : '' ,
46- 'HeartbeatTable' : '' ,
47- 'Verbose' : False ,
48- 'Instance' : '' ,
49- }
42+
43+ # Verbose logging on/off. Override in config by specifying 'Verbose'.
44+ VERBOSE_LOGGING = False
45+
46+ CONFIGS = []
5047
5148MYSQL_STATUS_VARS = {
5249 'Aborted_clients' : 'counter' ,
311308 },
312309}
313310
314- def get_mysql_conn ():
311+ def get_mysql_conn (conf ):
315312 return MySQLdb .connect (
316- host = MYSQL_CONFIG [ 'Host ' ],
317- port = MYSQL_CONFIG [ 'Port ' ],
318- user = MYSQL_CONFIG [ 'User ' ],
319- passwd = MYSQL_CONFIG [ 'Password ' ]
313+ host = conf [ 'host ' ],
314+ port = conf [ 'port ' ],
315+ user = conf [ 'user ' ],
316+ passwd = conf [ 'password ' ]
320317 )
321318
322319def mysql_query (conn , query ):
@@ -358,7 +355,7 @@ def fetch_mysql_master_stats(conn):
358355
359356 return stats
360357
361- def fetch_mysql_slave_stats (conn ):
358+ def fetch_mysql_slave_stats (conf , conn ):
362359 result = mysql_query (conn , 'SHOW SLAVE STATUS' )
363360 slave_row = result .fetchone ()
364361 if slave_row is None :
@@ -370,12 +367,12 @@ def fetch_mysql_slave_stats(conn):
370367 'slave_lag' : slave_row ['Seconds_Behind_Master' ] if slave_row ['Seconds_Behind_Master' ] != None else 0 ,
371368 }
372369
373- if MYSQL_CONFIG [ 'HeartbeatTable ' ]:
370+ if conf [ 'heartbeattable ' ]:
374371 query = """
375372 SELECT MAX(UNIX_TIMESTAMP() - UNIX_TIMESTAMP(ts)) AS delay
376373 FROM %s
377374 WHERE server_id = %s
378- """ % (MYSQL_CONFIG [ 'HeartbeatTable ' ], slave_row ['Master_Server_Id' ])
375+ """ % (conf [ 'heartbeattable ' ], slave_row ['Master_Server_Id' ])
379376 result = mysql_query (conn , query )
380377 row = result .fetchone ()
381378 if 'delay' in row and row ['delay' ] != None :
@@ -482,14 +479,14 @@ def fetch_innodb_stats(conn):
482479 return stats
483480
484481def log_verbose (msg ):
485- if not MYSQL_CONFIG [ 'Verbose' ] :
482+ if not VERBOSE_LOGGING :
486483 return
487484 if COLLECTD_ENABLED :
488485 collectd .info ('mysql plugin: %s' % msg )
489486 else :
490487 print ('mysql plugin: %s' % msg )
491488
492- def dispatch_value (prefix , key , value , type , type_instance = None ):
489+ def dispatch_value (instance , prefix , key , value , type , type_instance = None ):
493490 if not type_instance :
494491 type_instance = key
495492
@@ -500,8 +497,12 @@ def dispatch_value(prefix, key, value, type, type_instance=None):
500497 if not COLLECTD_ENABLED :
501498 return
502499
500+ if instance is None :
501+ plugin = 'mysql'
502+ else :
503+ plugin = 'mysql.%s' % instance
503504 value = int (value ) # safety check
504- val = collectd .Values (plugin = 'mysql' , plugin_instance = prefix )
505+ val = collectd .Values (plugin = plugin , plugin_instance = prefix )
505506 val .plugin = 'mysql.%s' % MYSQL_CONFIG ['Instance' ]
506507 val .plugin_instance = prefix
507508 val .type = type
@@ -510,17 +511,50 @@ def dispatch_value(prefix, key, value, type, type_instance=None):
510511 val .dispatch ()
511512
512513def configure_callback (conf ):
513- global MYSQL_CONFIG
514+ instance = None
515+ host = 'localhost'
516+ port = 3306
517+ user = 'root'
518+ password = ''
519+ heartbeattable = ''
520+ verbose = False
521+
514522 for node in conf .children :
515- if node .key in MYSQL_CONFIG :
516- MYSQL_CONFIG [node .key ] = node .values [0 ]
523+ key = node .key .lower ()
524+ val = node .values [0 ]
525+ if key == 'instance' :
526+ instance = val
527+ elif key == 'host' :
528+ host = val
529+ elif key == 'port' :
530+ port = int (val )
531+ elif key == 'user' :
532+ user = val
533+ elif key == 'password' :
534+ password = val
535+ elif key == 'heartbeattable' :
536+ heartbeattable = val
537+ elif key == 'verbose' :
538+ global VERBOSE_LOGGING
539+ VERBOSE_LOGGING = bool (val ) or VERBOSE_LOGGING
540+ else :
541+ collectd .warning ('mysql plugin: Unknown config key: %s.' % key )
517542
518- MYSQL_CONFIG ['Port' ] = int (MYSQL_CONFIG ['Port' ])
519- MYSQL_CONFIG ['Verbose' ] = bool (MYSQL_CONFIG ['Verbose' ])
543+ log_verbose ('Configured with host=%s, port=%s, instance name=%s, user=%s' % ( host , port , instance , user ))
520544
521- def read_callback ():
545+ mysql_config = {
546+ 'instance' : instance ,
547+ 'host' : host ,
548+ 'port' : port ,
549+ 'user' : user ,
550+ 'password' : password ,
551+ 'heartbeattable' : heartbeattable
552+ }
553+ CONFIGS .append (mysql_config )
554+
555+ def get_metrics (conf ):
522556 global MYSQL_STATUS_VARS
523- conn = get_mysql_conn ()
557+ conn = get_mysql_conn (conf )
524558
525559 mysql_status = fetch_mysql_status (conn )
526560 for key in mysql_status :
@@ -536,48 +570,56 @@ def read_callback():
536570 else :
537571 continue
538572
539- dispatch_value ('status' , key , mysql_status [key ], ds_type )
573+ dispatch_value (conf [ 'instance' ], 'status' , key , mysql_status [key ], ds_type )
540574
541575 mysql_variables = fetch_mysql_variables (conn )
542576 for key in mysql_variables :
543- dispatch_value ('variables' , key , mysql_variables [key ], 'gauge' )
577+ dispatch_value (conf [ 'instance' ], 'variables' , key , mysql_variables [key ], 'gauge' )
544578
545579 mysql_master_status = fetch_mysql_master_stats (conn )
546580 for key in mysql_master_status :
547- dispatch_value ('master' , key , mysql_master_status [key ], 'gauge' )
581+ dispatch_value (conf [ 'instance' ], 'master' , key , mysql_master_status [key ], 'gauge' )
548582
549583 mysql_states = fetch_mysql_process_states (conn )
550584 for key in mysql_states :
551- dispatch_value ('state' , key , mysql_states [key ], 'gauge' )
585+ dispatch_value (conf [ 'instance' ], 'state' , key , mysql_states [key ], 'gauge' )
552586
553- slave_status = fetch_mysql_slave_stats (conn )
587+ slave_status = fetch_mysql_slave_stats (conf , conn )
554588 for key in slave_status :
555- dispatch_value ('slave' , key , slave_status [key ], 'gauge' )
589+ dispatch_value (conf [ 'instance' ], 'slave' , key , slave_status [key ], 'gauge' )
556590
557591 response_times = fetch_mysql_response_times (conn )
558592 for key in response_times :
559- dispatch_value ('response_time_total' , str (key ), response_times [key ]['total' ], 'counter' )
560- dispatch_value ('response_time_count' , str (key ), response_times [key ]['count' ], 'counter' )
593+ dispatch_value (conf [ 'instance' ], 'response_time_total' , str (key ), response_times [key ]['total' ], 'counter' )
594+ dispatch_value (conf [ 'instance' ], 'response_time_count' , str (key ), response_times [key ]['count' ], 'counter' )
561595
562596 innodb_status = fetch_innodb_stats (conn )
563597 for key in MYSQL_INNODB_STATUS_VARS :
564598 if key not in innodb_status : continue
565- dispatch_value ('innodb' , key , innodb_status [key ], MYSQL_INNODB_STATUS_VARS [key ])
599+ dispatch_value (conf ['instance' ], 'innodb' , key , innodb_status [key ], MYSQL_INNODB_STATUS_VARS [key ])
600+
601+ def read_callback ():
602+ for conf in CONFIGS :
603+ get_metrics (conf )
566604
567605if COLLECTD_ENABLED :
568606 collectd .register_read (read_callback )
569607 collectd .register_config (configure_callback )
570608
571609if __name__ == "__main__" and not COLLECTD_ENABLED :
572610 print "Running in test mode, invoke with"
573- print sys .argv [0 ] + " Host Port User Password "
574- MYSQL_CONFIG ['Host' ] = sys .argv [1 ]
575- MYSQL_CONFIG ['Port' ] = int (sys .argv [2 ])
576- MYSQL_CONFIG ['User' ] = sys .argv [3 ]
577- MYSQL_CONFIG ['Password' ] = sys .argv [4 ]
578- MYSQL_CONFIG ['Verbose' ] = True
611+ print sys .argv [0 ] + " Host Port User Password Instance"
612+ mysql_config = {}
613+ mysql_config ['host' ] = sys .argv [1 ]
614+ mysql_config ['heartbeattable' ] = ''
615+ mysql_config ['instance' ] = 'slave' if sys .argv .count < 6 else sys .argv [5 ]
616+ mysql_config ['port' ] = int (sys .argv [2 ])
617+ mysql_config ['user' ] = sys .argv [3 ]
618+ mysql_config ['password' ] = sys .argv [4 ]
619+ mysql_config ['verbose' ] = VERBOSE_LOGGING = True
579620 from pprint import pprint as pp
580- pp (MYSQL_CONFIG )
621+ pp (mysql_config )
622+ CONFIGS .append (mysql_config )
581623 read_callback ()
582624
583625
0 commit comments