[Asterisk-cvs] asterisk logger.c,1.59,1.60

markster at lists.digium.com markster at lists.digium.com
Thu Mar 31 13:15:23 CST 2005


Update of /usr/cvsroot/asterisk
In directory mongoose.digium.com:/tmp/cvs-serv25466

Modified Files:
	logger.c 
Log Message:
Make logger respond better to lack of disk space and add "logger show channels" CLI (bug #3909 with minor mods)


Index: logger.c
===================================================================
RCS file: /usr/cvsroot/asterisk/logger.c,v
retrieving revision 1.59
retrieving revision 1.60
diff -u -d -r1.59 -r1.60
--- logger.c	28 Mar 2005 20:57:59 -0000	1.59
+++ logger.c	31 Mar 2005 19:08:51 -0000	1.60
@@ -23,6 +23,7 @@
 #include <asterisk/term.h>
 #include <asterisk/cli.h>
 #include <asterisk/utils.h>
+#include <asterisk/manager.h>
 #include <string.h>
 #include <stdlib.h>
 #include <errno.h>
@@ -56,6 +57,7 @@
 #endif
 
 static char dateformat[256] = "%b %e %T";		/* Original Asterisk Format */
+
 AST_MUTEX_DEFINE_STATIC(msglist_lock);
 AST_MUTEX_DEFINE_STATIC(loglock);
 static int pending_logger_reload = 0;
@@ -73,14 +75,20 @@
 
 static char hostname[256];
 
+enum logtypes {
+	LOGTYPE_SYSLOG,
+	LOGTYPE_FILE,
+	LOGTYPE_CONSOLE,
+};
+
 struct logchannel {
-	int logmask;
-	int facility; /* syslog */
-	int syslog; /* syslog flag */
-	int console;  /* console logging */
-	FILE *fileptr; /* logfile logging */
-	char filename[256];
-	struct logchannel *next;
+	int logmask;			/* What to log to this channel */
+	int disabled;			/* If this channel is disabled or not */
+	int facility; 			/* syslog facility */
+	enum logtypes type;		/* Type of log channel */
+	FILE *fileptr;			/* logfile logging file pointer */
+	char filename[256];		/* Filename */
+	struct logchannel *next;	/* Next channel in chain */
 };
 
 static struct logchannel *logchannels = NULL;
@@ -115,24 +123,24 @@
 	stringp=s;
 	w = strsep(&stringp, ",");
 	while(w) {
-	    while(*w && (*w < 33))
-		w++;
-	    if (!strcasecmp(w, "error")) 
-		res |= (1 << __LOG_ERROR);
-	    else if (!strcasecmp(w, "warning"))
-		res |= (1 << __LOG_WARNING);
-	    else if (!strcasecmp(w, "notice"))
-		res |= (1 << __LOG_NOTICE);
-	    else if (!strcasecmp(w, "event"))
-		res |= (1 << __LOG_EVENT);
-	    else if (!strcasecmp(w, "debug"))
-		res |= (1 << __LOG_DEBUG);
-	    else if (!strcasecmp(w, "verbose"))
-		res |= (1 << __LOG_VERBOSE);
-	    else {
-		fprintf(stderr, "Logfile Warning: Unknown keyword '%s' at line %d of logger.conf\n", w, lineno);
-	    }
-	    w = strsep(&stringp, ",");
+		while(*w && (*w < 33))
+			w++;
+		if (!strcasecmp(w, "error")) 
+			res |= (1 << __LOG_ERROR);
+		else if (!strcasecmp(w, "warning"))
+			res |= (1 << __LOG_WARNING);
+		else if (!strcasecmp(w, "notice"))
+			res |= (1 << __LOG_NOTICE);
+		else if (!strcasecmp(w, "event"))
+			res |= (1 << __LOG_EVENT);
+		else if (!strcasecmp(w, "debug"))
+			res |= (1 << __LOG_DEBUG);
+		else if (!strcasecmp(w, "verbose"))
+			res |= (1 << __LOG_VERBOSE);
+		else {
+			fprintf(stderr, "Logfile Warning: Unknown keyword '%s' at line %d of logger.conf\n", w, lineno);
+		}
+		w = strsep(&stringp, ",");
 	}
 	return res;
 }
