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
2929import collectd
3030import re
3131import MySQLdb
32+ import copy
3233
33- MYSQL_CONFIG = {
34- 'Host' : 'localhost' ,
35- 'Port' : 3306 ,
36- 'User' : 'root' ,
37- 'Password' : '' ,
38- 'HeartbeatTable' : '' ,
39- 'Verbose' : False ,
40- 'Instance' : '' ,
41- }
34+
35+ # Verbose logging on/off. Override in config by specifying 'Verbose'.
36+ VERBOSE_LOGGING = False
37+
38+ CONFIGS = []
4239
4340MYSQL_STATUS_VARS = {
4441 'Aborted_clients' : 'counter' ,
302299 },
303300}
304301
305- def get_mysql_conn ():
302+ def get_mysql_conn (conf ):
306303 return MySQLdb .connect (
307- host = MYSQL_CONFIG [ 'Host ' ],
308- port = MYSQL_CONFIG [ 'Port ' ],
309- user = MYSQL_CONFIG [ 'User ' ],
310- passwd = MYSQL_CONFIG [ 'Password ' ]
304+ host = conf [ 'host ' ],
305+ port = conf [ 'port ' ],
306+ user = conf [ 'user ' ],
307+ passwd = conf [ 'password ' ]
311308 )
312309
313310def mysql_query (conn , query ):
@@ -349,7 +346,7 @@ def fetch_mysql_master_stats(conn):
349346
350347 return stats
351348
352- def fetch_mysql_slave_stats (conn ):
349+ def fetch_mysql_slave_stats (conf , conn ):
353350 result = mysql_query (conn , 'SHOW SLAVE STATUS' )
354351 slave_row = result .fetchone ()
355352 if slave_row is None :
@@ -361,12 +358,12 @@ def fetch_mysql_slave_stats(conn):
361358 'slave_lag' : slave_row ['Seconds_Behind_Master' ] if slave_row ['Seconds_Behind_Master' ] != None else 0 ,
362359 }
363360
364- if MYSQL_CONFIG [ 'HeartbeatTable ' ]:
361+ if conf [ 'heartbeattable ' ]:
365362 query = """
366363 SELECT MAX(UNIX_TIMESTAMP() - UNIX_TIMESTAMP(ts)) AS delay
367364 FROM %s
368365 WHERE server_id = %s
369- """ % (MYSQL_CONFIG [ 'HeartbeatTable ' ], slave_row ['Master_Server_Id' ])
366+ """ % (conf [ 'heartbeattable ' ], slave_row ['Master_Server_Id' ])
370367 result = mysql_query (conn , query )
371368 row = result .fetchone ()
372369 if 'delay' in row and row ['delay' ] != None :
@@ -470,11 +467,10 @@ def fetch_innodb_stats(conn):
470467 return stats
471468
472469def log_verbose (msg ):
473- if MYSQL_CONFIG ['Verbose' ] == False :
474- return
475- collectd .info ('mysql plugin: %s' % msg )
470+ if VERBOSE_LOGGING :
471+ collectd .info ('mysql plugin: %s' % msg )
476472
477- def dispatch_value (prefix , key , value , type , type_instance = None ):
473+ def dispatch_value (instance , prefix , key , value , type , type_instance = None ):
478474 if not type_instance :
479475 type_instance = key
480476
@@ -483,26 +479,61 @@ def dispatch_value(prefix, key, value, type, type_instance=None):
483479 return
484480 value = int (value ) # safety check
485481
486- val = collectd .Values (plugin = 'mysql' , plugin_instance = prefix )
487- val .plugin = 'mysql.%s' % MYSQL_CONFIG ['Instance' ]
488- val .plugin_instance = prefix
482+ if instance is None :
483+ plugin = 'mysql'
484+ else :
485+ plugin = 'mysql.%s' % instance
486+ val = collectd .Values (plugin = plugin , plugin_instance = prefix )
489487 val .type = type
490488 val .type_instance = type_instance
491489 val .values = [value ]
492490 val .dispatch ()
493491
494492def configure_callback (conf ):
495- global MYSQL_CONFIG
493+ instance = None
494+ host = 'localhost'
495+ port = 3306
496+ user = 'root'
497+ password = ''
498+ heartbeattable = ''
499+ verbose = False
500+
496501 for node in conf .children :
497- if node .key in MYSQL_CONFIG :
498- MYSQL_CONFIG [node .key ] = node .values [0 ]
502+ key = node .key .lower ()
503+ val = node .values [0 ]
504+ if key == 'instance' :
505+ instance = val
506+ elif key == 'host' :
507+ host = val
508+ elif key == 'port' :
509+ port = int (val )
510+ elif key == 'user' :
511+ user = val
512+ elif key == 'password' :
513+ password = val
514+ elif key == 'heartbeattable' :
515+ heartbeattable = val
516+ elif key == 'verbose' :
517+ global VERBOSE_LOGGING
518+ VERBOSE_LOGGING = bool (val ) or VERBOSE_LOGGING
519+ else :
520+ collectd .warning ('mysql plugin: Unknown config key: %s.' % key )
499521
500- MYSQL_CONFIG ['Port' ] = int (MYSQL_CONFIG ['Port' ])
501- MYSQL_CONFIG ['Verbose' ] = bool (MYSQL_CONFIG ['Verbose' ])
522+ log_verbose ('Configured with host=%s, port=%s, instance name=%s, user=%s' % ( host , port , instance , user ))
502523
503- def read_callback ():
524+ mysql_config = {
525+ 'instance' : instance ,
526+ 'host' : host ,
527+ 'port' : port ,
528+ 'user' : user ,
529+ 'password' : password ,
530+ 'heartbeattable' : heartbeattable
531+ }
532+ CONFIGS .append (mysql_config )
533+
534+ def get_metrics (conf ):
504535 global MYSQL_STATUS_VARS
505- conn = get_mysql_conn ()
536+ conn = get_mysql_conn (conf )
506537
507538 mysql_status = fetch_mysql_status (conn )
508539 for key in mysql_status :
@@ -518,33 +549,37 @@ def read_callback():
518549 else :
519550 continue
520551
521- dispatch_value ('status' , key , mysql_status [key ], ds_type )
552+ dispatch_value (conf [ 'instance' ], 'status' , key , mysql_status [key ], ds_type )
522553
523554 mysql_variables = fetch_mysql_variables (conn )
524555 for key in mysql_variables :
525- dispatch_value ('variables' , key , mysql_variables [key ], 'gauge' )
556+ dispatch_value (conf [ 'instance' ], 'variables' , key , mysql_variables [key ], 'gauge' )
526557
527558 mysql_master_status = fetch_mysql_master_stats (conn )
528559 for key in mysql_master_status :
529- dispatch_value ('master' , key , mysql_master_status [key ], 'gauge' )
560+ dispatch_value (conf [ 'instance' ], 'master' , key , mysql_master_status [key ], 'gauge' )
530561
531562 mysql_states = fetch_mysql_process_states (conn )
532563 for key in mysql_states :
533- dispatch_value ('state' , key , mysql_states [key ], 'gauge' )
564+ dispatch_value (conf [ 'instance' ], 'state' , key , mysql_states [key ], 'gauge' )
534565
535- slave_status = fetch_mysql_slave_stats (conn )
566+ slave_status = fetch_mysql_slave_stats (conf , conn )
536567 for key in slave_status :
537- dispatch_value ('slave' , key , slave_status [key ], 'gauge' )
568+ dispatch_value (conf [ 'instance' ], 'slave' , key , slave_status [key ], 'gauge' )
538569
539570 response_times = fetch_mysql_response_times (conn )
540571 for key in response_times :
541- dispatch_value ('response_time_total' , str (key ), response_times [key ]['total' ], 'counter' )
542- dispatch_value ('response_time_count' , str (key ), response_times [key ]['count' ], 'counter' )
572+ dispatch_value (conf [ 'instance' ], 'response_time_total' , str (key ), response_times [key ]['total' ], 'counter' )
573+ dispatch_value (conf [ 'instance' ], 'response_time_count' , str (key ), response_times [key ]['count' ], 'counter' )
543574
544575 innodb_status = fetch_innodb_stats (conn )
545576 for key in MYSQL_INNODB_STATUS_VARS :
546577 if key not in innodb_status : continue
547- dispatch_value ('innodb' , key , innodb_status [key ], MYSQL_INNODB_STATUS_VARS [key ])
578+ dispatch_value (conf ['instance' ], 'innodb' , key , innodb_status [key ], MYSQL_INNODB_STATUS_VARS [key ])
579+
580+ def read_callback ():
581+ for conf in CONFIGS :
582+ get_metrics (conf )
548583
549584collectd .register_read (read_callback )
550585collectd .register_config (configure_callback )
0 commit comments