diff options
Diffstat (limited to 'net/asterisk/files/patch-suppress_log_dups.diff')
-rw-r--r-- | net/asterisk/files/patch-suppress_log_dups.diff | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/net/asterisk/files/patch-suppress_log_dups.diff b/net/asterisk/files/patch-suppress_log_dups.diff new file mode 100644 index 000000000000..115b69f21ca1 --- /dev/null +++ b/net/asterisk/files/patch-suppress_log_dups.diff @@ -0,0 +1,270 @@ +Index: main/logger.c +=================================================================== +--- main/logger.c (revision 188505) ++++ main/logger.c (working copy) +@@ -140,6 +140,17 @@ + AST_THREADSTORAGE(log_buf, log_buf_init); + #define LOG_BUF_INIT_SIZE 128 + ++/* ++ * Storage for previous log message to prevent log storms ++ */ ++static int stored_log_level; ++static int stored_log_dup_count = 0; ++static char *stored_log_msg = NULL; ++static const char *stored_log_file; ++static int stored_log_line; ++static const char *stored_log_function; ++static ast_mutex_t stored_log_msg_lock; ++ + static int make_components(char *s, int lineno) + { + char *w; +@@ -591,6 +602,8 @@ + char tmp[256]; + int res = 0; + ++ ast_mutex_init(&stored_log_msg_lock); ++ + /* auto rotate if sig SIGXFSZ comes a-knockin */ + (void) signal(SIGXFSZ,(void *) handle_SIGXFSZ); + +@@ -655,14 +668,14 @@ + return; + } + +-static void __attribute__((format(printf, 5, 0))) ast_log_vsyslog(int level, const char *file, int line, const char *function, const char *fmt, va_list args) ++static void ast_log_syslog(int level, const char *file, int line, const char *function, const char *msg) + { + char buf[BUFSIZ]; + char *s; + + if (level >= SYSLOG_NLEVELS) { + /* we are locked here, so cannot ast_log() */ +- fprintf(stderr, "ast_log_vsyslog called with bogus level: %d\n", level); ++ fprintf(stderr, "ast_log_syslog called with bogus level: %d\n", level); + return; + } + if (level == __LOG_VERBOSE) { +@@ -676,27 +689,20 @@ + levels[level], (long)GETTID(), file, line, function); + } + s = buf + strlen(buf); +- vsnprintf(s, sizeof(buf) - strlen(buf), fmt, args); ++ snprintf(s, sizeof(buf) - strlen(buf), "%s", msg); + term_strip(s, s, strlen(s) + 1); + syslog(syslog_level_map[level], "%s", buf); + } + +-/*! +- * \brief send log messages to syslog and/or the console +- */ +-void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...) ++static void __ast_log(int level, const char *file, int line, const char *function, char *msg, int msglen) + { + struct logchannel *chan; +- struct ast_dynamic_str *buf; + time_t t; + struct tm tm; + char date[256]; ++ char buf[2048]; ++ int res; + +- va_list ap; +- +- if (!(buf = ast_dynamic_str_thread_get(&log_buf, LOG_BUF_INIT_SIZE))) +- return; +- + if (AST_LIST_EMPTY(&logchannels)) + { + /* +@@ -704,35 +710,12 @@ + * so just log to stdout + */ + if (level != __LOG_VERBOSE) { +- int res; +- va_start(ap, fmt); +- res = ast_dynamic_str_thread_set_va(&buf, BUFSIZ, &log_buf, fmt, ap); +- va_end(ap); +- if (res != AST_DYNSTR_BUILD_FAILED) { +- term_filter_escapes(buf->str); +- fputs(buf->str, stdout); +- } ++ term_filter_escapes(msg); ++ fputs(msg, stdout); + } + return; + } + +- /* don't display LOG_DEBUG messages unless option_verbose _or_ option_debug +- are non-zero; LOG_DEBUG messages can still be displayed if option_debug +- is zero, if option_verbose is non-zero (this allows for 'level zero' +- LOG_DEBUG messages to be displayed, if the logmask on any channel +- allows it) +- */ +- if (!option_verbose && !option_debug && (level == __LOG_DEBUG)) +- return; +- +- /* Ignore anything that never gets logged anywhere */ +- if (!(global_logmask & (1 << level))) +- return; +- +- /* Ignore anything other than the currently debugged file if there is one */ +- if ((level == __LOG_DEBUG) && !ast_strlen_zero(debug_filename) && strcasecmp(debug_filename, file)) +- return; +- + time(&t); + ast_localtime(&t, &tm, NULL); + strftime(date, sizeof(date), dateformat, &tm); +@@ -740,13 +723,8 @@ + AST_LIST_LOCK(&logchannels); + + if (logfiles.event_log && level == __LOG_EVENT) { +- va_start(ap, fmt); +- +- fprintf(eventlog, "%s asterisk[%ld]: ", date, (long)getpid()); +- vfprintf(eventlog, fmt, ap); ++ fprintf(eventlog, "%s asterisk[%ld]: %s", date, (long)getpid(), msg); + fflush(eventlog); +- +- va_end(ap); + AST_LIST_UNLOCK(&logchannels); + return; + } +@@ -756,18 +734,15 @@ + break; + /* Check syslog channels */ + if (chan->type == LOGTYPE_SYSLOG && (chan->logmask & (1 << level))) { +- va_start(ap, fmt); +- ast_log_vsyslog(level, file, line, function, fmt, ap); +- va_end(ap); ++ ast_log_syslog(level, file, line, function, msg); + /* Console channels */ + } else if ((chan->logmask & (1 << level)) && (chan->type == LOGTYPE_CONSOLE)) { + char linestr[128]; + char tmp1[80], tmp2[80], tmp3[80], tmp4[80]; + + if (level != __LOG_VERBOSE) { +- int res; + sprintf(linestr, "%d", line); +- ast_dynamic_str_thread_set(&buf, BUFSIZ, &log_buf, ++ snprintf(buf, sizeof(buf), + "[%s] %s[%ld]: %s:%s %s: ", + date, + term_color(tmp1, levels[level], colors[level], 0, sizeof(tmp1)), +@@ -776,23 +751,17 @@ + term_color(tmp3, linestr, COLOR_BRWHITE, 0, sizeof(tmp3)), + term_color(tmp4, function, COLOR_BRWHITE, 0, sizeof(tmp4))); + /*filter to the console!*/ +- term_filter_escapes(buf->str); +- ast_console_puts_mutable(buf->str); +- +- va_start(ap, fmt); +- res = ast_dynamic_str_thread_set_va(&buf, BUFSIZ, &log_buf, fmt, ap); +- va_end(ap); +- if (res != AST_DYNSTR_BUILD_FAILED) +- ast_console_puts_mutable(buf->str); ++ term_filter_escapes(buf); ++ ast_console_puts_mutable(buf); ++ ast_console_puts_mutable(msg); + } + /* File channels */ + } else if ((chan->logmask & (1 << level)) && (chan->fileptr)) { +- int res; +- ast_dynamic_str_thread_set(&buf, BUFSIZ, &log_buf, ++ snprintf(buf, sizeof(buf), + "[%s] %s[%ld] %s: ", + date, levels[level], (long)GETTID(), file); +- res = fprintf(chan->fileptr, "%s", buf->str); +- if (res <= 0 && !ast_strlen_zero(buf->str)) { /* Error, no characters printed */ ++ res = fprintf(chan->fileptr, "%s", buf); ++ if (res <= 0 && !ast_strlen_zero(buf)) { /* 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); +@@ -801,16 +770,10 @@ + 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 { +- int res; + /* No error message, continue printing */ +- va_start(ap, fmt); +- res = ast_dynamic_str_thread_set_va(&buf, BUFSIZ, &log_buf, fmt, ap); +- va_end(ap); +- if (res != AST_DYNSTR_BUILD_FAILED) { +- term_strip(buf->str, buf->str, buf->len); +- fputs(buf->str, chan->fileptr); +- fflush(chan->fileptr); +- } ++ term_strip(msg, msg, msglen); ++ fputs(msg, chan->fileptr); ++ fflush(chan->fileptr); + } + } + } +@@ -825,6 +788,65 @@ + } + } + ++/*! ++ * \brief send log messages to syslog and/or the console ++ */ ++void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...) ++{ ++ struct ast_dynamic_str *buf; ++ int res; ++ va_list ap; ++ ++ if (!(buf = ast_dynamic_str_thread_get(&log_buf, LOG_BUF_INIT_SIZE))) ++ return; ++ ++ va_start(ap, fmt); ++ res = ast_dynamic_str_thread_set_va(&buf, BUFSIZ, &log_buf, fmt, ap); ++ va_end(ap); ++ if (res == AST_DYNSTR_BUILD_FAILED) ++ return; ++ ++ /* don't display LOG_DEBUG messages unless option_verbose _or_ option_debug ++ are non-zero; LOG_DEBUG messages can still be displayed if option_debug ++ is zero, if option_verbose is non-zero (this allows for 'level zero' ++ LOG_DEBUG messages to be displayed, if the logmask on any channel ++ allows it) ++ */ ++ if (!option_verbose && !option_debug && (level == __LOG_DEBUG)) ++ return; ++ ++ /* Ignore anything that never gets logged anywhere */ ++ if (!(global_logmask & (1 << level))) ++ return; ++ ++ /* Ignore anything other than the currently debugged file if there is one */ ++ if ((level == __LOG_DEBUG) && !ast_strlen_zero(debug_filename) && strcasecmp(debug_filename, file)) ++ return; ++ ++ ast_mutex_lock(&stored_log_msg_lock); ++ if (stored_log_msg == NULL || stored_log_level != level || strcmp(buf->str, stored_log_msg) != 0) { ++ if (stored_log_dup_count > 0) { ++ char buf2[1024]; ++ ++ snprintf(buf2, sizeof(buf2), "Last message repeated %d times\n", stored_log_dup_count); ++ __ast_log(stored_log_level, stored_log_file, stored_log_line, stored_log_function, buf2, strlen(buf2)); ++ } ++ if (stored_log_msg != NULL) ++ ast_free(stored_log_msg); ++ stored_log_msg = ast_strdup(buf->str); ++ stored_log_level = level; ++ stored_log_dup_count = 0; ++ stored_log_file = file; ++ stored_log_line = line; ++ stored_log_function = function; ++ __ast_log(level, file, line, function, buf->str, buf->len); ++ } ++ else ++ ++stored_log_dup_count; ++ ++ ast_mutex_unlock(&stored_log_msg_lock); ++} ++ + void ast_backtrace(void) + { + #ifdef linux |