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' ,
303300 },
304301}
305302
306- def get_mysql_conn ():
303+ def get_mysql_conn (conf ):
307304 return MySQLdb .connect (
308- host = MYSQL_CONFIG [ 'Host ' ],
309- port = MYSQL_CONFIG [ 'Port ' ],
310- user = MYSQL_CONFIG [ 'User ' ],
311- passwd = MYSQL_CONFIG [ 'Password ' ]
305+ host = conf [ 'host ' ],
306+ port = conf [ 'port ' ],
307+ user = conf [ 'user ' ],
308+ passwd = conf [ 'password ' ]
312309 )
313310
314311def mysql_query (conn , query ):
@@ -350,7 +347,7 @@ def fetch_mysql_master_stats(conn):
350347
351348 return stats
352349
353- def fetch_mysql_slave_stats (conn ):
350+ def fetch_mysql_slave_stats (conf , conn ):
354351 result = mysql_query (conn , 'SHOW SLAVE STATUS' )
355352 slave_row = result .fetchone ()
356353 if slave_row is None :
@@ -362,12 +359,12 @@ def fetch_mysql_slave_stats(conn):
362359 'slave_lag' : slave_row ['Seconds_Behind_Master' ] if slave_row ['Seconds_Behind_Master' ] != None else 0 ,
363360 }
364361
365- if MYSQL_CONFIG [ 'HeartbeatTable ' ]:
362+ if conf [ 'heartbeattable ' ]:
366363 query = """
367364 SELECT MAX(UNIX_TIMESTAMP() - UNIX_TIMESTAMP(ts)) AS delay
368365 FROM %s
369366 WHERE server_id = %s
370- """ % (MYSQL_CONFIG [ 'HeartbeatTable ' ], slave_row ['Master_Server_Id' ])
367+ """ % (conf [ 'heartbeattable ' ], slave_row ['Master_Server_Id' ])
371368 result = mysql_query (conn , query )
372369 row = result .fetchone ()
373370 if 'delay' in row and row ['delay' ] != None :
@@ -471,11 +468,10 @@ def fetch_innodb_stats(conn):
471468 return stats
472469
473470def log_verbose (msg ):
474- if MYSQL_CONFIG ['Verbose' ] == False :
475- return
476- collectd .info ('mysql plugin: %s' % msg )
471+ if VERBOSE_LOGGING :
472+ collectd .info ('mysql plugin: %s' % msg )
477473
478- def dispatch_value (prefix , key , value , type , type_instance = None ):
474+ def dispatch_value (instance , prefix , key , value , type , type_instance = None ):
479475 if not type_instance :
480476 type_instance = key
481477
@@ -484,26 +480,61 @@ def dispatch_value(prefix, key, value, type, type_instance=None):
484480 return
485481 value = int (value ) # safety check
486482
487- val = collectd .Values (plugin = 'mysql' , plugin_instance = prefix )
488- val .plugin = 'mysql.%s' % MYSQL_CONFIG ['Instance' ]
489- val .plugin_instance = prefix
483+ if instance is None :
484+ plugin = 'mysql'
485+ else :
486+ plugin = 'mysql.%s' % instance
487+ val = collectd .Values (plugin = plugin , plugin_instance = prefix )
490488 val .type = type
491489 val .type_instance = type_instance
492490 val .values = [value ]
493491 val .dispatch ()
494492
495493def configure_callback (conf ):
496- global MYSQL_CONFIG
494+ instance = None
495+ host = 'localhost'
496+ port = 3306
497+ user = 'root'
498+ password = ''
499+ heartbeattable = ''
500+ verbose = False
501+
497502 for node in conf .children :
498- if node .key in MYSQL_CONFIG :
499- MYSQL_CONFIG [node .key ] = node .values [0 ]
503+ key = node .key .lower ()
504+ val = node .values [0 ]
505+ if key == 'instance' :
506+ instance = val
507+ elif key == 'host' :
508+ host = val
509+ elif key == 'port' :
510+ port = int (val )
511+ elif key == 'user' :
512+ user = val
513+ elif key == 'password' :
514+ password = val
515+ elif key == 'heartbeattable' :
516+ heartbeattable = val
517+ elif key == 'verbose' :
518+ global VERBOSE_LOGGING
519+ VERBOSE_LOGGING = bool (val ) or VERBOSE_LOGGING
520+ else :
521+ collectd .warning ('mysql plugin: Unknown config key: %s.' % key )
500522
501- MYSQL_CONFIG ['Port' ] = int (MYSQL_CONFIG ['Port' ])
502- MYSQL_CONFIG ['Verbose' ] = bool (MYSQL_CONFIG ['Verbose' ])
523+ log_verbose ('Configured with host=%s, port=%s, instance name=%s, user=%s' % ( host , port , instance , user ))
503524
504- def read_callback ():
525+ mysql_config = {
526+ 'instance' : instance ,
527+ 'host' : host ,
528+ 'port' : port ,
529+ 'user' : user ,
530+ 'password' : password ,
531+ 'heartbeattable' : heartbeattable
532+ }
533+ CONFIGS .append (mysql_config )
534+
535+ def get_metrics (conf ):
505536 global MYSQL_STATUS_VARS
506- conn = get_mysql_conn ()
537+ conn = get_mysql_conn (conf )
507538
508539 mysql_status = fetch_mysql_status (conn )
509540 for key in mysql_status :
@@ -519,33 +550,37 @@ def read_callback():
519550 else :
520551 continue
521552
522- dispatch_value ('status' , key , mysql_status [key ], ds_type )
553+ dispatch_value (conf [ 'instance' ], 'status' , key , mysql_status [key ], ds_type )
523554
524555 mysql_variables = fetch_mysql_variables (conn )
525556 for key in mysql_variables :
526- dispatch_value ('variables' , key , mysql_variables [key ], 'gauge' )
557+ dispatch_value (conf [ 'instance' ], 'variables' , key , mysql_variables [key ], 'gauge' )
527558
528559 mysql_master_status = fetch_mysql_master_stats (conn )
529560 for key in mysql_master_status :
530- dispatch_value ('master' , key , mysql_master_status [key ], 'gauge' )
561+ dispatch_value (conf [ 'instance' ], 'master' , key , mysql_master_status [key ], 'gauge' )
531562
532563 mysql_states = fetch_mysql_process_states (conn )
533564 for key in mysql_states :
534- dispatch_value ('state' , key , mysql_states [key ], 'gauge' )
565+ dispatch_value (conf [ 'instance' ], 'state' , key , mysql_states [key ], 'gauge' )
535566
536- slave_status = fetch_mysql_slave_stats (conn )
567+ slave_status = fetch_mysql_slave_stats (conf , conn )
537568 for key in slave_status :
538- dispatch_value ('slave' , key , slave_status [key ], 'gauge' )
569+ dispatch_value (conf [ 'instance' ], 'slave' , key , slave_status [key ], 'gauge' )
539570
540571 response_times = fetch_mysql_response_times (conn )
541572 for key in response_times :
542- dispatch_value ('response_time_total' , str (key ), response_times [key ]['total' ], 'counter' )
543- dispatch_value ('response_time_count' , str (key ), response_times [key ]['count' ], 'counter' )
573+ dispatch_value (conf [ 'instance' ], 'response_time_total' , str (key ), response_times [key ]['total' ], 'counter' )
574+ dispatch_value (conf [ 'instance' ], 'response_time_count' , str (key ), response_times [key ]['count' ], 'counter' )
544575
545576 innodb_status = fetch_innodb_stats (conn )
546577 for key in MYSQL_INNODB_STATUS_VARS :
547578 if key not in innodb_status : continue
548- dispatch_value ('innodb' , key , innodb_status [key ], MYSQL_INNODB_STATUS_VARS [key ])
579+ dispatch_value (conf ['instance' ], 'innodb' , key , innodb_status [key ], MYSQL_INNODB_STATUS_VARS [key ])
580+
581+ def read_callback ():
582+ for conf in CONFIGS :
583+ get_metrics (conf )
549584
550585collectd .register_read (read_callback )
551586collectd .register_config (configure_callback )
0 commit comments