From 9d785ca5f30ae96a1a31e922e1cbb3a351a9a9c7 Mon Sep 17 00:00:00 2001 From: Richard Mudgett Date: Wed, 10 Aug 2011 20:51:07 +0000 Subject: Merged revisions 331462 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/10 ................ r331462 | rmudgett | 2011-08-10 15:41:35 -0500 (Wed, 10 Aug 2011) | 37 lines Merged revisions 331461 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ........ r331461 | rmudgett | 2011-08-10 15:29:59 -0500 (Wed, 10 Aug 2011) | 30 lines Output of queue log not started until logger reloaded. ASTERISK-15863 caused a regression with queue logging. The output of the queue log is not started until the logger configuration is reloaded. * Queue log initialization is completely delayed until the first message is posted to the queue log system. Including the initial opening of the queue log file. * Fixed rotate_file() ROTATE strategy to give the file just rotated out to the configured exec function after rotate. Just like the other strategies. * Fixed logger reload to always post the queue reload entry instead of just if there is a queue log file. * Refactored some code to eliminate some redundancy and to reduce stack utilization. (closes issue ASTERISK-17036) JIRA SWP-2952 Reported by: Juan Carlos Valero Patches: jira_asterisk_17036_v1.8.patch (license #5621) patch uploaded by rmudgett Tested by: rmudgett (closes issue ASTERISK-18208) Reported by: Christian Pinedo Review: https://reviewboard.asterisk.org/r/1333/ ........ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@331463 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- main/logger.c | 186 ++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 129 insertions(+), 57 deletions(-) (limited to 'main/logger.c') diff --git a/main/logger.c b/main/logger.c index 63facaaae..17f342825 100644 --- a/main/logger.c +++ b/main/logger.c @@ -70,6 +70,7 @@ static char exec_after_rotate[256] = ""; static int filesize_reload_needed; static unsigned int global_logmask = 0xFFFF; static int queuelog_init; +static int logger_initialized; static enum rotatestrategy { SEQUENTIAL = 1 << 0, /* Original method - create a new file, in order */ @@ -388,11 +389,10 @@ static void init_logger_chain(int locked, const char *altconf) AST_RWLIST_INSERT_HEAD(&logchannels, chan, list); global_logmask |= chan->logmask; } + if (qlog) { - char tmp[4096]; fclose(qlog); - snprintf(tmp, sizeof(tmp), "%s/%s", ast_config_AST_LOG_DIR, queue_log_name); - qlog = fopen(tmp, "a"); + qlog = NULL; } if (!locked) { @@ -460,9 +460,25 @@ void ast_queue_log(const char *queuename, const char *callid, const char *agent, int qlog_len; char time_str[30]; + if (!logger_initialized) { + /* You are too early. We are not open yet! */ + return; + } if (!queuelog_init) { - queuelog_init = 1; - logger_queue_init(); + AST_RWLIST_WRLOCK(&logchannels); + if (!queuelog_init) { + /* + * We have delayed initializing the queue logging system so + * preloaded realtime modules can get up. We must initialize + * now since someone is trying to log something. + */ + logger_queue_init(); + queuelog_init = 1; + AST_RWLIST_UNLOCK(&logchannels); + ast_queue_log("NONE", "NONE", "NONE", "QUEUESTART", "%s", ""); + } else { + AST_RWLIST_UNLOCK(&logchannels); + } } if (ast_check_realtime("queue_log")) { @@ -478,7 +494,8 @@ void ast_queue_log(const char *queuename, const char *callid, const char *agent, ); AST_NONSTANDARD_APP_ARGS(args, qlog_msg, '|'); /* Ensure fields are large enough to receive data */ - ast_realtime_require_field("queue_log", "data1", RQ_CHAR, strlen(S_OR(args.data[0], "")), + ast_realtime_require_field("queue_log", + "data1", RQ_CHAR, strlen(S_OR(args.data[0], "")), "data2", RQ_CHAR, strlen(S_OR(args.data[1], "")), "data3", RQ_CHAR, strlen(S_OR(args.data[2], "")), "data4", RQ_CHAR, strlen(S_OR(args.data[3], "")), @@ -600,6 +617,8 @@ static int rotate_file(const char *filename) if (rename(filename, new)) { fprintf(stderr, "Unable to rename file '%s' to '%s'\n", filename, new); res = -1; + } else { + filename = new; } } @@ -616,9 +635,77 @@ static int rotate_file(const char *filename) return res; } +/*! + * \internal + * \brief Start the realtime queue logging if configured. + * + * \retval TRUE if not to open queue log file. + */ +static int logger_queue_rt_start(void) +{ + if (ast_check_realtime("queue_log")) { + if (!ast_realtime_require_field("queue_log", + "time", RQ_DATETIME, 26, + "data1", RQ_CHAR, 20, + "data2", RQ_CHAR, 20, + "data3", RQ_CHAR, 20, + "data4", RQ_CHAR, 20, + "data5", RQ_CHAR, 20, + SENTINEL)) { + logfiles.queue_adaptive_realtime = 1; + } else { + logfiles.queue_adaptive_realtime = 0; + } + + if (!logfiles.queue_log_to_file) { + /* Don't open the log file. */ + return 1; + } + } + return 0; +} + +/*! + * \internal + * \brief Rotate the queue log file and restart. + * + * \param queue_rotate Log queue rotation mode. + * + * \note Assumes logchannels is write locked on entry. + * + * \retval 0 on success. + * \retval -1 on error. + */ +static int logger_queue_restart(int queue_rotate) +{ + int res = 0; + char qfname[PATH_MAX]; + + if (logger_queue_rt_start()) { + return res; + } + + snprintf(qfname, sizeof(qfname), "%s/%s", ast_config_AST_LOG_DIR, queue_log_name); + if (qlog) { + /* Just in case it was still open. */ + fclose(qlog); + qlog = NULL; + } + if (queue_rotate) { + rotate_file(qfname); + } + + /* Open the log file. */ + qlog = fopen(qfname, "a"); + if (!qlog) { + ast_log(LOG_ERROR, "Unable to create queue log: %s\n", strerror(errno)); + res = -1; + } + return res; +} + static int reload_logger(int rotate, const char *altconf) { - char old[PATH_MAX] = ""; int queue_rotate = rotate; struct logchannel *f; int res = 0; @@ -667,48 +754,16 @@ static int reload_logger(int rotate, const char *altconf) init_logger_chain(1 /* locked */, altconf); + ast_unload_realtime("queue_log"); if (logfiles.queue_log) { - do { - ast_unload_realtime("queue_log"); - if (ast_check_realtime("queue_log")) { - if (!ast_realtime_require_field("queue_log", - "time", RQ_DATETIME, 26, "data1", RQ_CHAR, 20, - "data2", RQ_CHAR, 20, "data3", RQ_CHAR, 20, - "data4", RQ_CHAR, 20, "data5", RQ_CHAR, 20, SENTINEL)) { - logfiles.queue_adaptive_realtime = 1; - } else { - logfiles.queue_adaptive_realtime = 0; - } - - if (!logfiles.queue_log_to_file) { - /* Skip the following section */ - break; - } - } - if (qlog) { - fclose(qlog); - qlog = NULL; - } - snprintf(old, sizeof(old), "%s/%s", ast_config_AST_LOG_DIR, queue_log_name); - if (queue_rotate) { - rotate_file(old); - } - - qlog = fopen(old, "a"); - if (qlog) { - AST_RWLIST_UNLOCK(&logchannels); - ast_queue_log("NONE", "NONE", "NONE", "CONFIGRELOAD", "%s", ""); - AST_RWLIST_WRLOCK(&logchannels); - ast_verb(1, "Asterisk Queue Logger restarted\n"); - } else { - ast_log(LOG_ERROR, "Unable to create queue log: %s\n", strerror(errno)); - res = -1; - } - } while (0); + res = logger_queue_restart(queue_rotate); + AST_RWLIST_UNLOCK(&logchannels); + ast_queue_log("NONE", "NONE", "NONE", "CONFIGRELOAD", "%s", ""); + ast_verb(1, "Asterisk Queue Logger restarted\n"); + } else { + AST_RWLIST_UNLOCK(&logchannels); } - AST_RWLIST_UNLOCK(&logchannels); - return res; } @@ -1012,22 +1067,36 @@ static void *logger_thread(void *data) return NULL; } +/*! + * \internal + * \brief Initialize the logger queue. + * + * \note Assumes logchannels is write locked on entry. + * + * \return Nothing + */ static void logger_queue_init(void) { - /* Preloaded modules are up. */ ast_unload_realtime("queue_log"); - if (logfiles.queue_log && ast_check_realtime("queue_log")) { - if (!ast_realtime_require_field("queue_log", - "time", RQ_DATETIME, 26, "data1", RQ_CHAR, 20, - "data2", RQ_CHAR, 20, "data3", RQ_CHAR, 20, - "data4", RQ_CHAR, 20, "data5", RQ_CHAR, 20, SENTINEL)) { - logfiles.queue_adaptive_realtime = 1; - } else { - logfiles.queue_adaptive_realtime = 0; + if (logfiles.queue_log) { + char qfname[PATH_MAX]; + + if (logger_queue_rt_start()) { + return; } - } - ast_queue_log("NONE", "NONE", "NONE", "QUEUESTART", "%s", ""); + /* Open the log file. */ + snprintf(qfname, sizeof(qfname), "%s/%s", ast_config_AST_LOG_DIR, + queue_log_name); + if (qlog) { + /* Just in case it was already open. */ + fclose(qlog); + } + qlog = fopen(qfname, "a"); + if (!qlog) { + ast_log(LOG_ERROR, "Unable to create queue log: %s\n", strerror(errno)); + } + } } int init_logger(void) @@ -1049,6 +1118,7 @@ int init_logger(void) /* create log channels */ init_logger_chain(0 /* locked */, NULL); + logger_initialized = 1; return 0; } @@ -1057,6 +1127,8 @@ void close_logger(void) { struct logchannel *f = NULL; + logger_initialized = 0; + /* Stop logger thread */ AST_LIST_LOCK(&logmsgs); close_logger_thread = 1; -- cgit v1.2.3