mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-05 12:16:00 +00:00
Allow each logging destination and console to have its own notion of the verbosity level.
Review: https://reviewboard.asterisk.org/r/1599 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@346391 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -101,6 +101,8 @@ struct logchannel {
|
||||
int disabled;
|
||||
/*! syslog facility */
|
||||
int facility;
|
||||
/*! Verbosity level */
|
||||
int verbosity;
|
||||
/*! Type of log channel */
|
||||
enum logtypes type;
|
||||
/*! logfile logging file pointer */
|
||||
@@ -209,19 +211,24 @@ AST_THREADSTORAGE(log_buf);
|
||||
|
||||
static void logger_queue_init(void);
|
||||
|
||||
static unsigned int make_components(const char *s, int lineno)
|
||||
static unsigned int make_components(const char *s, int lineno, int *verbosity)
|
||||
{
|
||||
char *w;
|
||||
unsigned int res = 0;
|
||||
char *stringp = ast_strdupa(s);
|
||||
unsigned int x;
|
||||
|
||||
*verbosity = 3;
|
||||
|
||||
while ((w = strsep(&stringp, ","))) {
|
||||
w = ast_skip_blanks(w);
|
||||
|
||||
if (!strcmp(w, "*")) {
|
||||
res = 0xFFFFFFFF;
|
||||
break;
|
||||
} else if (!strncasecmp(w, "verbose(", 8) && sscanf(w + 8, "%d)", verbosity) == 1) {
|
||||
res |= (1 << __LOG_VERBOSE);
|
||||
break;
|
||||
} else for (x = 0; x < ARRAY_LEN(levels); x++) {
|
||||
if (levels[x] && !strcasecmp(w, levels[x])) {
|
||||
res |= (1 << x);
|
||||
@@ -300,7 +307,7 @@ static struct logchannel *make_logchannel(const char *channel, const char *compo
|
||||
}
|
||||
chan->type = LOGTYPE_FILE;
|
||||
}
|
||||
chan->logmask = make_components(chan->components, lineno);
|
||||
chan->logmask = make_components(chan->components, lineno, &chan->verbosity);
|
||||
|
||||
return chan;
|
||||
}
|
||||
@@ -434,11 +441,6 @@ void ast_child_verbose(int level, const char *fmt, ...)
|
||||
va_list ap, aq;
|
||||
int size;
|
||||
|
||||
/* Don't bother, if the level isn't that high */
|
||||
if (option_verbose < level) {
|
||||
return;
|
||||
}
|
||||
|
||||
va_start(ap, fmt);
|
||||
va_copy(aq, ap);
|
||||
if ((size = vsnprintf(msg, 0, fmt, ap)) < 0) {
|
||||
@@ -968,15 +970,23 @@ static void ast_log_vsyslog(struct logmsg *msg)
|
||||
syslog(syslog_level, "%s", buf);
|
||||
}
|
||||
|
||||
/* These gymnastics are due to platforms which designate char as unsigned by
|
||||
* default. Level is the negative character -- offset by 1, because \0 is the
|
||||
* EOS delimiter. */
|
||||
#define VERBOSE_MAGIC2LEVEL(x) (((char) -*(signed char *) (x)) - 1)
|
||||
#define VERBOSE_HASMAGIC(x) (*(signed char *) (x) < 0)
|
||||
|
||||
/*! \brief Print a normal log message to the channels */
|
||||
static void logger_print_normal(struct logmsg *logmsg)
|
||||
{
|
||||
struct logchannel *chan = NULL;
|
||||
char buf[BUFSIZ];
|
||||
struct verb *v = NULL;
|
||||
int level = 0;
|
||||
|
||||
if (logmsg->level == __LOG_VERBOSE) {
|
||||
char *tmpmsg = ast_strdupa(logmsg->message + 1);
|
||||
level = VERBOSE_MAGIC2LEVEL(logmsg->message);
|
||||
/* Iterate through the list of verbosers and pass them the log message string */
|
||||
AST_RWLIST_RDLOCK(&verbosers);
|
||||
AST_RWLIST_TRAVERSE(&verbosers, v, list)
|
||||
@@ -990,8 +1000,13 @@ static void logger_print_normal(struct logmsg *logmsg)
|
||||
if (!AST_RWLIST_EMPTY(&logchannels)) {
|
||||
AST_RWLIST_TRAVERSE(&logchannels, chan, list) {
|
||||
/* If the channel is disabled, then move on to the next one */
|
||||
if (chan->disabled)
|
||||
if (chan->disabled) {
|
||||
continue;
|
||||
}
|
||||
if (logmsg->level == __LOG_VERBOSE && level > chan->verbosity) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check syslog channels */
|
||||
if (chan->type == LOGTYPE_SYSLOG && (chan->logmask & (1 << logmsg->level))) {
|
||||
ast_log_vsyslog(logmsg);
|
||||
@@ -1219,20 +1234,11 @@ void ast_log(int level, const char *file, int line, const char *function, const
|
||||
}
|
||||
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 (level != __LOG_VERBOSE && !(global_logmask & (1 << level)))
|
||||
return;
|
||||
|
||||
|
||||
/* Build string */
|
||||
va_start(ap, fmt);
|
||||
res = ast_str_set_va(&buf, BUFSIZ, fmt, ap);
|
||||
@@ -1492,13 +1498,31 @@ void ast_backtrace(void)
|
||||
#endif /* defined(HAVE_BKTR) */
|
||||
}
|
||||
|
||||
void __ast_verbose_ap(const char *file, int line, const char *func, const char *fmt, va_list ap)
|
||||
void __ast_verbose_ap(const char *file, int line, const char *func, int level, const char *fmt, va_list ap)
|
||||
{
|
||||
struct ast_str *buf = NULL;
|
||||
int res = 0;
|
||||
const char *prefix = level >= 4 ? VERBOSE_PREFIX_4 : level == 3 ? VERBOSE_PREFIX_3 : level == 2 ? VERBOSE_PREFIX_2 : level == 1 ? VERBOSE_PREFIX_1 : "";
|
||||
signed char magic = level > 127 ? -128 : -level - 1; /* 0 => -1, 1 => -2, etc. Can't pass NUL, as it is EOS-delimiter */
|
||||
|
||||
if (!(buf = ast_str_thread_get(&verbose_buf, VERBOSE_BUF_INIT_SIZE)))
|
||||
/* For compatibility with modules still calling ast_verbose() directly instead of using ast_verb() */
|
||||
if (level < 0) {
|
||||
if (!strncmp(fmt, VERBOSE_PREFIX_4, strlen(VERBOSE_PREFIX_4))) {
|
||||
magic = -5;
|
||||
} else if (!strncmp(fmt, VERBOSE_PREFIX_3, strlen(VERBOSE_PREFIX_3))) {
|
||||
magic = -4;
|
||||
} else if (!strncmp(fmt, VERBOSE_PREFIX_2, strlen(VERBOSE_PREFIX_2))) {
|
||||
magic = -3;
|
||||
} else if (!strncmp(fmt, VERBOSE_PREFIX_1, strlen(VERBOSE_PREFIX_1))) {
|
||||
magic = -2;
|
||||
} else {
|
||||
magic = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(buf = ast_str_thread_get(&verbose_buf, VERBOSE_BUF_INIT_SIZE))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ast_opt_timestamp) {
|
||||
struct timeval now;
|
||||
@@ -1509,12 +1533,12 @@ void __ast_verbose_ap(const char *file, int line, const char *func, const char *
|
||||
now = ast_tvnow();
|
||||
ast_localtime(&now, &tm, NULL);
|
||||
ast_strftime(date, sizeof(date), dateformat, &tm);
|
||||
datefmt = alloca(strlen(date) + 3 + strlen(fmt) + 1);
|
||||
sprintf(datefmt, "%c[%s] %s", 127, date, fmt);
|
||||
datefmt = alloca(strlen(date) + 3 + strlen(prefix) + strlen(fmt) + 1);
|
||||
sprintf(datefmt, "%c[%s] %s%s", (char) magic, date, prefix, fmt);
|
||||
fmt = datefmt;
|
||||
} else {
|
||||
char *tmp = alloca(strlen(fmt) + 2);
|
||||
sprintf(tmp, "%c%s", 127, fmt);
|
||||
char *tmp = alloca(strlen(prefix) + strlen(fmt) + 2);
|
||||
sprintf(tmp, "%c%s%s", (char) magic, prefix, fmt);
|
||||
fmt = tmp;
|
||||
}
|
||||
|
||||
@@ -1522,18 +1546,19 @@ void __ast_verbose_ap(const char *file, int line, const char *func, const char *
|
||||
res = ast_str_set_va(&buf, 0, fmt, ap);
|
||||
|
||||
/* If the build failed then we can drop this allocated message */
|
||||
if (res == AST_DYNSTR_BUILD_FAILED)
|
||||
if (res == AST_DYNSTR_BUILD_FAILED) {
|
||||
return;
|
||||
}
|
||||
|
||||
ast_log(__LOG_VERBOSE, file, line, func, "%s", ast_str_buffer(buf));
|
||||
}
|
||||
|
||||
void __ast_verbose(const char *file, int line, const char *func, const char *fmt, ...)
|
||||
void __ast_verbose(const char *file, int line, const char *func, int level, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
__ast_verbose_ap(file, line, func, fmt, ap);
|
||||
__ast_verbose_ap(file, line, func, level, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
@@ -1545,7 +1570,7 @@ void ast_verbose(const char *fmt, ...)
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
__ast_verbose_ap("", 0, "", fmt, ap);
|
||||
__ast_verbose_ap("", 0, "", 0, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
@@ -1592,7 +1617,7 @@ static void update_logchannels(void)
|
||||
global_logmask = 0;
|
||||
|
||||
AST_RWLIST_TRAVERSE(&logchannels, cur, list) {
|
||||
cur->logmask = make_components(cur->components, cur->lineno);
|
||||
cur->logmask = make_components(cur->components, cur->lineno, &cur->verbosity);
|
||||
global_logmask |= cur->logmask;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user