diff options
-rw-r--r-- | src/MYSQL-STAT-MIB.txt | 127 | ||||
-rw-r--r-- | src/mysqlstat.c | 220 | ||||
-rw-r--r-- | src/mysqlstat.h | 27 | ||||
-rw-r--r-- | src/mysqlstat_mib.mib2c | 114 |
4 files changed, 204 insertions, 284 deletions
diff --git a/src/MYSQL-STAT-MIB.txt b/src/MYSQL-STAT-MIB.txt index 8fbc0e6..3c05db2 100644 --- a/src/MYSQL-STAT-MIB.txt +++ b/src/MYSQL-STAT-MIB.txt @@ -20,3 +20,3 @@ IMPORTS mysql MODULE-IDENTITY - LAST-UPDATED "201606061638Z" + LAST-UPDATED "201606070800Z" ORGANIZATION "Gray Software" @@ -25,3 +25,3 @@ mysql MODULE-IDENTITY "This MIB module defines objects for MySQL statistics." - REVISION "201606061638Z" + REVISION "201606070800Z" DESCRIPTION @@ -463,98 +463,2 @@ replMasterSSLVerifyServerCert OBJECT-TYPE -- --- Table of Replication Slave Servers --- - --- replSlaveCount OBJECT-TYPE --- SYNTAX Counter32 --- MAX-ACCESS read-only --- STATUS current --- DESCRIPTION --- "Number of active replication slaves." --- ::= { replSlave 1 } - --- replSlaveTable OBJECT-TYPE --- SYNTAX SEQUENCE OF ReplSlaveEntry --- MAX-ACCESS not-accessible --- STATUS current --- DESCRIPTION --- "A table of active replication slaves." --- ::= { replSlave 2 } - --- replSlaveEntry OBJECT-TYPE --- SYNTAX ReplSlaveEntry --- MAX-ACCESS not-accessible --- STATUS current --- DESCRIPTION --- "An entry (conceptual row) describing a replication --- slave server." --- INDEX { replSlaveIndex } --- ::= { replSlaveTable 1 } - --- ReplSlaveEntry ::= SEQUENCE { --- replSlaveIndex Integer32, --- replSlaveHost DisplayString, --- replSlaveUser DisplayString, --- replSlaveCommand DisplayString, --- replSlaveState DisplayString, --- replSlaveTime TimeStamp, --- replSlaveInfo DisplayString --- } - --- replSlaveIndex OBJECT-TYPE --- SYNTAX Integer32 (0..65535) --- MAX-ACCESS not-accessible --- STATUS current --- DESCRIPTION --- "A number uniquely identifying each slave server." --- ::= { replSlaveEntry 1 } - --- replSlaveHost OBJECT-TYPE --- SYNTAX DisplayString --- MAX-ACCESS read-only --- STATUS current --- DESCRIPTION --- "Hostname of the server." --- ::= { replSlaveEntry 2 } - --- replSlaveUser OBJECT-TYPE --- SYNTAX DisplayString --- MAX-ACCESS read-only --- STATUS current --- DESCRIPTION --- "User name used by that server." --- ::= { replSlaveEntry 3 } - --- replSlaveCommand OBJECT-TYPE --- SYNTAX DisplayString --- MAX-ACCESS read-only --- STATUS current --- DESCRIPTION --- "Command being run." --- ::= { replSlaveEntry 4 } - --- replSlaveState OBJECT-TYPE --- SYNTAX DisplayString --- MAX-ACCESS read-only --- STATUS current --- DESCRIPTION --- "State of the connection." --- ::= { replSlaveEntry 5 } - --- replSlaveTime OBJECT-TYPE --- SYNTAX TimeStamp --- MAX-ACCESS read-only --- STATUS current --- DESCRIPTION --- "Timestamp of the last status change." --- ::= { replSlaveEntry 6 } - --- replSlaveInfo OBJECT-TYPE --- SYNTAX DisplayString --- MAX-ACCESS read-only --- STATUS current --- DESCRIPTION --- "Additional info about the connection." --- ::= { replSlaveEntry 7 } - --- -- Process List @@ -568,3 +472,3 @@ processListTable OBJECT-TYPE "A table of active threads." - ::= { processList 2 } + ::= { processList 1 } @@ -662,2 +566,27 @@ processInfo OBJECT-TYPE ::= { processListEntry 9 } + +processTotalCount OBJECT-TYPE + SYNTAX Counter32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Total number of processes (threads)." + ::= { processList 2 } + +processActiveCount OBJECT-TYPE + SYNTAX Counter32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of active processes (threads)." + ::= { processList 3 } + +processSlaveCount OBJECT-TYPE + SYNTAX Counter32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of replication slaves" + ::= { processList 4 } + END diff --git a/src/mysqlstat.c b/src/mysqlstat.c index 938439a..2ffd0dd 100644 --- a/src/mysqlstat.c +++ b/src/mysqlstat.c @@ -56,18 +56,22 @@ mysqlstat_connect(void) { - struct mysqlstat_connection *conn; + static struct mysqlstat_connection *conn; my_bool t = 1; - conn = xcalloc(1, sizeof(*conn)); - mysql_init(&conn->mysql); - if (access(config_file, F_OK) == 0) - mysql_options(&conn->mysql, MYSQL_READ_DEFAULT_FILE, - config_file); - mysql_options(&conn->mysql, MYSQL_READ_DEFAULT_GROUP, "mysqlstat"); - mysql_options(&conn->mysql, MYSQL_OPT_RECONNECT, &t); - if (!mysql_real_connect(&conn->mysql, NULL, NULL, NULL, NULL, 0, - NULL, 0)) { - snmp_log(LOG_ERR, "can't connect to MySQL: %s\n", - mysql_error(&conn->mysql)); - free(conn); - conn = NULL; + if (!conn) { + conn = xcalloc(1, sizeof(*conn)); + mysql_init(&conn->mysql); + if (access(config_file, F_OK) == 0) + mysql_options(&conn->mysql, MYSQL_READ_DEFAULT_FILE, + config_file); + mysql_options(&conn->mysql, + MYSQL_READ_DEFAULT_GROUP, "mysqlstat"); + mysql_options(&conn->mysql, MYSQL_OPT_RECONNECT, &t); + if (!mysql_real_connect(&conn->mysql, + NULL, NULL, NULL, NULL, 0, + NULL, 0)) { + snmp_log(LOG_ERR, "can't connect to MySQL: %s\n", + mysql_error(&conn->mysql)); + free(conn); + conn = NULL; + } } @@ -75,11 +79,2 @@ mysqlstat_connect(void) } - -void -mysqlstat_disconnect(mysqlstat_connection_t conn) -{ - if (!conn) - return; - mysql_close(&conn->mysql); - free(conn); -} @@ -103,3 +98,94 @@ unsigned mysqlstat_cache_timeout = CACHE_TIMEOUT; #define STREQ(pat,str) (strcmp(#pat, str) == 0) + +struct process_list { + time_t ts; + MYSQL_RES *res; + uint32_t total; + uint32_t active; + uint32_t slaves; + uint32_t itr; +}; + +enum { + FI_processID, + FI_processUser, + FI_processHost, + FI_processDatabase, + FI_processCommand, + FI_processTime, + FI_processState, + FI_processInfo +}; +static int +get_process_list(struct process_list **p) +{ + static struct process_list plist; + time_t now; + + now = time(NULL); + if (!plist.res || now - plist.ts >= mysqlstat_cache_timeout) { + mysqlstat_connection_t conn; + unsigned i; + + if (plist.res) { + mysql_free_result(plist.res); + plist.res = NULL; + plist.total = plist.active = plist.slaves = 0; + } + DEBUGMSGTL(("mysqlstat", "Getting process list\n")); + + conn = mysqlstat_connect(); + if (!conn) + return SNMP_ERR_GENERR; + + if (mysql_query(&conn->mysql, "SHOW PROCESSLIST")) { + snmp_log(LOG_ERR, "can't get slave process list: %s\n", + mysql_error(&conn->mysql)); + return SNMP_ERR_NOSUCHNAME; + } + plist.res = mysql_store_result(&conn->mysql); + plist.ts = now; + + plist.total = mysql_num_rows(plist.res); + for (i = 0; i < plist.total; i++) { + MYSQL_ROW row; + + mysql_data_seek(plist.res, i); + row = mysql_fetch_row(plist.res); + if (!row[FI_processState] + || STREQ(Sleep, row[FI_processState])) + continue; + if (row[FI_processCommand] + && strcmp(row[FI_processCommand], "Binlog Dump") == 0) + plist.slaves++; + else + plist.active++; + } + } + *p = &plist; + return 0; +} + +MYSQL_ROW +process_next(struct process_list *p) +{ + MYSQL_ROW row; + if (p->itr >= p->total) + return NULL; + mysql_data_seek(p->res, p->itr); + ++p->itr; + return mysql_fetch_row(p->res); +} + +MYSQL_ROW +process_first(struct process_list **state) +{ + struct process_list *p; + if (get_process_list(&p)) + return NULL; + p->itr = 0; + *state = p; + return process_next(p); +} @@ -226,3 +312,2 @@ replSlaveStatusTable_load(netsnmp_cache *cache, void *vmagic) mysql_error(&conn->mysql)); - mysqlstat_disconnect(conn); return SNMP_ERR_NOSUCHNAME; @@ -232,3 +317,3 @@ replSlaveStatusTable_load(netsnmp_cache *cache, void *vmagic) if (mysql_num_rows(res) < 1) { - snmp_log(LOG_INFO, "empty slave status\n"); + /* snmp_log(LOG_INFO, "empty slave status\n"); */ return 0; @@ -242,3 +327,2 @@ replSlaveStatusTable_load(netsnmp_cache *cache, void *vmagic) if (!ent) { - mysqlstat_disconnect(conn); return SNMP_ERR_GENERR; @@ -249,3 +333,2 @@ replSlaveStatusTable_load(netsnmp_cache *cache, void *vmagic) SNMP_FREE(ent); - mysqlstat_disconnect(conn); return SNMP_ERR_GENERR; @@ -261,6 +344,5 @@ replSlaveStatusTable_load(netsnmp_cache *cache, void *vmagic) for (i = 0; i < num_fields; i++) - store_slave_status_row (ent, fields[i].name, row[i]); + store_slave_status_row(ent, fields[i].name, row[i]); mysql_free_result(res); - mysqlstat_disconnect(conn); return 0; @@ -297,14 +379,2 @@ replSlaveStatusTable_entry_free(void *data) - -enum { - FI_processID, - FI_processUser, - FI_processHost, - FI_processDatabase, - FI_processCommand, - FI_processTime, - FI_processState, - FI_processInfo -}; - static void @@ -329,4 +399,9 @@ process_list_add(netsnmp_tdata *table_data, long idx, MYSQL_ROW mysql_row) ent->processID = strtol(mysql_row[FI_processID], NULL, 10); + ASSIGN_ROW(ent, processUser, mysql_row); - ASSIGN_ROW(ent, processHost, mysql_row); + + ent->processHost_len = strcspn(mysql_row[FI_processHost], ":"); + ent->processHost = xmalloc(ent->processHost_len); + memcpy(ent->processHost, mysql_row[FI_processHost], ent->processHost_len); + ASSIGN_ROW(ent, processDatabase, mysql_row); @@ -348,35 +423,10 @@ processListTable_load(netsnmp_cache *cache, void *vmagic) { - mysqlstat_connection_t conn; - MYSQL_RES *res; - unsigned int num_rows, i; + struct process_list *p; netsnmp_tdata *table = (netsnmp_tdata *) vmagic; + MYSQL_ROW row; + uint32_t i; - DEBUGMSGTL(("mysqlstat", "Getting process list\n")); - - conn = mysqlstat_connect(); - if (!conn) - return SNMP_ERR_GENERR; - - if (mysql_query(&conn->mysql, "SHOW PROCESSLIST")) { - snmp_log(LOG_ERR, "can't get slave process list: %s\n", - mysql_error(&conn->mysql)); - mysqlstat_disconnect(conn); - return SNMP_ERR_NOSUCHNAME; - } - - res = mysql_store_result(&conn->mysql); - num_rows = mysql_num_rows(res); - - for (i = 0; i < num_rows; i++) { - MYSQL_ROW row; - - mysql_data_seek(res, i); - row = mysql_fetch_row(res); - + for (row = process_first(&p), i = 0; row; row = process_next(p), i++) { process_list_add(table, i, row); } - - mysql_free_result(res); - mysqlstat_disconnect(conn); - return 0; @@ -395,2 +445,30 @@ processListTable_entry_free(void *data) +uint32_t +process_total_count(void) +{ + struct process_list *p; + if (get_process_list(&p)) + return 0; + return p->total; +} + +uint32_t +process_active_count(void) +{ + struct process_list *p; + if (get_process_list(&p)) + return 0; + return p->active; +} + +uint32_t +process_slave_count(void) +{ + struct process_list *p; + if (get_process_list(&p)) + return 0; + return p->slaves; +} + + #if 0 diff --git a/src/mysqlstat.h b/src/mysqlstat.h index 1fc724e..f4bf137 100644 --- a/src/mysqlstat.h +++ b/src/mysqlstat.h @@ -29,26 +29,4 @@ -enum { - MYSQLSTAT_CACHE_REPL, - MYSQLSTAT_MAX_CACHE -}; - typedef struct mysqlstat_connection *mysqlstat_connection_t; -struct repl_stat { - char *replMasterLogFile; - uint32_t replReadMasterLogPos; - char *replRelayLogFile; - uint32_t replRelayLogPos; - char *replRelayMasterLogFile; - int replSlaveIORunning; - int replSlaveSQLRunning; - int replLastSQLErrno; - char *replLastSQLError; - int replLastIOErrno; - char *replLastIOError; - uint32_t replExecMasterLogPos; - uint64_t replRelayLogSpace; - uint32_t replSecondsBehindMaster; -}; - mysqlstat_connection_t mysqlstat_connect(void); @@ -56,2 +34,5 @@ void mysqlstat_disconnect(mysqlstat_connection_t); -char const *mysqlstat_get(int id, char const *name); +uint32_t process_total_count(void); +uint32_t process_active_count(void); +uint32_t process_slave_count(void); + diff --git a/src/mysqlstat_mib.mib2c b/src/mysqlstat_mib.mib2c index 7f00d9b..733f977 100644 --- a/src/mysqlstat_mib.mib2c +++ b/src/mysqlstat_mib.mib2c @@ -25,77 +25,5 @@ $vars{'mysqlstat_translate_table'} = { - replSlaveIOState => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Slave_IO_State")}, - replMasterLogFile => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Master_Log_File")}, - replReadMasterLogPos => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Read_Master_Log_Pos")}, - replRelayLogFile => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Relay_Log_File")}, - replRelayLogPos => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Relay_Log_Pos")}, - replRelayMasterLogFile => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Relay_Master_Log_File")}, - replSlaveIORunning => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Slave_IO_Running")}, - replSlaveSQLRunning => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Slave_SQL_Running")}, - replLastSQLErrno => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Last_SQL_Errno")}, - replLastSQLError => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Last_SQL_Error")}, - replLastIOErrno => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Last_IO_Errno")}, - replLastIOError => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Last_IO_Error")}, - replExecMasterLogPos => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Exec_Master_Log_Pos")}, - replRelayLogSpace => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Relay_Log_Space")}, - replSecondsBehindMaster => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Seconds_Behind_Master")}, - - replMasterHost => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Master_Host")}, - replMasterUser => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Master_User")}, - replMasterPort => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Master_Port")}, - replConnectRetry => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Connect_Retry")}, - replReplicateDoDB => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Replicate_Do_DB")}, - replReplicateIgnoreDB => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Replicate_Ignore_DB")}, - replReplicateDoTable => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Replicate_Do_Table")}, - replReplicateIgnoreTable => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Replicate_Ignore_Table")}, - replReplicateWildDoTable => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Replicate_Wild_Do_Table")}, - replReplicateWildIgnoreTable => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Replicate_Wild_Ignore_Table")}, - replSkipCounter => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Skip_Counter")}, - replUntilCondition => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Until_Condition")}, - replUntilLogFile => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Until_Log_File")}, - replUntilLogPos => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Until_Log_Pos")}, - replMasterServerId => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Master_Server_Id")}, - replMasterSSLAllowed => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Master_SSL_Allowed")}, - replMasterSSLCAFile => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Master_SSL_CA_File")}, - replMasterSSLCAPath => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Master_SSL_CA_Path")}, - replMasterSSLCert => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Master_SSL_Cert")}, - replMasterSSLCipher => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Master_SSL_Cipher")}, - replMasterSSLKey => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Master_SSL_Key")}, - replMasterSSLVerifyServerCert => - q{mysqlstat_get(MYSQLSTAT_CACHE_REPL, "Master_SSL_Verify_Server_Cert")} + processTotalCount => q{process_total_count()}, + processActiveCount => q{process_active_count()}, + processSlaveCount => q{process_slave_count()} }; @@ -150,7 +78,15 @@ handle_$i(netsnmp_mib_handler *handler, @end@ - char const *val = $mysqlstat_get; + @if $i.type eq 'ASN_OCTET_STR'@ + @eval $mysqlstat_type = q{char const *};@ + @elsif $i.type eq 'ASN_COUNTER64'@ + @eval $mysqlstat_type = q{uint64_t};@ + @elsif $i.type eq 'ASN_COUNTER'@ + @eval $mysqlstat_type = q{uint32_t};@ + @elsif $i.type eq 'ASN_INTEGER'@ + @eval $mysqlstat_type = q{uint32_t};@ + @elsif $i.type eq 'ASN_TIMETICKS'@ + @eval $mysqlstat_type = q{uint32_t};@ + @end@ + $mysqlstat_type val = $mysqlstat_get; - if (!val) - return SNMP_ERR_NOSUCHNAME; - switch(reqinfo->mode) { @@ -160,5 +96,4 @@ handle_$i(netsnmp_mib_handler *handler, struct counter64 ctr; - uint64_t n = strtoull(val, NULL, 10); - ctr.high = n >> 32; - ctr.low = n & 0xffffffff; + ctr.high = val >> 32; + ctr.low = val & 0xffffffff; snmp_set_var_typed_value(requests->requestvb, $i.type, @@ -174,6 +109,5 @@ handle_$i(netsnmp_mib_handler *handler, { - uint32_t n = strtoul(val, NULL, 10); snmp_set_var_typed_value(requests->requestvb, $i.type, - &n, - sizeof(n)); + &val, + sizeof(val)); } @@ -181,6 +115,5 @@ handle_$i(netsnmp_mib_handler *handler, { - uint32_t n = strtoul(val, NULL, 10); snmp_set_var_typed_value(requests->requestvb, $i.type, - &n, - sizeof(n)); + &val, + sizeof(val)); } @@ -188,6 +121,5 @@ handle_$i(netsnmp_mib_handler *handler, { - uint32_t n = strtoul(val, NULL, 10); snmp_set_var_typed_value(requests->requestvb, $i.type, - &n, - sizeof(n)); + &val, + sizeof(val)); } |