@ -54,7 +54,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
from < syslog . h > which is included by logger . h */
from < syslog . h > which is included by logger . h */
# include <syslog.h>
# include <syslog.h>
static int syslog_level_map [ ] = {
static const int syslog_level_map [ ] = {
LOG_DEBUG ,
LOG_DEBUG ,
LOG_INFO , /* arbitrary equivalent of LOG_EVENT */
LOG_INFO , /* arbitrary equivalent of LOG_EVENT */
LOG_NOTICE ,
LOG_NOTICE ,
@ -89,14 +89,13 @@ static int syslog_level_map[] = {
# else
# else
# define GETTID() getpid()
# define GETTID() getpid()
# endif
# endif
static char dateformat [ 256 ] = " %b %e %T " ; /* Original Asterisk Format */
static char dateformat [ 256 ] = " %b %e %T " ; /* Original Asterisk Format */
static char queue_log_name [ 256 ] = QUEUELOG ;
static char queue_log_name [ 256 ] = QUEUELOG ;
static char exec_after_rotate [ 256 ] = " " ;
static char exec_after_rotate [ 256 ] = " " ;
static int filesize_reload_needed ;
static int filesize_reload_needed ;
static int global_logmask = - 1 ;
static unsigned int global_logmask = 0xFFFF ;
enum rotatestrategy {
enum rotatestrategy {
SEQUENTIAL = 1 < < 0 , /* Original method - create a new file, in order */
SEQUENTIAL = 1 < < 0 , /* Original method - create a new file, in order */
@ -117,13 +116,24 @@ enum logtypes {
} ;
} ;
struct logchannel {
struct logchannel {
int logmask ; /* What to log to this channel */
/*! What to log to this channel */
int disabled ; /* If this channel is disabled or not */
unsigned int logmask ;
int facility ; /* syslog facility */
/*! If this channel is disabled or not */
enum logtypes type ; /* Type of log channel */
int disabled ;
FILE * fileptr ; /* logfile logging file pointer */
/*! syslog facility */
char filename [ 256 ] ; /* Filename */
int facility ;
/*! Type of log channel */
enum logtypes type ;
/*! logfile logging file pointer */
FILE * fileptr ;
/*! Filename */
char filename [ PATH_MAX ] ;
/*! field for linking to list */
AST_LIST_ENTRY ( logchannel ) list ;
AST_LIST_ENTRY ( logchannel ) list ;
/*! Line number from configuration file */
int lineno ;
/*! Components (levels) from last config load */
char components [ 0 ] ;
} ;
} ;
static AST_RWLIST_HEAD_STATIC ( logchannels , logchannel ) ;
static AST_RWLIST_HEAD_STATIC ( logchannels , logchannel ) ;
@ -135,14 +145,17 @@ enum logmsgtypes {
struct logmsg {
struct logmsg {
enum logmsgtypes type ;
enum logmsgtypes type ;
char date [ 256 ] ;
int level ;
int level ;
char file [ 80 ] ;
int line ;
int line ;
char function [ 80 ] ;
long process_id ;
long process_id ;
AST_DECLARE_STRING_FIELDS (
AST_STRING_FIELD ( date ) ;
AST_STRING_FIELD ( file ) ;
AST_STRING_FIELD ( function ) ;
AST_STRING_FIELD ( message ) ;
AST_STRING_FIELD ( level_name ) ;
) ;
AST_LIST_ENTRY ( logmsg ) list ;
AST_LIST_ENTRY ( logmsg ) list ;
char str [ 0 ] ;
} ;
} ;
static AST_LIST_HEAD_STATIC ( logmsgs , logmsg ) ;
static AST_LIST_HEAD_STATIC ( logmsgs , logmsg ) ;
@ -152,26 +165,61 @@ static int close_logger_thread;
static FILE * qlog ;
static FILE * qlog ;
/*! \brief Logging channels used in the Asterisk logging system */
/*! \brief Logging channels used in the Asterisk logging system
static char * levels [ ] = {
*
* The first 16 levels are reserved for system usage , and the remaining
* levels are reserved for usage by dynamic levels registered via
* ast_logger_register_level .
*/
/* Modifications to this array are protected by the rwlock in the
* logchannels list .
*/
static char * levels [ 32 ] = {
" DEBUG " ,
" DEBUG " ,
" ---EVENT--- " , /* no longer used */
" ---EVENT--- " , /* no longer used */
" NOTICE " ,
" NOTICE " ,
" WARNING " ,
" WARNING " ,
" ERROR " ,
" ERROR " ,
" VERBOSE " ,
" VERBOSE " ,
" DTMF "
" DTMF " ,
} ;
} ;
/*! \brief Colors used in the console for logging */
/*! \brief Colors used in the console for logging */
static int colors [ ] = {
static const int colors [ 32 ] = {
COLOR_BRGREEN ,
COLOR_BRGREEN ,
COLOR_BRBLUE ,
COLOR_BRBLUE , /* no longer used */
COLOR_YELLOW ,
COLOR_YELLOW ,
COLOR_BRRED ,
COLOR_BRRED ,
COLOR_RED ,
COLOR_RED ,
COLOR_GREEN ,
COLOR_GREEN ,
COLOR_BRGREEN
COLOR_BRGREEN ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
COLOR_BRBLUE ,
COLOR_BRBLUE ,
COLOR_BRBLUE ,
COLOR_BRBLUE ,
COLOR_BRBLUE ,
COLOR_BRBLUE ,
COLOR_BRBLUE ,
COLOR_BRBLUE ,
COLOR_BRBLUE ,
COLOR_BRBLUE ,
COLOR_BRBLUE ,
COLOR_BRBLUE ,
COLOR_BRBLUE ,
COLOR_BRBLUE ,
COLOR_BRBLUE ,
COLOR_BRBLUE ,
} ;
} ;
AST_THREADSTORAGE ( verbose_buf ) ;
AST_THREADSTORAGE ( verbose_buf ) ;
@ -180,28 +228,24 @@ AST_THREADSTORAGE(verbose_buf);
AST_THREADSTORAGE ( log_buf ) ;
AST_THREADSTORAGE ( log_buf ) ;
# define LOG_BUF_INIT_SIZE 256
# define LOG_BUF_INIT_SIZE 256
static int make_components ( const char * s , int lineno )
static unsigned int make_components ( const char * s , int lineno )
{
{
char * w ;
char * w ;
int res = 0 ;
unsigned int res = 0 ;
char * stringp = ast_strdupa ( s ) ;
char * stringp = ast_strdupa ( s ) ;
unsigned int x ;
while ( ( w = strsep ( & stringp , " , " ) ) ) {
while ( ( w = strsep ( & stringp , " , " ) ) ) {
int found = 0 ;
w = ast_skip_blanks ( w ) ;
w = ast_skip_blanks ( w ) ;
if ( ! strcasecmp ( w , " error " ) )
res | = ( 1 < < __LOG_ERROR ) ;
for ( x = 0 ; x < ARRAY_LEN ( levels ) ; x + + ) {
else if ( ! strcasecmp ( w , " warning " ) )
if ( levels [ x ] & & ! strcasecmp ( w , levels [ x ] ) ) {
res | = ( 1 < < __LOG_WARNING ) ;
res | = ( 1 < < x ) ;
else if ( ! strcasecmp ( w , " notice " ) )
found = 1 ;
res | = ( 1 < < __LOG_NOTICE ) ;
break ;
else if ( ! strcasecmp ( w , " debug " ) )
}
res | = ( 1 < < __LOG_DEBUG ) ;
else if ( ! strcasecmp ( w , " verbose " ) )
res | = ( 1 < < __LOG_VERBOSE ) ;
else if ( ! strcasecmp ( w , " dtmf " ) )
res | = ( 1 < < __LOG_DTMF ) ;
else {
fprintf ( stderr , " Logfile Warning: Unknown keyword '%s' at line %d of logger.conf \n " , w , lineno ) ;
}
}
}
}
@ -216,9 +260,12 @@ static struct logchannel *make_logchannel(const char *channel, const char *compo
CODE * cptr ;
CODE * cptr ;
# endif
# endif
if ( ast_strlen_zero ( channel ) | | ! ( chan = ast_calloc ( 1 , sizeof ( * chan ) ) ) )
if ( ast_strlen_zero ( channel ) | | ! ( chan = ast_calloc ( 1 , sizeof ( * chan ) + strlen ( components ) + 1 ) ) )
return NULL ;
return NULL ;
strcpy ( chan - > components , components ) ;
chan - > lineno = lineno ;
if ( ! strcasecmp ( channel , " console " ) ) {
if ( ! strcasecmp ( channel , " console " ) ) {
chan - > type = LOGTYPE_CONSOLE ;
chan - > type = LOGTYPE_CONSOLE ;
} else if ( ! strncasecmp ( channel , " syslog " , 6 ) ) {
} else if ( ! strncasecmp ( channel , " syslog " , 6 ) ) {
@ -292,7 +339,7 @@ static struct logchannel *make_logchannel(const char *channel, const char *compo
}
}
chan - > type = LOGTYPE_SYSLOG ;
chan - > type = LOGTYPE_SYSLOG ;
snprintf ( chan - > filename , sizeof ( chan - > filename ) , " %s " , channel ) ;
ast_copy_string ( chan - > filename , channel , sizeof ( chan - > filename ) ) ;
openlog ( " asterisk " , LOG_PID , chan - > facility ) ;
openlog ( " asterisk " , LOG_PID , chan - > facility ) ;
} else {
} else {
if ( ! ast_strlen_zero ( hostname ) ) {
if ( ! ast_strlen_zero ( hostname ) ) {
@ -302,14 +349,14 @@ static struct logchannel *make_logchannel(const char *channel, const char *compo
snprintf ( chan - > filename , sizeof ( chan - > filename ) , " %s/%s " ,
snprintf ( chan - > filename , sizeof ( chan - > filename ) , " %s/%s " ,
channel [ 0 ] ! = ' / ' ? ast_config_AST_LOG_DIR : " " , channel ) ;
channel [ 0 ] ! = ' / ' ? ast_config_AST_LOG_DIR : " " , channel ) ;
}
}
chan - > fileptr = fopen ( chan - > filename , " a " ) ;
if ( ! ( chan - > fileptr = fopen ( chan - > filename , " a " ) ) ) {
if ( ! chan - > fileptr ) {
/* Can't log here, since we're called with a lock */
/* 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 ) ) ;
fprintf ( stderr , " Logger Warning: Unable to open log file '%s': %s \n " , chan - > filename , strerror ( errno ) ) ;
}
}
chan - > type = LOGTYPE_FILE ;
chan - > type = LOGTYPE_FILE ;
}
}
chan - > logmask = make_components ( components , lineno ) ;
chan - > logmask = make_components ( chan - > components , lineno ) ;
return chan ;
return chan ;
}
}
@ -329,10 +376,10 @@ static void init_logger_chain(int locked)
AST_RWLIST_WRLOCK ( & logchannels ) ;
AST_RWLIST_WRLOCK ( & logchannels ) ;
while ( ( chan = AST_RWLIST_REMOVE_HEAD ( & logchannels , list ) ) )
while ( ( chan = AST_RWLIST_REMOVE_HEAD ( & logchannels , list ) ) )
ast_free ( chan ) ;
ast_free ( chan ) ;
global_logmask = 0 ;
if ( ! locked )
if ( ! locked )
AST_RWLIST_UNLOCK ( & logchannels ) ;
AST_RWLIST_UNLOCK ( & logchannels ) ;
global_logmask = 0 ;
errno = 0 ;
errno = 0 ;
/* close syslog */
/* close syslog */
closelog ( ) ;
closelog ( ) ;
@ -346,13 +393,13 @@ static void init_logger_chain(int locked)
if ( ! ( chan = ast_calloc ( 1 , sizeof ( * chan ) ) ) )
if ( ! ( chan = ast_calloc ( 1 , sizeof ( * chan ) ) ) )
return ;
return ;
chan - > type = LOGTYPE_CONSOLE ;
chan - > type = LOGTYPE_CONSOLE ;
chan - > logmask = 28 ; /*warning,notice,error */
chan - > logmask = __LOG_WARNING | __LOG_NOTICE | __LOG_ERROR ;
if ( ! locked )
if ( ! locked )
AST_RWLIST_WRLOCK ( & logchannels ) ;
AST_RWLIST_WRLOCK ( & logchannels ) ;
AST_RWLIST_INSERT_HEAD ( & logchannels , chan , list ) ;
AST_RWLIST_INSERT_HEAD ( & logchannels , chan , list ) ;
global_logmask | = chan - > logmask ;
if ( ! locked )
if ( ! locked )
AST_RWLIST_UNLOCK ( & logchannels ) ;
AST_RWLIST_UNLOCK ( & logchannels ) ;
global_logmask | = chan - > logmask ;
return ;
return ;
}
}
@ -711,13 +758,17 @@ static char *handle_logger_set_level(struct ast_cli_entry *e, int cmd, struct as
if ( a - > argc < 5 )
if ( a - > argc < 5 )
return CLI_SHOWUSAGE ;
return CLI_SHOWUSAGE ;
for ( x = 0 ; x < = NUMLOGLEVELS ; x + + ) {
AST_RWLIST_WRLOCK ( & logchannels ) ;
if ( ! strcasecmp ( a - > argv [ 3 ] , levels [ x ] ) ) {
for ( x = 0 ; x < ARRAY_LEN ( levels ) ; x + + ) {
if ( levels [ x ] & & ! strcasecmp ( a - > argv [ 3 ] , levels [ x ] ) ) {
level = x ;
level = x ;
break ;
break ;
}
}
}
}
AST_RWLIST_UNLOCK ( & logchannels ) ;
state = ast_true ( a - > argv [ 4 ] ) ? 1 : 0 ;
state = ast_true ( a - > argv [ 4 ] ) ? 1 : 0 ;
if ( level ! = - 1 ) {
if ( level ! = - 1 ) {
@ -750,21 +801,16 @@ static char *handle_logger_show_channels(struct ast_cli_entry *e, int cmd, struc
ast_cli ( a - > fd , " ------------- \n " ) ;
ast_cli ( a - > fd , " ------------- \n " ) ;
AST_RWLIST_RDLOCK ( & logchannels ) ;
AST_RWLIST_RDLOCK ( & logchannels ) ;
AST_RWLIST_TRAVERSE ( & logchannels , chan , list ) {
AST_RWLIST_TRAVERSE ( & logchannels , chan , list ) {
unsigned int level ;
ast_cli ( a - > fd , FORMATL , chan - > filename , chan - > type = = LOGTYPE_CONSOLE ? " Console " : ( chan - > type = = LOGTYPE_SYSLOG ? " Syslog " : " File " ) ,
ast_cli ( a - > fd , FORMATL , chan - > filename , chan - > type = = LOGTYPE_CONSOLE ? " Console " : ( chan - > type = = LOGTYPE_SYSLOG ? " Syslog " : " File " ) ,
chan - > disabled ? " Disabled " : " Enabled " ) ;
chan - > disabled ? " Disabled " : " Enabled " ) ;
ast_cli ( a - > fd , " - " ) ;
ast_cli ( a - > fd , " - " ) ;
if ( chan - > logmask & ( 1 < < __LOG_DEBUG ) )
for ( level = 0 ; level < ARRAY_LEN ( levels ) ; level + + ) {
ast_cli ( a - > fd , " Debug " ) ;
if ( chan - > logmask & ( 1 < < level ) ) {
if ( chan - > logmask & ( 1 < < __LOG_DTMF ) )
ast_cli ( a - > fd , " %s " , levels [ level ] ) ;
ast_cli ( a - > fd , " DTMF " ) ;
}
if ( chan - > logmask & ( 1 < < __LOG_VERBOSE ) )
}
ast_cli ( a - > fd , " Verbose " ) ;
if ( chan - > logmask & ( 1 < < __LOG_WARNING ) )
ast_cli ( a - > fd , " Warning " ) ;
if ( chan - > logmask & ( 1 < < __LOG_NOTICE ) )
ast_cli ( a - > fd , " Notice " ) ;
if ( chan - > logmask & ( 1 < < __LOG_ERROR ) )
ast_cli ( a - > fd , " Error " ) ;
ast_cli ( a - > fd , " \n " ) ;
ast_cli ( a - > fd , " \n " ) ;
}
}
AST_RWLIST_UNLOCK ( & logchannels ) ;
AST_RWLIST_UNLOCK ( & logchannels ) ;
@ -794,7 +840,7 @@ static int handle_SIGXFSZ(int sig)
return 0 ;
return 0 ;
}
}
static void ast_log_vsyslog ( int level , const char * file , int line , const char * function , char * str , long pid )
static void ast_log_vsyslog ( int level , const char * file , int line , const char * function , const char * str , long pid )
{
{
char buf [ BUFSIZ ] ;
char buf [ BUFSIZ ] ;
@ -834,7 +880,7 @@ static void logger_print_normal(struct logmsg *logmsg)
continue ;
continue ;
/* Check syslog channels */
/* Check syslog channels */
if ( chan - > type = = LOGTYPE_SYSLOG & & ( chan - > logmask & ( 1 < < logmsg - > level ) ) ) {
if ( chan - > type = = LOGTYPE_SYSLOG & & ( chan - > logmask & ( 1 < < logmsg - > level ) ) ) {
ast_log_vsyslog ( logmsg - > level , logmsg - > file , logmsg - > line , logmsg - > function , logmsg - > str , logmsg - > process_id ) ;
ast_log_vsyslog ( logmsg - > level , logmsg - > file , logmsg - > line , logmsg - > function , logmsg - > message , logmsg - > process_id ) ;
/* Console channels */
/* Console channels */
} else if ( chan - > type = = LOGTYPE_CONSOLE & & ( chan - > logmask & ( 1 < < logmsg - > level ) ) ) {
} else if ( chan - > type = = LOGTYPE_CONSOLE & & ( chan - > logmask & ( 1 < < logmsg - > level ) ) ) {
char linestr [ 128 ] ;
char linestr [ 128 ] ;
@ -849,12 +895,12 @@ static void logger_print_normal(struct logmsg *logmsg)
/* Build string to print out */
/* Build string to print out */
snprintf ( buf , sizeof ( buf ) , " [%s] %s[%ld]: %s:%s %s: %s " ,
snprintf ( buf , sizeof ( buf ) , " [%s] %s[%ld]: %s:%s %s: %s " ,
logmsg - > date ,
logmsg - > date ,
term_color ( tmp1 , l evels[ logmsg - > level ] , colors [ logmsg - > level ] , 0 , sizeof ( tmp1 ) ) ,
term_color ( tmp1 , l ogmsg- > level_name , colors [ logmsg - > level ] , 0 , sizeof ( tmp1 ) ) ,
logmsg - > process_id ,
logmsg - > process_id ,
term_color ( tmp2 , logmsg - > file , COLOR_BRWHITE , 0 , sizeof ( tmp2 ) ) ,
term_color ( tmp2 , logmsg - > file , COLOR_BRWHITE , 0 , sizeof ( tmp2 ) ) ,
term_color ( tmp3 , linestr , COLOR_BRWHITE , 0 , sizeof ( tmp3 ) ) ,
term_color ( tmp3 , linestr , COLOR_BRWHITE , 0 , sizeof ( tmp3 ) ) ,
term_color ( tmp4 , logmsg - > function , COLOR_BRWHITE , 0 , sizeof ( tmp4 ) ) ,
term_color ( tmp4 , logmsg - > function , COLOR_BRWHITE , 0 , sizeof ( tmp4 ) ) ,
logmsg - > str ) ;
logmsg - > message ) ;
/* Print out */
/* Print out */
ast_console_puts_mutable ( buf , logmsg - > level ) ;
ast_console_puts_mutable ( buf , logmsg - > level ) ;
/* File channels */
/* File channels */
@ -867,8 +913,8 @@ static void logger_print_normal(struct logmsg *logmsg)
/* Print out to the file */
/* Print out to the file */
res = fprintf ( chan - > fileptr , " [%s] %s[%ld] %s: %s " ,
res = fprintf ( chan - > fileptr , " [%s] %s[%ld] %s: %s " ,
logmsg - > date , l evels[ logmsg - > level ] , logmsg - > process_id , logmsg - > file , logmsg - > str ) ;
logmsg - > date , l ogmsg- > level_name , logmsg - > process_id , logmsg - > file , logmsg - > message ) ;
if ( res < = 0 & & ! ast_strlen_zero ( logmsg - > str ) ) {
if ( res < = 0 & & ! ast_strlen_zero ( logmsg - > message ) ) {
fprintf ( stderr , " **** Asterisk Logging Error: *********** \n " ) ;
fprintf ( stderr , " **** Asterisk Logging Error: *********** \n " ) ;
if ( errno = = ENOMEM | | errno = = ENOSPC )
if ( errno = = ENOMEM | | errno = = ENOSPC )
fprintf ( stderr , " Asterisk logging error: Out of disk space, can't log to log file %s \n " , chan - > filename ) ;
fprintf ( stderr , " Asterisk logging error: Out of disk space, can't log to log file %s \n " , chan - > filename ) ;
@ -882,7 +928,7 @@ static void logger_print_normal(struct logmsg *logmsg)
}
}
}
}
} else if ( logmsg - > level ! = __LOG_VERBOSE ) {
} else if ( logmsg - > level ! = __LOG_VERBOSE ) {
fputs ( logmsg - > str , stdout ) ;
fputs ( logmsg - > message , stdout ) ;
}
}
AST_RWLIST_UNLOCK ( & logchannels ) ;
AST_RWLIST_UNLOCK ( & logchannels ) ;
@ -904,7 +950,7 @@ static void logger_print_verbose(struct logmsg *logmsg)
/* Iterate through the list of verbosers and pass them the log message string */
/* Iterate through the list of verbosers and pass them the log message string */
AST_RWLIST_RDLOCK ( & verbosers ) ;
AST_RWLIST_RDLOCK ( & verbosers ) ;
AST_RWLIST_TRAVERSE ( & verbosers , v , list )
AST_RWLIST_TRAVERSE ( & verbosers , v , list )
v - > verboser ( logmsg - > str ) ;
v - > verboser ( logmsg - > message ) ;
AST_RWLIST_UNLOCK ( & verbosers ) ;
AST_RWLIST_UNLOCK ( & verbosers ) ;
return ;
return ;
@ -941,6 +987,7 @@ static void *logger_thread(void *data)
logger_print_verbose ( msg ) ;
logger_print_verbose ( msg ) ;
/* Free the data since we are done */
/* Free the data since we are done */
ast_string_field_free_memory ( msg ) ;
ast_free ( msg ) ;
ast_free ( msg ) ;
}
}
@ -1028,6 +1075,7 @@ void ast_log(int level, const char *file, int line, const char *function, const
struct timeval now = ast_tvnow ( ) ;
struct timeval now = ast_tvnow ( ) ;
int res = 0 ;
int res = 0 ;
va_list ap ;
va_list ap ;
char datestring [ 256 ] ;
if ( ! ( buf = ast_str_thread_get ( & log_buf , LOG_BUF_INIT_SIZE ) ) )
if ( ! ( buf = ast_str_thread_get ( & log_buf , LOG_BUF_INIT_SIZE ) ) )
return ;
return ;
@ -1073,24 +1121,26 @@ void ast_log(int level, const char *file, int line, const char *function, const
return ;
return ;
/* Create a new logging message */
/* Create a new logging message */
if ( ! ( logmsg = ast_calloc ( 1 , sizeof ( * logmsg ) + res + 1 ) ) )
if ( ! ( logmsg = ast_calloc _with_stringfields( 1 , struct logmsg , res + 128 ) ) )
return ;
return ;
/* Copy string over */
/* Copy string over */
strcpy( logmsg - > str , ast_str_buffer ( buf ) ) ;
ast_string_field_set( logmsg , message , ast_str_buffer ( buf ) ) ;
/* Set type to be normal */
/* Set type to be normal */
logmsg - > type = LOGMSG_NORMAL ;
logmsg - > type = LOGMSG_NORMAL ;
/* Create our date/time */
/* Create our date/time */
ast_localtime ( & now , & tm , NULL ) ;
ast_localtime ( & now , & tm , NULL ) ;
ast_strftime ( logmsg - > date , sizeof ( logmsg - > date ) , dateformat , & tm ) ;
ast_strftime ( datestring , sizeof ( datestring ) , dateformat , & tm ) ;
ast_string_field_set ( logmsg , date , datestring ) ;
/* Copy over data */
/* Copy over data */
logmsg - > level = level ;
logmsg - > level = level ;
logmsg - > line = line ;
logmsg - > line = line ;
ast_copy_string ( logmsg - > file , file , sizeof ( logmsg - > file ) ) ;
ast_string_field_set ( logmsg , level_name , levels [ level ] ) ;
ast_copy_string ( logmsg - > function , function , sizeof ( logmsg - > function ) ) ;
ast_string_field_set ( logmsg , file , file ) ;
ast_string_field_set ( logmsg , function , function ) ;
logmsg - > process_id = ( long ) GETTID ( ) ;
logmsg - > process_id = ( long ) GETTID ( ) ;
/* If the logger thread is active, append it to the tail end of the list - otherwise skip that step */
/* If the logger thread is active, append it to the tail end of the list - otherwise skip that step */
@ -1206,12 +1256,12 @@ void __ast_verbose_ap(const char *file, int line, const char *func, const char *
if ( res = = AST_DYNSTR_BUILD_FAILED )
if ( res = = AST_DYNSTR_BUILD_FAILED )
return ;
return ;
if ( ! ( logmsg = ast_calloc ( 1 , sizeof ( * logmsg ) + res + 1 ) ) )
if ( ! ( logmsg = ast_calloc _with_stringfields( 1 , struct logmsg , res + 128 ) ) )
return ;
return ;
strcpy( logmsg - > str , ast_str_buffer ( buf ) ) ;
ast_string_field_set( logmsg , message , ast_str_buffer ( buf ) ) ;
ast_log ( __LOG_VERBOSE , file , line , func , " %s " , logmsg - > str + 1 ) ;
ast_log ( __LOG_VERBOSE , file , line , func , " %s " , logmsg - > message + 1 ) ;
/* Set type */
/* Set type */
logmsg - > type = LOGMSG_VERBOSE ;
logmsg - > type = LOGMSG_VERBOSE ;
@ -1231,6 +1281,7 @@ void __ast_verbose_ap(const char *file, int line, const char *func, const char *
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 , const char * fmt , . . . )
{
{
va_list ap ;
va_list ap ;
va_start ( ap , fmt ) ;
va_start ( ap , fmt ) ;
__ast_verbose_ap ( file , line , func , fmt , ap ) ;
__ast_verbose_ap ( file , line , func , fmt , ap ) ;
va_end ( ap ) ;
va_end ( ap ) ;
@ -1242,6 +1293,7 @@ void __attribute__((format(printf, 1,2))) ast_verbose(const char *fmt, ...);
void ast_verbose ( const char * fmt , . . . )
void ast_verbose ( const char * fmt , . . . )
{
{
va_list ap ;
va_list ap ;
va_start ( ap , fmt ) ;
va_start ( ap , fmt ) ;
__ast_verbose_ap ( " " , 0 , " " , fmt , ap ) ;
__ast_verbose_ap ( " " , 0 , " " , fmt , ap ) ;
va_end ( ap ) ;
va_end ( ap ) ;
@ -1280,3 +1332,102 @@ int ast_unregister_verbose(void (*v)(const char *string))
return cur ? 0 : - 1 ;
return cur ? 0 : - 1 ;
}
}
static void update_logchannels ( void )
{
struct logchannel * cur ;
AST_RWLIST_WRLOCK ( & logchannels ) ;
global_logmask = 0 ;
AST_RWLIST_TRAVERSE ( & logchannels , cur , list ) {
cur - > logmask = make_components ( cur - > components , cur - > lineno ) ;
global_logmask | = cur - > logmask ;
}
AST_RWLIST_UNLOCK ( & logchannels ) ;
}
int ast_logger_register_level ( const char * name )
{
unsigned int level ;
unsigned int available = 0 ;
AST_RWLIST_WRLOCK ( & logchannels ) ;
for ( level = 0 ; level < ARRAY_LEN ( levels ) ; level + + ) {
if ( ( level > = 16 ) & & ! available & & ! levels [ level ] ) {
available = level ;
continue ;
}
if ( levels [ level ] & & ! strcasecmp ( levels [ level ] , name ) ) {
ast_log ( LOG_WARNING ,
" Unable to register dynamic logger level '%s': a standard logger level uses that name. \n " ,
name ) ;
AST_RWLIST_UNLOCK ( & logchannels ) ;
return - 1 ;
}
}
if ( ! available ) {
ast_log ( LOG_WARNING ,
" Unable to register dynamic logger level '%s'; maximum number of levels registered. \n " ,
name ) ;
AST_RWLIST_UNLOCK ( & logchannels ) ;
return - 1 ;
}
levels [ available ] = ast_strdup ( name ) ;
AST_RWLIST_UNLOCK ( & logchannels ) ;
ast_debug ( 1 , " Registered dynamic logger level '%s' with index %d. \n " , name , available ) ;
update_logchannels ( ) ;
return available ;
}
void ast_logger_unregister_level ( const char * name )
{
unsigned int found = 0 ;
unsigned int x ;
AST_RWLIST_WRLOCK ( & logchannels ) ;
for ( x = 16 ; x < ARRAY_LEN ( levels ) ; x + + ) {
if ( ! levels [ x ] ) {
continue ;
}
if ( strcasecmp ( levels [ x ] , name ) ) {
continue ;
}
found = 1 ;
break ;
}
if ( found ) {
/* take this level out of the global_logmask, to ensure that no new log messages
* will be queued for it
*/
global_logmask & = ~ ( 1 < < x ) ;
free ( levels [ x ] ) ;
levels [ x ] = NULL ;
AST_RWLIST_UNLOCK ( & logchannels ) ;
ast_debug ( 1 , " Unregistered dynamic logger level '%s' with index %d. \n " , name , x ) ;
update_logchannels ( ) ;
} else {
AST_RWLIST_UNLOCK ( & logchannels ) ;
}
}