Index: cdr_addon_mysql.c =================================================================== RCS file: /usr/cvsroot/asterisk-addons/cdr_addon_mysql.c,v retrieving revision 1.1 diff -u -r1.1 cdr_addon_mysql.c --- cdr_addon_mysql.c 29 Sep 2003 21:27:12 -0000 1.1 +++ cdr_addon_mysql.c 22 Jan 2004 17:55:14 -0000 @@ -20,6 +20,7 @@ #include #include #include +#include #include "asterisk.h" #include @@ -41,18 +42,108 @@ static int hostname_alloc = 0, dbname_alloc = 0, dbuser_alloc = 0, password_alloc = 0, dbsock_alloc = 0; static int dbport = 0; static int connected = 0; +static time_t connect_time = 0; +static int records = 0; +static int totalrecords = 0; static ast_mutex_t mysql_lock = AST_MUTEX_INITIALIZER; static MYSQL mysql; +STANDARD_LOCAL_USER; + +LOCAL_USER_DECL; + +#define MYSQL_USER_ADD(u) { \ + \ + if (!(u=malloc(sizeof(struct localuser)))) { \ + ast_log(LOG_WARNING, "Out of memory\n"); \ + return -1; \ + } \ + ast_mutex_lock(&localuser_lock); \ + u->next = localusers; \ + localusers = u; \ + localusecnt++; \ + ast_mutex_unlock(&localuser_lock); \ + ast_update_use_count(); \ +} + +#define MYSQL_USER_REMOVE(u) { \ + struct localuser *uc, *ul = NULL; \ + ast_mutex_lock(&localuser_lock); \ + uc = localusers; \ + while (uc) { \ + if (uc == u) { \ + if (ul) \ + ul->next = uc->next; \ + else \ + localusers = uc->next; \ + break; \ + } \ + ul = uc; \ + uc = uc->next; \ + }\ + free(u); \ + localusecnt--; \ + ast_mutex_unlock(&localuser_lock); \ + ast_update_use_count(); \ +} + +static char cdr_mysql_status_help[] = +"Usage: cdr mysql status\n" +" Shows current connection status for cdr_mysql\n"; + +static int handle_cdr_mysql_status(int fd, int argc, char *argv[]) +{ + if (connected) { + char status[256], status2[100] = ""; + int ctime = time(NULL) - connect_time; + if (dbport) + snprintf(status, 255, "Connected to %s@%s, port %d", dbname, hostname, dbport); + else if (dbsock) + snprintf(status, 255, "Connected to %s on socket file %s", dbname, dbsock); + else + snprintf(status, 255, "Connected to %s@%s", dbname, hostname); + + if (dbuser && *dbuser) + snprintf(status2, 99, " with username %s", dbuser); + if (ctime > 31536000) { + ast_cli(fd, "%s%s for %d years, %d days, %d hours, %d minutes, %d seconds.\n", status, status2, ctime / 31536000, (ctime % 31536000) / 86400, (ctime % 86400) / 3600, (ctime % 3600) / 60, ctime % 60); + } else if (ctime > 86400) { + ast_cli(fd, "%s%s for %d days, %d hours, %d minutes, %d seconds.\n", status, status2, ctime / 86400, (ctime % 86400) / 3600, (ctime % 3600) / 60, ctime % 60); + } else if (ctime > 3600) { + ast_cli(fd, "%s%s for %d hours, %d minutes, %d seconds.\n", status, status2, ctime / 3600, (ctime % 3600) / 60, ctime % 60); + } else if (ctime > 60) { + ast_cli(fd, "%s%s for %d minutes, %d seconds.\n", status, status2, ctime / 60, ctime % 60); + } else { + ast_cli(fd, "%s%s for %d seconds.\n", status, status2, ctime); + } + if (records == totalrecords) + ast_cli(fd, " Wrote %d records since last restart.\n", totalrecords); + else + ast_cli(fd, " Wrote %d records since last restart and %d records since last reconnect.\n", totalrecords, records); + return RESULT_SUCCESS; + } else { + ast_cli(fd, "Not currently connected to a MySQL server\n"); + return RESULT_FAILURE; + } +} + +static struct ast_cli_entry cdr_mysql_status_cli = + { { "cdr", "mysql", "status", NULL }, + handle_cdr_mysql_status, "Show connection status of cdr_mysql", + cdr_mysql_status_help, NULL }; + static int mysql_log(struct ast_cdr *cdr) { struct tm tm; struct timeval tv; + struct localuser *u; char sqlcmd[2048], timestr[128]; time_t t; + MYSQL_USER_ADD(u); + ast_mutex_lock(&mysql_lock); memset(sqlcmd,0,2048); @@ -67,6 +158,8 @@ mysql_init(&mysql); if (mysql_real_connect(&mysql, hostname, dbuser, password, dbname, dbport, dbsock, 0)) { connected = 1; + connect_time = time(NULL); + records = 0; } else { ast_log(LOG_ERROR, "cdr_mysql: cannot connect to database server %s. Call will not be logged\n", hostname); } @@ -75,6 +168,7 @@ int error; if ((error = mysql_ping(&mysql))) { connected = 0; + records = 0; switch (error) { case CR_SERVER_GONE_ERROR: ast_log(LOG_ERROR, "cdr_mysql: Server has gone away\n"); @@ -117,6 +211,7 @@ #endif ast_log(LOG_ERROR, "cdr_mysql: Out of memory error (insert fails)\n"); ast_mutex_unlock(&mysql_lock); + MYSQL_USER_REMOVE(u); return -1; } @@ -132,10 +227,15 @@ if (mysql_real_query(&mysql,sqlcmd,strlen(sqlcmd))) { ast_log(LOG_ERROR,"Failed to insert into database."); ast_mutex_unlock(&mysql_lock); + MYSQL_USER_REMOVE(u); return -1; + } else { + records++; + totalrecords++; } } ast_mutex_unlock(&mysql_lock); + MYSQL_USER_REMOVE(u); return 0; } @@ -146,9 +246,11 @@ static int my_unload_module(void) { + ast_cli_unregister(&cdr_mysql_status_cli); if (connected) { mysql_close(&mysql); connected = 0; + records = 0; } if (hostname && hostname_alloc) { free(hostname); @@ -297,15 +399,20 @@ if (!mysql_real_connect(&mysql, hostname, dbuser, password, dbname, dbport, dbsock, 0)) { ast_log(LOG_ERROR, "Failed to connect to mysql database %s on %s.\n", dbname, hostname); connected = 0; + records = 0; } else { ast_log(LOG_DEBUG,"Successfully connected to MySQL database.\n"); connected = 1; + records = 0; + connect_time = time(NULL); } res = ast_cdr_register(name, desc, mysql_log); if (res) { ast_log(LOG_ERROR, "Unable to register MySQL CDR handling\n"); } + ast_cli_register(&cdr_mysql_status_cli); + return res; } @@ -327,7 +434,9 @@ int usecount(void) { - return connected; + int res = 0; + STANDARD_USECOUNT(res); + return res; } char *key()