mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +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