@@ -152,79 +160,79 @@
 	if (chan) {
 		memset(chan, 0, sizeof(struct logchannel));
 		if (!strcasecmp(channel, "console")) {
-		    chan->console = 1;
+			chan->type = LOGTYPE_CONSOLE;
 		} else if (!strncasecmp(channel, "syslog", 6)) {
-		    /*
-		     * syntax is:
-		     *  syslog.facility => level,level,level
-		     */
-		    facility = strchr(channel, '.');
-		    if(!facility++ || !facility) {
-			facility = "local0";
-		    }
+			/*
+			* syntax is:
+			*  syslog.facility => level,level,level
+			*/
+			facility = strchr(channel, '.');
+			if(!facility++ || !facility) {
+				facility = "local0";
+			}
 
 #ifndef SOLARIS
-		    /*
-		     * Walk through the list of facilitynames (defined in sys/syslog.h)
-		     * to see if we can find the one we have been given
-		     */
-		    chan->facility = -1;
-		    cptr = facilitynames;
-		    while (cptr->c_name) {
-			if (!strcasecmp(facility, cptr->c_name)) {
-			    chan->facility = cptr->c_val;
-			    break;
+			/*
+		 	* Walk through the list of facilitynames (defined in sys/syslog.h)
+			* to see if we can find the one we have been given
+			*/
+			chan->facility = -1;
+		 	cptr = facilitynames;
+			while (cptr->c_name) {
+				if (!strcasecmp(facility, cptr->c_name)) {
+					    chan->facility = cptr->c_val;
+					    break;
+				}
+				cptr++;
 			}
-			cptr++;
-		    }
 #else
-		    chan->facility = -1;
-		    if (!strcasecmp(facility, "kern")) 
-			chan->facility = LOG_KERN;
-		    else if (!strcasecmp(facility, "USER")) 
-			chan->facility = LOG_USER;
-		    else if (!strcasecmp(facility, "MAIL")) 
-			chan->facility = LOG_MAIL;
-		    else if (!strcasecmp(facility, "DAEMON")) 
-			chan->facility = LOG_DAEMON;
-		    else if (!strcasecmp(facility, "AUTH")) 
-			chan->facility = LOG_AUTH;
-		    else if (!strcasecmp(facility, "SYSLOG")) 
-			chan->facility = LOG_SYSLOG;
-		    else if (!strcasecmp(facility, "LPR")) 
-			chan->facility = LOG_LPR;
-		    else if (!strcasecmp(facility, "NEWS")) 
-			chan->facility = LOG_NEWS;
-		    else if (!strcasecmp(facility, "UUCP")) 
-			chan->facility = LOG_UUCP;
-		    else if (!strcasecmp(facility, "CRON")) 
-			chan->facility = LOG_CRON;
-		    else if (!strcasecmp(facility, "LOCAL0")) 
-			chan->facility = LOG_LOCAL0;
-		    else if (!strcasecmp(facility, "LOCAL1")) 
-			chan->facility = LOG_LOCAL1;
-		    else if (!strcasecmp(facility, "LOCAL2")) 
-			chan->facility = LOG_LOCAL2;
-		    else if (!strcasecmp(facility, "LOCAL3")) 
-			chan->facility = LOG_LOCAL3;
-		    else if (!strcasecmp(facility, "LOCAL4")) 
-			chan->facility = LOG_LOCAL4;
-		    else if (!strcasecmp(facility, "LOCAL5")) 
-			chan->facility = LOG_LOCAL5;
-		    else if (!strcasecmp(facility, "LOCAL6")) 
-			chan->facility = LOG_LOCAL6;
-		    else if (!strcasecmp(facility, "LOCAL7")) 
-			chan->facility = LOG_LOCAL7;
-#endif
+			chan->facility = -1;
+			if (!strcasecmp(facility, "kern")) 
+				chan->facility = LOG_KERN;
+			else if (!strcasecmp(facility, "USER")) 
+				chan->facility = LOG_USER;
+			else if (!strcasecmp(facility, "MAIL")) 
+				chan->facility = LOG_MAIL;
+			else if (!strcasecmp(facility, "DAEMON")) 
+				chan->facility = LOG_DAEMON;
+			else if (!strcasecmp(facility, "AUTH")) 
+				chan->facility = LOG_AUTH;
+			else if (!strcasecmp(facility, "SYSLOG")) 
+				chan->facility = LOG_SYSLOG;
+			else if (!strcasecmp(facility, "LPR")) 
+				chan->facility = LOG_LPR;
+			else if (!strcasecmp(facility, "NEWS")) 
+				chan->facility = LOG_NEWS;
+			else if (!strcasecmp(facility, "UUCP")) 
+				chan->facility = LOG_UUCP;
+			else if (!strcasecmp(facility, "CRON")) 
+				chan->facility = LOG_CRON;
+			else if (!strcasecmp(facility, "LOCAL0")) 
+				chan->facility = LOG_LOCAL0;
+			else if (!strcasecmp(facility, "LOCAL1")) 
+				chan->facility = LOG_LOCAL1;
+			else if (!strcasecmp(facility, "LOCAL2")) 
+				chan->facility = LOG_LOCAL2;
+			else if (!strcasecmp(facility, "LOCAL3")) 
+				chan->facility = LOG_LOCAL3;
+			else if (!strcasecmp(facility, "LOCAL4")) 
+				chan->facility = LOG_LOCAL4;
+			else if (!strcasecmp(facility, "LOCAL5")) 
+				chan->facility = LOG_LOCAL5;
+			else if (!strcasecmp(facility, "LOCAL6")) 
+				chan->facility = LOG_LOCAL6;
+			else if (!strcasecmp(facility, "LOCAL7")) 
+				chan->facility = LOG_LOCAL7;
+#endif /* Solaris */
 
-		    if (0 > chan->facility) {
-			fprintf(stderr, "Logger Warning: bad syslog facility in logger.conf\n");
-			free(chan);
-			return NULL;
-		    }
+			if (0 > chan->facility) {
+				fprintf(stderr, "Logger Warning: bad syslog facility in logger.conf\n");
+				free(chan);
+				return NULL;
+			}
 
-		    chan->syslog = 1;
-		    openlog("asterisk", LOG_PID, chan->facility);
+			chan->type = LOGTYPE_SYSLOG;
+			openlog("asterisk", LOG_PID, chan->facility);
 		} else {
 			if (channel[0] == '/') {
 				if(!ast_strlen_zero(hostname)) { 
@@ -243,7 +251,8 @@
 			if (!chan->fileptr) {
 				/* Can't log here, since we're called with a lock */
 				fprintf(stderr, "Logger Warning: Unable to open log file '%s': %s\n", chan->filename, strerror(errno));
-			}
+			} 
+			chan->type = LOGTYPE_FILE;
 		}
 		chan->logmask = make_components(components, lineno);
 	}
@@ -261,9 +270,9 @@
 	ast_mutex_lock(&loglock);
 	chan = logchannels;
 	while (chan) {
-	    cur = chan->next;
-	    free(chan);
-	    chan = cur;
+		cur = chan->next;
+		free(chan);
+		chan = cur;
 	}
 	logchannels = NULL;
 	ast_mutex_unlock(&loglock);
@@ -276,7 +285,7 @@
 	
 	/* If no config file, we're fine */
 	if (!cfg)
-	    return;
+		return;
 	
 	ast_mutex_lock(&loglock);
 	if ((s = ast_variable_retrieve(cfg, "general", "appendhostname"))) {
@@ -337,6 +346,7 @@
 {
 	char filename[256];
 	int reloaded = 0;
+
 	ast_mutex_lock(&qloglock);
 	if (qlog) {
 		reloaded = 1;
@@ -360,8 +370,8 @@
 	char new[AST_CONFIG_MAX_PATH];
 	struct logchannel *f;
 	FILE *myf;
-
 	int x;
+
 	ast_mutex_lock(&loglock);
 	if (eventlog) 
 		fclose(eventlog);
@@ -369,8 +379,6 @@
 		rotate = 0;
 	eventlog = NULL;
 
-
-
 	mkdir((char *)ast_config_AST_LOG_DIR, 0755);
 	snprintf(old, sizeof(old), "%s/%s", (char *)ast_config_AST_LOG_DIR, EVENTLOG);
 
@@ -379,7 +387,7 @@
 			for (x=0;;x++) {
 				snprintf(new, sizeof(new), "%s/%s.%d", (char *)ast_config_AST_LOG_DIR, EVENTLOG,x);
 				myf = fopen((char *)new, "r");
-				if (myf) 
+				if (myf) 	/* File exists */
 					fclose(myf);
 				else
 					break;
@@ -395,8 +403,12 @@
 
 	f = logchannels;
 	while(f) {
+		if (f->disabled) {
+			f->disabled = 0;	/* Re-enable logging at reload */
+			manager_event(EVENT_FLAG_SYSTEM, "LogChannel", "Channel: %s\r\nEnabled: Yes\r\n", f->filename);
+		}
 		if (f->fileptr && (f->fileptr != stdout) && (f->fileptr != stderr)) {
-			fclose(f->fileptr);
+			fclose(f->fileptr);	/* Close file */
 			f->fileptr = NULL;
 			if(rotate) {
 				strncpy(old, f->filename, sizeof(old) - 1);
@@ -439,26 +451,62 @@
 
 static int handle_logger_reload(int fd, int argc, char *argv[])
 {
-	if(reload_logger(0))
-	{
+	if(reload_logger(0)) {
 		ast_cli(fd, "Failed to reload the logger\n");
 		return RESULT_FAILURE;
-	}
-	else
+	} else
 		return RESULT_SUCCESS;
 }
 
 static int handle_logger_rotate(int fd, int argc, char *argv[])
 {
-	if(reload_logger(1))
-	{
+	if(reload_logger(1)) {
 		ast_cli(fd, "Failed to reload the logger and rotate log files\n");
 		return RESULT_FAILURE;
-	}
-	else
+	} else
 		return RESULT_SUCCESS;
 }
 
+/*--- handle_logger_show_channels: CLI command to show logging system 
+ 	configuration */
+static int handle_logger_show_channels(int fd, int argc, char *argv[])
+{
+#define FORMATL	"%-35.35s %-8.8s %-9.9s "
+	struct logchannel *chan;
+
+	ast_mutex_lock(&loglock);
+
+	chan = logchannels;
+	ast_cli(fd,FORMATL, "Channel", "Type", "Status");
+	ast_cli(fd, "Configuration\n");
+	ast_cli(fd,FORMATL, "-------", "----", "------");
+	ast_cli(fd, "-------------\n");
+	while (chan) {
+		ast_cli(fd, FORMATL, chan->filename, chan->type==LOGTYPE_CONSOLE ? "Console" : (chan->type==LOGTYPE_SYSLOG ? "Syslog" : "File"),
+			chan->disabled ? "Disabled" : "Enabled");
+		ast_cli(fd, " - ");
+		if (chan->logmask & (1 << __LOG_DEBUG)) 
+			ast_cli(fd, "Debug ");
+		if (chan->logmask & (1 << __LOG_VERBOSE)) 
+			ast_cli(fd, "Verbose ");
+		if (chan->logmask & (1 << __LOG_WARNING)) 
+			ast_cli(fd, "Warning ");
+		if (chan->logmask & (1 << __LOG_NOTICE)) 
+			ast_cli(fd, "Notice ");
+		if (chan->logmask & (1 << __LOG_ERROR)) 
+			ast_cli(fd, "Error ");
+		if (chan->logmask & (1 << __LOG_EVENT)) 
+			ast_cli(fd, "Event ");
+		ast_cli(fd, "\n");
+		chan = chan->next;
+	}
+	ast_cli(fd, "\n");
+
+	ast_mutex_unlock(&loglock);
+ 		
+	return RESULT_SUCCESS;
+}
+
 static struct verb {
 	void (*verboser)(const char *string, int opos, int replacelast, int complete);
 	struct verb *next;
@@ -467,12 +515,21 @@
 
 static char logger_reload_help[] =
 "Usage: logger reload\n"
-"       Reloads the logger subsystem state.  Use after restarting syslogd(8)\n";
+"       Reloads the logger subsystem state.  Use after restarting syslogd(8) if you are using syslog logging.\n";
 
 static char logger_rotate_help[] =
 "Usage: logger rotate\n"
 "       Rotates and Reopens the log files.\n";
 
+static char logger_show_channels_help[] =
+"Usage: logger show channels\n"
+"       Show configured logger channels.\n";
+
+static struct ast_cli_entry logger_show_channels_cli = 
+	{ { "logger", "show", "channels", NULL }, 
+	handle_logger_show_channels, "List configured log channels",
+	logger_show_channels_help };
+
 static struct ast_cli_entry reload_logger_cli = 
 	{ { "logger", "reload", NULL }, 
 	handle_logger_reload, "Reopens the log files",
@@ -500,6 +557,7 @@
 	/* register the relaod logger cli command */
 	ast_cli_register(&reload_logger_cli);
 	ast_cli_register(&rotate_logger_cli);
+	ast_cli_register(&logger_show_channels_cli);
 
 	/* initialize queue logger */
 	queue_log_init();
@@ -609,12 +667,14 @@
 
 	if (logchannels) {
 		chan = logchannels;
-		while(chan) {
-			if (chan->syslog && (chan->logmask & (1 << level))) {
+		while(chan && !chan->disabled) {
+			/* Check syslog channels */
+			if (chan->type == LOG_SYSLOG && (chan->logmask & (1 << level))) {
 				va_start(ap, fmt);
 				ast_log_vsyslog(level, file, line, function, fmt, ap);
 				va_end(ap);
-			} else if ((chan->logmask & (1 << level)) && (chan->console)) {
+			/* Console channels */
+			} else if ((chan->logmask & (1 << level)) && (chan->type == LOGTYPE_CONSOLE)) {
 				char linestr[128];
 				char tmp1[80], tmp2[80], tmp3[80], tmp4[80];
 
@@ -634,15 +694,28 @@
 					va_end(ap);
 					ast_console_puts(buf);
 				}
+			/* File channels */
 			} else if ((chan->logmask & (1 << level)) && (chan->fileptr)) {
-				snprintf(buf, sizeof(buf), option_timestamp ? "[%s] %s[%ld]: " : "%s %s[%ld]: ", date,
-					levels[level], (long)GETTID());
-				fprintf(chan->fileptr, buf);
-				va_start(ap, fmt);
-				vsnprintf(buf, sizeof(buf), fmt, ap);
-				va_end(ap);
-				fputs(buf, chan->fileptr);
-				fflush(chan->fileptr);
+				int res;
+				snprintf(buf, sizeof(buf), option_timestamp ? "[%s] %s[%ld]: " : "%s %s[%ld] %s: ", date,
+					levels[level], (long)GETTID(), file);
+				res = fprintf(chan->fileptr, buf);
+				if (res <= 0 && buf[0] != '\0') {	/* Error, no characters printed */
+					fprintf(stderr,"**** Asterisk Logging Error: ***********\n");
+					if (errno == ENOMEM || errno == ENOSPC) {
+						fprintf(stderr, "Asterisk logging error: Out of disk space, can't log to log file %s\n", chan->filename);
+					} else
+						fprintf(stderr, "Logger Warning: Unable to write to log file '%s': %s (disabled)\n", chan->filename, strerror(errno));
+					manager_event(EVENT_FLAG_SYSTEM, "LogChannel", "Channel: %s\r\nEnabled: No\r\nReason: %d - %s\r\n", chan->filename, errno, strerror(errno));
+					chan->disabled = 1;	
+				} else {
+					/* No error message, continue printing */
+					va_start(ap, fmt);
+					vsnprintf(buf, sizeof(buf), fmt, ap);
+					va_end(ap);
+					fputs(buf, chan->fileptr);
+					fflush(chan->fileptr);
+				}
 			}
 			chan = chan->next;
 		}
@@ -663,9 +736,9 @@
 	/* end critical section */
 	if (pending_logger_reload) {
 		reload_logger(1);
-		ast_log(LOG_EVENT,"Rotated Logs Per SIGXFSZ\n");
+		ast_log(LOG_EVENT,"Rotated Logs Per SIGXFSZ (Exceeded file size limit)\n");
 		if (option_verbose)
-			ast_verbose("Rotated Logs Per SIGXFSZ\n");
+			ast_verbose("Rotated Logs Per SIGXFSZ (Exceeded file size limit)\n");
 	}
 }
 




More information about the svn-commits mailing list