mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-26 22:30:28 +00:00
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/branches/1.8@331461 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
186
main/logger.c
186
main/logger.c
@@ -79,6 +79,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 */
|
||||
@@ -397,11 +398,10 @@ static void init_logger_chain(int locked)
|
||||
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) {
|
||||
@@ -469,9 +469,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")) {
|
||||
@@ -487,7 +503,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], "")),
|
||||
@@ -609,6 +626,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -625,9 +644,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)
|
||||
{
|
||||
char old[PATH_MAX] = "";
|
||||
int queue_rotate = rotate;
|
||||
struct logchannel *f;
|
||||
int res = 0;
|
||||
@@ -676,48 +763,16 @@ static int reload_logger(int rotate)
|
||||
|
||||
init_logger_chain(1 /* locked */);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1021,22 +1076,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;
|
||||
}
|
||||
|
||||
/* 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));
|
||||
}
|
||||
}
|
||||
|
||||
ast_queue_log("NONE", "NONE", "NONE", "QUEUESTART", "%s", "");
|
||||
}
|
||||
|
||||
int init_logger(void)
|
||||
@@ -1058,6 +1127,7 @@ int init_logger(void)
|
||||
|
||||
/* create log channels */
|
||||
init_logger_chain(0 /* locked */);
|
||||
logger_initialized = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1066,6 +1136,8 @@ void close_logger(void)
|
||||
{
|
||||
struct logchannel *f = NULL;
|
||||
|
||||
logger_initialized = 0;
|
||||
|
||||
/* Stop logger thread */
|
||||
AST_LIST_LOCK(&logmsgs);
|
||||
close_logger_thread = 1;
|
||||
|
||||
Reference in New Issue
Block a user