logger.c File Reference

Asterisk Logger. More...

#include "asterisk.h"
#include <syslog.h>
#include <signal.h>
#include <time.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "asterisk/_private.h"
#include "asterisk/paths.h"
#include "asterisk/logger.h"
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/term.h"
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/manager.h"
#include "asterisk/astobj2.h"
#include "asterisk/threadstorage.h"
#include "asterisk/strings.h"
#include "asterisk/pbx.h"
#include "asterisk/app.h"
#include "asterisk/buildinfo.h"
#include "asterisk/ast_version.h"
#include "asterisk/backtrace.h"

Include dependency graph for logger.c:

Go to the source code of this file.

Data Structures

struct  logchannel
struct  logchannels
struct  logmsg
struct  logmsgs
struct  verb
struct  verb_console
struct  verb_consoles
struct  verbosers

Defines

#define FORMATL   "%-35.35s %-8.8s %-9.9s "
#define LOG_BUF_INIT_SIZE   256
#define VERBOSE_BUF_INIT_SIZE   256

Enumerations

enum  logmsgtypes { LOGMSG_NORMAL = 0, LOGMSG_VERBOSE }
enum  logtypes { LOGTYPE_SYSLOG, LOGTYPE_FILE, LOGTYPE_CONSOLE }
enum  rotatestrategy { NONE = 0, SEQUENTIAL = 1 << 0, ROTATE = 1 << 1, TIMESTAMP = 1 << 2 }

Functions

void __ast_verbose (const char *file, int line, const char *func, int level, const char *fmt,...)
 Send a verbose message (based on verbose level).
void __ast_verbose_ap (const char *file, int line, const char *func, int level, ast_callid callid, const char *fmt, va_list ap)
void __ast_verbose_callid (const char *file, int line, const char *func, int level, ast_callid callid, const char *fmt,...)
 Send a verbose message (based on verbose level) with deliberately specified callid.
static void __fini_logchannels (void)
static void __fini_verb_consoles (void)
static void __fini_verbosers (void)
static void __init_log_buf (void)
static void __init_logchannels (void)
static void __init_my_verb_console (void)
static void __init_unique_callid (void)
static void __init_verb_consoles (void)
static void __init_verbose_buf (void)
static void __init_verbose_build_buf (void)
static void __init_verbosers (void)
static void _handle_SIGXFSZ (int sig)
void ast_callid_strnprint (char *buffer, size_t buffer_size, ast_callid callid)
 copy a string representation of the callid into a target string
int ast_callid_threadassoc_add (ast_callid callid)
 Adds a known callid to thread storage of the calling thread.
int ast_callid_threadassoc_change (ast_callid callid)
 Sets what is stored in the thread storage to the given callid if it does not match what is already there.
int ast_callid_threadassoc_remove (void)
 Removes callid from thread storage of the calling thread.
int ast_callid_threadstorage_auto (ast_callid *callid)
 Checks thread storage for a callid and stores a reference if it exists. If not, then a new one will be created, bound to the thread, and a reference to it will be stored.
void ast_callid_threadstorage_auto_clean (ast_callid callid, int callid_created)
 Use in conjunction with ast_callid_threadstorage_auto. Cleans up the references and if the callid was created by threadstorage_auto, unbinds the callid from the threadstorage.
void ast_child_verbose (int level, const char *fmt,...)
ast_callid ast_create_callid (void)
 factory function to create a new uniquely identifying callid.
void ast_log (int level, const char *file, int line, const char *function, const char *fmt,...)
 Used for sending a log message This is the standard logger function. Probably the only way you will invoke it would be something like this: ast_log(AST_LOG_WHATEVER, "Problem with the %s Captain. We should get some more. Will %d be enough?\n", "flux capacitor", 10); where WHATEVER is one of ERROR, DEBUG, EVENT, NOTICE, or WARNING depending on which log you wish to output to. These are implemented as macros, that will provide the function with the needed arguments.
void ast_log_backtrace (void)
 Log a backtrace of the current thread's execution stack to the Asterisk log.
void ast_log_callid (int level, const char *file, int line, const char *function, ast_callid callid, const char *fmt,...)
 Used for sending a log message with a known call_id This is a modified logger function which is functionally identical to the above logger function, it just include a call_id argument as well. If NULL is specified here, no attempt will be made to join the log message with a call_id.
static void ast_log_full (int level, const char *file, int line, const char *function, ast_callid callid, const char *fmt, va_list ap)
 send log messages to syslog and/or the console
void ast_log_safe (int level, const char *file, int line, const char *function, const char *fmt,...)
 Used for sending a log message with protection against recursion.
static void ast_log_vsyslog (struct logmsg *msg)
const char * ast_logger_get_dateformat (void)
 Get the logger configured date format.
int ast_logger_register_level (const char *name)
 Register a new logger level.
int ast_logger_rotate ()
 Reload logger while rotating log files.
void ast_logger_unregister_level (const char *name)
 Unregister a previously registered logger level.
void ast_queue_log (const char *queuename, const char *callid, const char *agent, const char *event, const char *fmt,...)
ast_callid ast_read_threadstorage_callid (void)
 extracts the callerid from the thread
int ast_register_verbose (void(*v)(const char *string))
 AST_THREADSTORAGE_RAW (in_safe_log)
int ast_unregister_verbose (void(*v)(const char *string))
int ast_verb_console_get (void)
 Get this thread's console verbosity level.
void ast_verb_console_register (int *level)
 Register this thread's console verbosity level pointer.
void ast_verb_console_set (int verb_level)
 Set this thread's console verbosity level.
void ast_verb_console_unregister (void)
 Unregister this thread's console verbosity level.
void ast_verb_update (void)
 Re-evaluate the system max verbosity level (ast_verb_sys_level).
void ast_verbose (const char *fmt,...)
void close_logger (void)
static char * handle_logger_add_channel (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_logger_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_logger_remove_channel (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_logger_rotate (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_logger_set_level (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_logger_show_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command to show logging system configuration.
int init_logger (void)
static int init_logger_chain (int locked, const char *altconf)
static void logger_print_normal (struct logmsg *logmsg)
 Print a normal log message to the channels.
static void logger_queue_init (void)
static int logger_queue_restart (int queue_rotate)
static int logger_queue_rt_start (void)
void logger_queue_start (void)
 Start the ast_queue_log() logger.
int logger_reload (void)
 Reload the logger module without rotating log files (also used from loader.c during a full Asterisk reload).
static char * logger_strip_verbose_magic (const char *message, int level)
static void * logger_thread (void *data)
 Actual logging thread.
static void logmsg_free (struct logmsg *msg)
static void make_components (struct logchannel *chan)
static struct logchannelmake_logchannel (const char *channel, const char *components, int lineno, int dynamic)
static int reload_logger (int rotate, const char *altconf)
static int rotate_file (const char *filename)
static void update_logchannels (void)
static void verb_console_free (void *v_console)
static void verb_console_unregister (struct verb_console *console)

Variables

static struct ast_cli_entry cli_logger []
static int close_logger_thread = 0
static const int colors [NUMLOGLEVELS]
 Colors used in the console for logging.
static char dateformat [256] = "%b %e %T"
static int display_callids
static char exec_after_rotate [256] = ""
static int filesize_reload_needed
static unsigned int global_logmask = 0xFFFF
static struct sigaction handle_SIGXFSZ
static char hostname [MAXHOSTNAMELEN]
static char * levels [NUMLOGLEVELS]
 Logging channels used in the Asterisk logging system.
static struct ast_threadstorage log_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_log_buf , .custom_init = NULL , }
static ast_cond_t logcond
struct {
   unsigned int   queue_adaptive_realtime:1
   unsigned int   queue_log:1
   unsigned int   queue_log_realtime_use_gmt:1
   unsigned int   queue_log_to_file:1
logfiles
static int logger_initialized
static pthread_t logthread = AST_PTHREADT_NULL
static struct ast_threadstorage my_verb_console = { .once = PTHREAD_ONCE_INIT , .key_init = __init_my_verb_console , .custom_init = NULL , }
static volatile int next_unique_callid = 1
static FILE * qlog
static char queue_log_name [256] = QUEUELOG
static int queuelog_init
static struct ast_threadstorage unique_callid = { .once = PTHREAD_ONCE_INIT , .key_init = __init_unique_callid , .custom_init = NULL , }
static ast_mutex_t verb_update_lock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 }
static struct ast_threadstorage verbose_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_verbose_buf , .custom_init = NULL , }
static struct ast_threadstorage verbose_build_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_verbose_build_buf , .custom_init = NULL , }


Detailed Description

Asterisk Logger.

Logging routines

Author:
Mark Spencer <markster@digium.com>

Definition in file logger.c.


Define Documentation

#define FORMATL   "%-35.35s %-8.8s %-9.9s "

#define LOG_BUF_INIT_SIZE   256

Definition at line 235 of file logger.c.

Referenced by ast_log_full().

#define VERBOSE_BUF_INIT_SIZE   256

Definition at line 232 of file logger.c.

Referenced by __ast_verbose_ap().


Enumeration Type Documentation

Enumerator:
LOGMSG_NORMAL 
LOGMSG_VERBOSE 

Definition at line 140 of file logger.c.

00140                  {
00141    LOGMSG_NORMAL = 0,
00142    LOGMSG_VERBOSE,
00143 };

enum logtypes

Enumerator:
LOGTYPE_SYSLOG 
LOGTYPE_FILE 
LOGTYPE_CONSOLE 

Definition at line 107 of file logger.c.

00107               {
00108    LOGTYPE_SYSLOG,
00109    LOGTYPE_FILE,
00110    LOGTYPE_CONSOLE,
00111 };

Enumerator:
NONE 
SEQUENTIAL 
ROTATE 
TIMESTAMP 

Definition at line 90 of file logger.c.

00090                            {
00091    NONE = 0,                /* Do not rotate log files at all, instead rely on external mechanisms */
00092    SEQUENTIAL = 1 << 0,     /* Original method - create a new file, in order */
00093    ROTATE = 1 << 1,         /* Rotate all files, such that the oldest file has the highest suffix */
00094    TIMESTAMP = 1 << 2,      /* Append the epoch timestamp onto the end of the archived file */
00095 } rotatestrategy = SEQUENTIAL;


Function Documentation

void __ast_verbose ( const char *  file,
int  line,
const char *  func,
int  level,
const char *  fmt,
  ... 
)

Send a verbose message (based on verbose level).

This works like ast_log, but prints verbose messages to the console depending on verbosity level set.

ast_verbose(VERBOSE_PREFIX_3 "Whatever %s is happening\n", "nothing");

This will print the message to the console if the verbose level is set to a level >= 3

Note the absence of a comma after the VERBOSE_PREFIX_3. This is important. VERBOSE_PREFIX_1 through VERBOSE_PREFIX_4 are defined.

Version:
11 added level parameter

Definition at line 1837 of file logger.c.

References __ast_verbose_ap(), and ast_read_threadstorage_callid().

01838 {
01839    ast_callid callid;
01840    va_list ap;
01841 
01842    callid = ast_read_threadstorage_callid();
01843 
01844    va_start(ap, fmt);
01845    __ast_verbose_ap(file, line, func, level, callid, fmt, ap);
01846    va_end(ap);
01847 }

void __ast_verbose_ap ( const char *  file,
int  line,
const char *  func,
int  level,
ast_callid  callid,
const char *  fmt,
va_list  ap 
)

Definition at line 1786 of file logger.c.

References __LOG_VERBOSE, AST_DYNSTR_BUILD_FAILED, ast_log_callid(), ast_str_append(), ast_str_append_substr(), ast_str_buffer(), ast_str_reset(), ast_str_set_va(), ast_str_thread_get(), buf, verbose_buf, VERBOSE_BUF_INIT_SIZE, verbose_build_buf, VERBOSE_PREFIX_1, VERBOSE_PREFIX_2, VERBOSE_PREFIX_3, and VERBOSE_PREFIX_4.

Referenced by __ast_verbose(), __ast_verbose_callid(), ast_log(), and ast_verbose().

01787 {
01788    const char *p;
01789    struct ast_str *prefixed, *buf;
01790    int res = 0;
01791    signed char magic = level > 9 ? -10 : -level - 1; /* 0 => -1, 1 => -2, etc.  Can't pass NUL, as it is EOS-delimiter */
01792 
01793    /* For compatibility with modules still calling ast_verbose() directly instead of using ast_verb() */
01794    if (level < 0) {
01795       if (!strncmp(fmt, VERBOSE_PREFIX_4, strlen(VERBOSE_PREFIX_4))) {
01796          magic = -5;
01797       } else if (!strncmp(fmt, VERBOSE_PREFIX_3, strlen(VERBOSE_PREFIX_3))) {
01798          magic = -4;
01799       } else if (!strncmp(fmt, VERBOSE_PREFIX_2, strlen(VERBOSE_PREFIX_2))) {
01800          magic = -3;
01801       } else if (!strncmp(fmt, VERBOSE_PREFIX_1, strlen(VERBOSE_PREFIX_1))) {
01802          magic = -2;
01803       } else {
01804          magic = -1;
01805       }
01806    }
01807 
01808    if (!(prefixed = ast_str_thread_get(&verbose_buf, VERBOSE_BUF_INIT_SIZE)) ||
01809        !(buf = ast_str_thread_get(&verbose_build_buf, VERBOSE_BUF_INIT_SIZE))) {
01810       return;
01811    }
01812 
01813    res = ast_str_set_va(&buf, 0, fmt, ap);
01814    /* If the build failed then we can drop this allocated message */
01815    if (res == AST_DYNSTR_BUILD_FAILED) {
01816       return;
01817    }
01818 
01819    ast_str_reset(prefixed);
01820 
01821    /* for every newline found in the buffer add verbose prefix data */
01822    fmt = ast_str_buffer(buf);
01823    do {
01824       if (!(p = strchr(fmt, '\n'))) {
01825          p = strchr(fmt, '\0') - 1;
01826       }
01827       ++p;
01828 
01829       ast_str_append(&prefixed, 0, "%c", (char)magic);
01830       ast_str_append_substr(&prefixed, 0, fmt, p - fmt);
01831       fmt = p;
01832    } while (p && *p);
01833 
01834    ast_log_callid(__LOG_VERBOSE, file, line, func, callid, "%s", ast_str_buffer(prefixed));
01835 }

void __ast_verbose_callid ( const char *  file,
int  line,
const char *  func,
int  level,
ast_callid  callid,
const char *  fmt,
  ... 
)

Send a verbose message (based on verbose level) with deliberately specified callid.

just like __ast_verbose, only __ast_verbose_callid allows you to specify which callid is being used for the log without needing to bind it to a thread. NULL is a valid argument for this function and will allow you to specify that a log will never display a call id even when there is a call id bound to the thread.

Definition at line 1849 of file logger.c.

References __ast_verbose_ap().

01850 {
01851    va_list ap;
01852    va_start(ap, fmt);
01853    __ast_verbose_ap(file, line, func, level, callid, fmt, ap);
01854    va_end(ap);
01855 }

static void __fini_logchannels ( void   )  [static]

Definition at line 138 of file logger.c.

00140 {

static void __fini_verb_consoles ( void   )  [static]

Definition at line 1881 of file logger.c.

01887 {

static void __fini_verbosers ( void   )  [static]

Definition at line 1119 of file logger.c.

01121 {

static void __init_log_buf ( void   )  [static]

Definition at line 234 of file logger.c.

00238 {

static void __init_logchannels ( void   )  [static]

Definition at line 138 of file logger.c.

00140 {

static void __init_my_verb_console ( void   )  [static]

Thread specific console verbosity level node.

Definition at line 1948 of file logger.c.

01951 {

static void __init_unique_callid ( void   )  [static]

Definition at line 88 of file logger.c.

00090 {

static void __init_verb_consoles ( void   )  [static]

Definition at line 1881 of file logger.c.

01887 {

static void __init_verbose_buf ( void   )  [static]

Definition at line 230 of file logger.c.

00238 {

static void __init_verbose_build_buf ( void   )  [static]

Definition at line 231 of file logger.c.

00238 {

static void __init_verbosers ( void   )  [static]

Definition at line 1119 of file logger.c.

01121 {

static void _handle_SIGXFSZ ( int  sig  )  [static]

Definition at line 1130 of file logger.c.

01131 {
01132    /* Indicate need to reload */
01133    filesize_reload_needed = 1;
01134 }

void ast_callid_strnprint ( char *  buffer,
size_t  buffer_size,
ast_callid  callid 
)

copy a string representation of the callid into a target string

Parameters:
buffer destination of callid string (should be able to store 13 characters or more)
buffer_size maximum writable length of the string (Less than 13 will result in truncation)
callid Callid for which string is being requested

Definition at line 1492 of file logger.c.

Referenced by ast_channel_callid_set(), handle_showchan(), and iax_pvt_callid_new().

01493 {
01494    snprintf(buffer, buffer_size, "[C-%08x]", callid);
01495 }

int ast_callid_threadassoc_add ( ast_callid  callid  ) 

Adds a known callid to thread storage of the calling thread.

Return values:
0 - success
non-zero - failure

Definition at line 1544 of file logger.c.

References ast_debug, ast_log, ast_threadstorage_get(), LOG_ERROR, LOG_WARNING, and unique_callid.

Referenced by __analog_ss_thread(), __ast_pbx_run(), ast_callid_threadstorage_auto(), async_dial(), attended_transfer_monitor_thread(), bridge_channel_control_thread(), bridge_channel_depart_thread(), bridge_channel_ind_thread(), handle_request_do(), jingle_action_hook(), jingle_outgoing_hook(), mixmonitor_thread(), socket_process_helper(), and softmix_mixing_thread().

01545 {
01546    ast_callid *pointing;
01547 
01548    pointing = ast_threadstorage_get(&unique_callid, sizeof(*pointing));
01549    if (!(pointing)) {
01550       ast_log(LOG_ERROR, "Failed to allocate thread storage.\n");
01551       return -1;
01552    }
01553 
01554    if (!(*pointing)) {
01555       *pointing = callid;
01556 #ifdef TEST_FRAMEWORK
01557       ast_debug(3, "CALL_ID [C-%08x] bound to thread.\n", callid);
01558 #endif
01559    } else {
01560       ast_log(LOG_WARNING, "Attempted to ast_callid_threadassoc_add on thread already associated with a callid.\n");
01561       return 1;
01562    }
01563 
01564    return 0;
01565 }

int ast_callid_threadassoc_change ( ast_callid  callid  ) 

Sets what is stored in the thread storage to the given callid if it does not match what is already there.

Return values:
0 - success
non-zero - failure

Definition at line 1518 of file logger.c.

References ast_debug, ast_log, ast_threadstorage_get(), LOG_ERROR, and unique_callid.

Referenced by autoservice_run(), and bridge_manager_service().

01519 {
01520    ast_callid *id = ast_threadstorage_get(&unique_callid, sizeof(*id));
01521 
01522    if (!id) {
01523       ast_log(LOG_ERROR, "Failed to allocate thread storage.\n");
01524       return -1;
01525    }
01526 
01527    if (*id && (*id != callid)) {
01528 #ifdef TEST_FRAMEWORK
01529       ast_debug(3, "CALL_ID [C-%08x] being removed from thread.\n", *id);
01530 #endif
01531       *id = 0;
01532    }
01533 
01534    if (!(*id) && callid) {
01535       *id = callid;
01536 #ifdef TEST_FRAMEWORK
01537       ast_debug(3, "CALL_ID [C-%08x] bound to thread.\n", callid);
01538 #endif
01539    }
01540 
01541    return 0;
01542 }

int ast_callid_threadassoc_remove ( void   ) 

Removes callid from thread storage of the calling thread.

Return values:
0 - success
non-zero - failure

Definition at line 1567 of file logger.c.

References ast_debug, ast_log, ast_threadstorage_get(), LOG_ERROR, and unique_callid.

Referenced by ast_callid_threadstorage_auto_clean(), attended_transfer_monitor_thread(), handle_request_do(), jingle_action_hook(), jingle_outgoing_hook(), and socket_process().

01568 {
01569    ast_callid *pointing;
01570 
01571    pointing = ast_threadstorage_get(&unique_callid, sizeof(*pointing));
01572    if (!(pointing)) {
01573       ast_log(LOG_ERROR, "Failed to allocate thread storage.\n");
01574       return -1;
01575    }
01576 
01577    if (!(*pointing)) {
01578       ast_log(LOG_ERROR, "Tried to clean callid thread storage with no callid in thread storage.\n");
01579       return -1;
01580    } else {
01581 #ifdef TEST_FRAMEWORK
01582       ast_debug(3, "CALL_ID [C-%08x] being removed from thread.\n", *pointing);
01583 #endif
01584       *pointing = 0;
01585       return 0;
01586    }
01587 }

int ast_callid_threadstorage_auto ( ast_callid callid  ) 

Checks thread storage for a callid and stores a reference if it exists. If not, then a new one will be created, bound to the thread, and a reference to it will be stored.

Parameters:
callid pointer to store the callid
Return values:
0 - callid was found
1 - callid was created
-1 - the function failed somehow (presumably memory problems)

Definition at line 1589 of file logger.c.

References ast_callid_threadassoc_add(), ast_create_callid(), ast_read_threadstorage_callid(), and tmp().

Referenced by __analog_handle_event(), analog_handle_init_event(), dahdi_handle_event(), dahdi_request(), do_monitor(), handle_init_event(), mwi_thread(), and my_new_analog_ast_channel().

01590 {
01591    ast_callid tmp;
01592 
01593    /* Start by trying to see if a callid is available from thread storage */
01594    tmp = ast_read_threadstorage_callid();
01595    if (tmp) {
01596       *callid = tmp;
01597       return 0;
01598    }
01599 
01600    /* If that failed, try to create a new one and bind it. */
01601    *callid = ast_create_callid();
01602    if (*callid) {
01603       ast_callid_threadassoc_add(*callid);
01604       return 1;
01605    }
01606 
01607    /* If neither worked, then something must have gone wrong. */
01608    return -1;
01609 }

void ast_callid_threadstorage_auto_clean ( ast_callid  callid,
int  callid_created 
)

Use in conjunction with ast_callid_threadstorage_auto. Cleans up the references and if the callid was created by threadstorage_auto, unbinds the callid from the threadstorage.

Parameters:
callid The callid set by ast_callid_threadstorage_auto
callid_created The integer returned through ast_callid_threadstorage_auto

Definition at line 1611 of file logger.c.

References ast_callid_threadassoc_remove().

Referenced by __analog_handle_event(), analog_handle_init_event(), dahdi_handle_event(), dahdi_new_callid_clean(), dahdi_request(), do_monitor(), handle_init_event(), and mwi_thread().

01612 {
01613    if (callid && callid_created) {
01614       /* If the callid was created rather than simply grabbed from the thread storage, we need to unbind here. */
01615       ast_callid_threadassoc_remove();
01616    }
01617 }

void ast_child_verbose ( int  level,
const char *  fmt,
  ... 
)

Definition at line 503 of file logger.c.

References ast_free, ast_malloc, and NULL.

Referenced by launch_script().

00504 {
00505    char *msg = NULL, *emsg = NULL, *sptr, *eptr;
00506    va_list ap, aq;
00507    int size;
00508 
00509    va_start(ap, fmt);
00510    va_copy(aq, ap);
00511    if ((size = vsnprintf(msg, 0, fmt, ap)) < 0) {
00512       va_end(ap);
00513       va_end(aq);
00514       return;
00515    }
00516    va_end(ap);
00517 
00518    if (!(msg = ast_malloc(size + 1))) {
00519       va_end(aq);
00520       return;
00521    }
00522 
00523    vsnprintf(msg, size + 1, fmt, aq);
00524    va_end(aq);
00525 
00526    if (!(emsg = ast_malloc(size * 2 + 1))) {
00527       ast_free(msg);
00528       return;
00529    }
00530 
00531    for (sptr = msg, eptr = emsg; ; sptr++) {
00532       if (*sptr == '"') {
00533          *eptr++ = '\\';
00534       }
00535       *eptr++ = *sptr;
00536       if (*sptr == '\0') {
00537          break;
00538       }
00539    }
00540    ast_free(msg);
00541 
00542    fprintf(stdout, "verbose \"%s\" %d\n", emsg, level);
00543    fflush(stdout);
00544    ast_free(emsg);
00545 }

ast_callid ast_create_callid ( void   ) 

factory function to create a new uniquely identifying callid.

Return values:
The call id

Definition at line 1497 of file logger.c.

References ast_atomic_fetchadd_int(), ast_debug, and call().

Referenced by __ast_pbx_run(), __find_call(), ast_callid_threadstorage_auto(), iax_pvt_callid_new(), and jingle_alloc().

01498 {
01499    ast_callid call;
01500 
01501    call = ast_atomic_fetchadd_int(&next_unique_callid, +1);
01502 #ifdef TEST_FRAMEWORK
01503    ast_debug(3, "CALL_ID [C-%08x] created by thread.\n", call);
01504 #endif
01505    return call;
01506 }

void ast_log ( int  level,
const char *  file,
int  line,
const char *  function,
const char *  fmt,
  ... 
)

Used for sending a log message This is the standard logger function. Probably the only way you will invoke it would be something like this: ast_log(AST_LOG_WHATEVER, "Problem with the %s Captain. We should get some more. Will %d be enough?\n", "flux capacitor", 10); where WHATEVER is one of ERROR, DEBUG, EVENT, NOTICE, or WARNING depending on which log you wish to output to. These are implemented as macros, that will provide the function with the needed arguments.

Parameters:
level Type of log event
file Will be provided by the AST_LOG_* macro
line Will be provided by the AST_LOG_* macro
function Will be provided by the AST_LOG_* macro
fmt This is what is important. The format is the same as your favorite breed of printf. You know how that works, right? :-)

Definition at line 1707 of file logger.c.

References __ast_verbose_ap(), __LOG_VERBOSE, ast_log_full(), and ast_read_threadstorage_callid().

01708 {
01709    ast_callid callid;
01710    va_list ap;
01711 
01712    callid = ast_read_threadstorage_callid();
01713 
01714    va_start(ap, fmt);
01715    if (level == __LOG_VERBOSE) {
01716       __ast_verbose_ap(file, line, function, 0, callid, fmt, ap);
01717    } else {
01718       ast_log_full(level, file, line, function, callid, fmt, ap);
01719    }
01720    va_end(ap);
01721 }

void ast_log_backtrace ( void   ) 

Log a backtrace of the current thread's execution stack to the Asterisk log.

Definition at line 1758 of file logger.c.

References ast_bt::addresses, ast_bt_create, ast_bt_destroy, ast_bt_get_symbols, ast_log, ast_std_free, ast_verbose, LOG_WARNING, and ast_bt::num_frames.

01759 {
01760 #ifdef HAVE_BKTR
01761    struct ast_bt *bt;
01762    int i = 0;
01763    char **strings;
01764 
01765    if (!(bt = ast_bt_create())) {
01766       ast_log(LOG_WARNING, "Unable to allocate space for backtrace structure\n");
01767       return;
01768    }
01769 
01770    if ((strings = ast_bt_get_symbols(bt->addresses, bt->num_frames))) {
01771       ast_verbose("Got %d backtrace record%c\n", bt->num_frames, bt->num_frames != 1 ? 's' : ' ');
01772       for (i = 3; i < bt->num_frames - 2; i++) {
01773          ast_verbose("#%d: [%p] %s\n", i - 3, bt->addresses[i], strings[i]);
01774       }
01775 
01776       ast_std_free(strings);
01777    } else {
01778       ast_verbose("Could not allocate memory for backtrace\n");
01779    }
01780    ast_bt_destroy(bt);
01781 #else
01782    ast_log(LOG_WARNING, "Must run configure with '--with-execinfo' for stack backtraces.\n");
01783 #endif /* defined(HAVE_BKTR) */
01784 }

void ast_log_callid ( int  level,
const char *  file,
int  line,
const char *  function,
ast_callid  callid,
const char *  fmt,
  ... 
)

Used for sending a log message with a known call_id This is a modified logger function which is functionally identical to the above logger function, it just include a call_id argument as well. If NULL is specified here, no attempt will be made to join the log message with a call_id.

Parameters:
level Type of log event
file Will be provided by the AST_LOG_* macro
line Will be provided by the AST_LOG_* macro
function Will be provided by the AST_LOG_* macro
callid This is the ast_callid that is associated with the log message. May be NULL.
fmt This is what is important. The format is the same as your favorite breed of printf. You know how that works, right? :-)

Definition at line 1749 of file logger.c.

References ast_log_full().

Referenced by __ast_verbose_ap(), and ast_channel_destructor().

01750 {
01751    va_list ap;
01752    va_start(ap, fmt);
01753    ast_log_full(level, file, line, function, callid, fmt, ap);
01754    va_end(ap);
01755 }

static void ast_log_full ( int  level,
const char *  file,
int  line,
const char *  function,
ast_callid  callid,
const char *  fmt,
va_list  ap 
) [static]

send log messages to syslog and/or the console

Definition at line 1622 of file logger.c.

References __LOG_VERBOSE, ast_calloc_with_stringfields, ast_cond_signal, AST_DYNSTR_BUILD_FAILED, ast_get_tid(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_localtime(), AST_PTHREADT_NULL, AST_RWLIST_EMPTY, ast_str_buffer(), ast_str_set_va(), ast_str_thread_get(), ast_strftime(), ast_string_field_set, ast_tvnow(), buf, logmsg::callid, close_logger_thread, logmsg::level, levels, logmsg::line, logchannel::list, log_buf, LOG_BUF_INIT_SIZE, logcond, logger_print_normal(), logmsg_free(), LOGMSG_NORMAL, LOGMSG_VERBOSE, logthread, logmsg::lwp, NULL, result, term_filter_escapes(), and logmsg::type.

Referenced by ast_log(), ast_log_callid(), and ast_log_safe().

01623 {
01624    struct logmsg *logmsg = NULL;
01625    struct ast_str *buf = NULL;
01626    struct ast_tm tm;
01627    struct timeval now = ast_tvnow();
01628    int res = 0;
01629    char datestring[256];
01630 
01631    if (!(buf = ast_str_thread_get(&log_buf, LOG_BUF_INIT_SIZE)))
01632       return;
01633 
01634    if (level != __LOG_VERBOSE && AST_RWLIST_EMPTY(&logchannels)) {
01635       /*
01636        * we don't have the logger chain configured yet,
01637        * so just log to stdout
01638        */
01639       int result;
01640       result = ast_str_set_va(&buf, BUFSIZ, fmt, ap); /* XXX BUFSIZ ? */
01641       if (result != AST_DYNSTR_BUILD_FAILED) {
01642          term_filter_escapes(ast_str_buffer(buf));
01643          fputs(ast_str_buffer(buf), stdout);
01644       }
01645       return;
01646    }
01647 
01648    /* Ignore anything that never gets logged anywhere */
01649    if (level != __LOG_VERBOSE && !(global_logmask & (1 << level)))
01650       return;
01651 
01652    /* Build string */
01653    res = ast_str_set_va(&buf, BUFSIZ, fmt, ap);
01654 
01655    /* If the build failed, then abort and free this structure */
01656    if (res == AST_DYNSTR_BUILD_FAILED)
01657       return;
01658 
01659    /* Create a new logging message */
01660    if (!(logmsg = ast_calloc_with_stringfields(1, struct logmsg, res + 128)))
01661       return;
01662 
01663    /* Copy string over */
01664    ast_string_field_set(logmsg, message, ast_str_buffer(buf));
01665 
01666    /* Set type */
01667    if (level == __LOG_VERBOSE) {
01668       logmsg->type = LOGMSG_VERBOSE;
01669    } else {
01670       logmsg->type = LOGMSG_NORMAL;
01671    }
01672 
01673    if (display_callids && callid) {
01674       logmsg->callid = callid;
01675    }
01676 
01677    /* Create our date/time */
01678    ast_localtime(&now, &tm, NULL);
01679    ast_strftime(datestring, sizeof(datestring), dateformat, &tm);
01680    ast_string_field_set(logmsg, date, datestring);
01681 
01682    /* Copy over data */
01683    logmsg->level = level;
01684    logmsg->line = line;
01685    ast_string_field_set(logmsg, level_name, levels[level]);
01686    ast_string_field_set(logmsg, file, file);
01687    ast_string_field_set(logmsg, function, function);
01688    logmsg->lwp = ast_get_tid();
01689 
01690    /* If the logger thread is active, append it to the tail end of the list - otherwise skip that step */
01691    if (logthread != AST_PTHREADT_NULL) {
01692       AST_LIST_LOCK(&logmsgs);
01693       if (close_logger_thread) {
01694          /* Logger is either closing or closed.  We cannot log this message. */
01695          logmsg_free(logmsg);
01696       } else {
01697          AST_LIST_INSERT_TAIL(&logmsgs, logmsg, list);
01698          ast_cond_signal(&logcond);
01699       }
01700       AST_LIST_UNLOCK(&logmsgs);
01701    } else {
01702       logger_print_normal(logmsg);
01703       logmsg_free(logmsg);
01704    }
01705 }

void ast_log_safe ( int  level,
const char *  file,
int  line,
const char *  function,
const char *  fmt,
  ... 
)

Used for sending a log message with protection against recursion.

Note:
This function should be used by all error messages that might be directly or indirectly caused by logging.
See also:
ast_log for documentation on the parameters.

Definition at line 1723 of file logger.c.

References ast_log_full(), ast_read_threadstorage_callid(), ast_threadstorage_get_ptr(), ast_threadstorage_set_ptr(), and NULL.

Referenced by __ast_str_helper().

01724 {
01725    va_list ap;
01726    void *recursed = ast_threadstorage_get_ptr(&in_safe_log);
01727    ast_callid callid;
01728 
01729    if (recursed) {
01730       return;
01731    }
01732 
01733    if (ast_threadstorage_set_ptr(&in_safe_log, (void*)1)) {
01734       /* We've failed to set the flag that protects against
01735        * recursion, so bail. */
01736       return;
01737    }
01738 
01739    callid = ast_read_threadstorage_callid();
01740 
01741    va_start(ap, fmt);
01742    ast_log_full(level, file, line, function, callid, fmt, ap);
01743    va_end(ap);
01744 
01745    /* Clear flag so the next allocation failure can be logged. */
01746    ast_threadstorage_set_ptr(&in_safe_log, NULL);
01747 }

static void ast_log_vsyslog ( struct logmsg msg  )  [static]

Definition at line 1141 of file logger.c.

References ast_syslog_priority_from_loglevel(), buf, logmsg::callid, logmsg::file, logmsg::function, logmsg::level, levels, logmsg::line, logmsg::lwp, logmsg::message, and term_strip().

Referenced by logger_print_normal().

01142 {
01143    char buf[BUFSIZ];
01144    int syslog_level = ast_syslog_priority_from_loglevel(msg->level);
01145    char call_identifier_str[13];
01146 
01147    if (msg->callid) {
01148       snprintf(call_identifier_str, sizeof(call_identifier_str), "[C-%08x]", msg->callid);
01149    } else {
01150       call_identifier_str[0] = '\0';
01151    }
01152 
01153    if (syslog_level < 0) {
01154       /* we are locked here, so cannot ast_log() */
01155       fprintf(stderr, "ast_log_vsyslog called with bogus level: %d\n", msg->level);
01156       return;
01157    }
01158 
01159    snprintf(buf, sizeof(buf), "%s[%d]%s: %s:%d in %s: %s",
01160        levels[msg->level], msg->lwp, call_identifier_str, msg->file, msg->line, msg->function, msg->message);
01161 
01162    term_strip(buf, buf, strlen(buf) + 1);
01163    syslog(syslog_level, "%s", buf);
01164 }

const char* ast_logger_get_dateformat ( void   ) 

Get the logger configured date format.

Return values:
The date format string
Since:
13.0.0

Definition at line 2146 of file logger.c.

Referenced by set_header().

02147 {
02148    return dateformat;
02149 }

int ast_logger_register_level ( const char *  name  ) 

Register a new logger level.

Parameters:
name The name of the level to be registered
Return values:
-1 if an error occurs
non-zero level to be used with ast_log for sending messages to this level
Since:
1.8

Definition at line 2064 of file logger.c.

References ARRAY_LEN, ast_debug, ast_log, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strdup, available(), levels, LOG_WARNING, and update_logchannels().

Referenced by ast_cc_init(), handle_cli_dynamic_level_test(), handle_cli_performance_test(), and load_module().

02065 {
02066    unsigned int level;
02067    unsigned int available = 0;
02068 
02069    AST_RWLIST_WRLOCK(&logchannels);
02070 
02071    for (level = 0; level < ARRAY_LEN(levels); level++) {
02072       if ((level >= 16) && !available && !levels[level]) {
02073          available = level;
02074          continue;
02075       }
02076 
02077       if (levels[level] && !strcasecmp(levels[level], name)) {
02078          ast_log(LOG_WARNING,
02079             "Unable to register dynamic logger level '%s': a standard logger level uses that name.\n",
02080             name);
02081          AST_RWLIST_UNLOCK(&logchannels);
02082 
02083          return -1;
02084       }
02085    }
02086 
02087    if (!available) {
02088       ast_log(LOG_WARNING,
02089          "Unable to register dynamic logger level '%s'; maximum number of levels registered.\n",
02090          name);
02091       AST_RWLIST_UNLOCK(&logchannels);
02092 
02093       return -1;
02094    }
02095 
02096    levels[available] = ast_strdup(name);
02097 
02098    AST_RWLIST_UNLOCK(&logchannels);
02099 
02100    ast_debug(1, "Registered dynamic logger level '%s' with index %u.\n", name, available);
02101 
02102    update_logchannels();
02103 
02104    return available;
02105 }

int ast_logger_rotate ( void   ) 

Reload logger while rotating log files.

Definition at line 917 of file logger.c.

References NULL, and reload_logger().

Referenced by action_loggerrotate().

00918 {
00919    return reload_logger(1, NULL);
00920 }

void ast_logger_unregister_level ( const char *  name  ) 

Unregister a previously registered logger level.

Parameters:
name The name of the level to be unregistered
Returns:
nothing
Since:
1.8

Definition at line 2107 of file logger.c.

References ARRAY_LEN, ast_debug, ast_free, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, levels, NULL, and update_logchannels().

Referenced by cc_shutdown(), handle_cli_dynamic_level_test(), handle_cli_performance_test(), load_module(), and unload_module().

02108 {
02109    unsigned int found = 0;
02110    unsigned int x;
02111 
02112    AST_RWLIST_WRLOCK(&logchannels);
02113 
02114    for (x = 16; x < ARRAY_LEN(levels); x++) {
02115       if (!levels[x]) {
02116          continue;
02117       }
02118 
02119       if (strcasecmp(levels[x], name)) {
02120          continue;
02121       }
02122 
02123       found = 1;
02124       break;
02125    }
02126 
02127    if (found) {
02128       /* take this level out of the global_logmask, to ensure that no new log messages
02129        * will be queued for it
02130        */
02131 
02132       global_logmask &= ~(1 << x);
02133 
02134       ast_free(levels[x]);
02135       levels[x] = NULL;
02136       AST_RWLIST_UNLOCK(&logchannels);
02137 
02138       ast_debug(1, "Unregistered dynamic logger level '%s' with index %u.\n", name, x);
02139 
02140       update_logchannels();
02141    } else {
02142       AST_RWLIST_UNLOCK(&logchannels);
02143    }
02144 }

void ast_queue_log ( const char *  queuename,
const char *  callid,
const char *  agent,
const char *  event,
const char *  fmt,
  ... 
)

Definition at line 547 of file logger.c.

References args, AST_APP_ARG, ast_check_realtime(), AST_DECLARE_APP_ARGS, ast_localtime(), AST_NONSTANDARD_APP_ARGS, ast_realtime_require_field(), AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_store_realtime(), ast_strftime(), ast_tvnow(), logfiles, logger_queue_start(), NULL, qlog, RQ_CHAR, S_OR, and SENTINEL.

Referenced by aqm_exec(), find_queue_by_name_rt(), handle_blind_transfer(), handle_hangup(), handle_queue_add_member(), handle_queue_remove_member(), log_attended_transfer(), logger_queue_start(), manager_add_queue_member(), manager_queue_log_custom(), manager_remove_queue_member(), ql_exec(), queue_agent_cb(), queue_exec(), reload_logger(), rna(), rqm_exec(), rt_handle_member_record(), set_member_paused(), set_member_penalty_help_members(), set_member_ringinuse_help_members(), try_calling(), update_realtime_members(), and wait_our_turn().

00548 {
00549    va_list ap;
00550    struct timeval tv;
00551    struct ast_tm tm;
00552    char qlog_msg[8192];
00553    int qlog_len;
00554    char time_str[30];
00555 
00556    if (!logger_initialized) {
00557       /* You are too early.  We are not open yet! */
00558       return;
00559    }
00560    if (!queuelog_init) {
00561       /* We must initialize now since someone is trying to log something. */
00562       logger_queue_start();
00563    }
00564 
00565    if (ast_check_realtime("queue_log")) {
00566       tv = ast_tvnow();
00567       ast_localtime(&tv, &tm, logfiles.queue_log_realtime_use_gmt ? "GMT" : NULL);
00568       ast_strftime(time_str, sizeof(time_str), "%F %T.%6q", &tm);
00569       va_start(ap, fmt);
00570       vsnprintf(qlog_msg, sizeof(qlog_msg), fmt, ap);
00571       va_end(ap);
00572       if (logfiles.queue_adaptive_realtime) {
00573          AST_DECLARE_APP_ARGS(args,
00574             AST_APP_ARG(data)[5];
00575          );
00576          AST_NONSTANDARD_APP_ARGS(args, qlog_msg, '|');
00577          /* Ensure fields are large enough to receive data */
00578          ast_realtime_require_field("queue_log",
00579             "data1", RQ_CHAR, strlen(S_OR(args.data[0], "")),
00580             "data2", RQ_CHAR, strlen(S_OR(args.data[1], "")),
00581             "data3", RQ_CHAR, strlen(S_OR(args.data[2], "")),
00582             "data4", RQ_CHAR, strlen(S_OR(args.data[3], "")),
00583             "data5", RQ_CHAR, strlen(S_OR(args.data[4], "")),
00584             SENTINEL);
00585 
00586          /* Store the log */
00587          ast_store_realtime("queue_log", "time", time_str,
00588             "callid", callid,
00589             "queuename", queuename,
00590             "agent", agent,
00591             "event", event,
00592             "data1", S_OR(args.data[0], ""),
00593             "data2", S_OR(args.data[1], ""),
00594             "data3", S_OR(args.data[2], ""),
00595             "data4", S_OR(args.data[3], ""),
00596             "data5", S_OR(args.data[4], ""),
00597             SENTINEL);
00598       } else {
00599          ast_store_realtime("queue_log", "time", time_str,
00600             "callid", callid,
00601             "queuename", queuename,
00602             "agent", agent,
00603             "event", event,
00604             "data", qlog_msg,
00605             SENTINEL);
00606       }
00607 
00608       if (!logfiles.queue_log_to_file) {
00609          return;
00610       }
00611    }
00612 
00613    if (qlog) {
00614       va_start(ap, fmt);
00615       qlog_len = snprintf(qlog_msg, sizeof(qlog_msg), "%ld|%s|%s|%s|%s|", (long)time(NULL), callid, queuename, agent, event);
00616       vsnprintf(qlog_msg + qlog_len, sizeof(qlog_msg) - qlog_len, fmt, ap);
00617       va_end(ap);
00618       AST_RWLIST_RDLOCK(&logchannels);
00619       if (qlog) {
00620          fprintf(qlog, "%s\n", qlog_msg);
00621          fflush(qlog);
00622       }
00623       AST_RWLIST_UNLOCK(&logchannels);
00624    }
00625 }

ast_callid ast_read_threadstorage_callid ( void   ) 

extracts the callerid from the thread

Return values:
Non-zero Call id related to the thread
0 if no call_id is present in the thread

Definition at line 1508 of file logger.c.

References ast_threadstorage_get(), and unique_callid.

Referenced by __ast_pbx_run(), __ast_verbose(), ast_bridge_impart(), ast_callid_threadstorage_auto(), ast_dial_run(), ast_log(), ast_log_safe(), ast_verbose(), bridge_channel_internal_join(), common_recall_channel_setup(), iax2_request(), jingle_alloc(), launch_monitor_thread(), local_request(), media_request_helper(), sip_request_call(), and socket_process().

01509 {
01510    ast_callid *callid;
01511 
01512    callid = ast_threadstorage_get(&unique_callid, sizeof(*callid));
01513 
01514    return callid ? *callid : 0;
01515 
01516 }

int ast_register_verbose ( void(*)(const char *string v  ) 

Definition at line 2014 of file logger.c.

References ast_malloc, AST_RWLIST_INSERT_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, logchannel::list, and verb::verboser.

Referenced by ast_makesocket(), and print_intro_message().

02015 {
02016    struct verb *verb;
02017 
02018    if (!(verb = ast_malloc(sizeof(*verb))))
02019       return -1;
02020 
02021    verb->verboser = v;
02022 
02023    AST_RWLIST_WRLOCK(&verbosers);
02024    AST_RWLIST_INSERT_HEAD(&verbosers, verb, list);
02025    AST_RWLIST_UNLOCK(&verbosers);
02026 
02027    return 0;
02028 }

AST_THREADSTORAGE_RAW ( in_safe_log   ) 

int ast_unregister_verbose ( void(*)(const char *string v  ) 

Definition at line 2030 of file logger.c.

References ast_free, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, logchannel::list, and verb::verboser.

02031 {
02032    struct verb *cur;
02033 
02034    AST_RWLIST_WRLOCK(&verbosers);
02035    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&verbosers, cur, list) {
02036       if (cur->verboser == v) {
02037          AST_RWLIST_REMOVE_CURRENT(list);
02038          ast_free(cur);
02039          break;
02040       }
02041    }
02042    AST_RWLIST_TRAVERSE_SAFE_END;
02043    AST_RWLIST_UNLOCK(&verbosers);
02044 
02045    return cur ? 0 : -1;
02046 }

int ast_verb_console_get ( void   ) 

Get this thread's console verbosity level.

Return values:
verbosity level of the console.

Definition at line 1977 of file logger.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_threadstorage_get(), verb_console::level, my_verb_console, and option_verbose.

Referenced by handle_show_settings(), handle_verbose(), and remoteconsolehandler().

01978 {
01979    struct verb_console *console;
01980    int verb_level;
01981 
01982    console = ast_threadstorage_get(&my_verb_console, sizeof(*console));
01983    AST_RWLIST_RDLOCK(&verb_consoles);
01984    if (!console) {
01985       verb_level = 0;
01986    } else if (console->level) {
01987       verb_level = *console->level;
01988    } else {
01989       verb_level = option_verbose;
01990    }
01991    AST_RWLIST_UNLOCK(&verb_consoles);
01992    return verb_level;
01993 }

void ast_verb_console_register ( int *  level  ) 

Register this thread's console verbosity level pointer.

Parameters:
level Where the verbose level value is.
Returns:
Nothing

Definition at line 1950 of file logger.c.

References AST_RWLIST_INSERT_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_threadstorage_get(), ast_verb_update(), verb_console::level, and my_verb_console.

Referenced by netconsole().

01951 {
01952    struct verb_console *console;
01953 
01954    console = ast_threadstorage_get(&my_verb_console, sizeof(*console));
01955    if (!console || !level) {
01956       return;
01957    }
01958    console->level = level;
01959 
01960    AST_RWLIST_WRLOCK(&verb_consoles);
01961    AST_RWLIST_INSERT_HEAD(&verb_consoles, console, node);
01962    AST_RWLIST_UNLOCK(&verb_consoles);
01963    ast_verb_update();
01964 }

void ast_verb_console_set ( int  verb_level  ) 

Set this thread's console verbosity level.

Parameters:
verb_level New level to set.
Returns:
Nothing

Definition at line 1995 of file logger.c.

References AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_threadstorage_get(), ast_verb_update(), verb_console::level, my_verb_console, and option_verbose.

Referenced by handle_verbose(), and remoteconsolehandler().

01996 {
01997    struct verb_console *console;
01998 
01999    console = ast_threadstorage_get(&my_verb_console, sizeof(*console));
02000    if (!console) {
02001       return;
02002    }
02003 
02004    AST_RWLIST_WRLOCK(&verb_consoles);
02005    if (console->level) {
02006       *console->level = verb_level;
02007    } else {
02008       option_verbose = verb_level;
02009    }
02010    AST_RWLIST_UNLOCK(&verb_consoles);
02011    ast_verb_update();
02012 }

void ast_verb_console_unregister ( void   ) 

Unregister this thread's console verbosity level.

Returns:
Nothing

Definition at line 1966 of file logger.c.

References ast_threadstorage_get(), my_verb_console, and verb_console_unregister().

Referenced by netconsole().

01967 {
01968    struct verb_console *console;
01969 
01970    console = ast_threadstorage_get(&my_verb_console, sizeof(*console));
01971    if (!console) {
01972       return;
01973    }
01974    verb_console_unregister(console);
01975 }

void ast_verb_update ( void   ) 

Re-evaluate the system max verbosity level (ast_verb_sys_level).

Returns:
Nothing

Definition at line 1886 of file logger.c.

References AST_LIST_TRAVERSE, ast_mutex_lock, ast_mutex_unlock, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_verb_sys_level, verb_console::level, logchannel::list, option_verbose, and logchannel::verbosity.

Referenced by ast_verb_console_register(), ast_verb_console_set(), init_logger(), reload_logger(), and verb_console_unregister().

01887 {
01888    struct logchannel *log;
01889    struct verb_console *console;
01890    int verb_level;
01891 
01892    ast_mutex_lock(&verb_update_lock);
01893 
01894    AST_RWLIST_RDLOCK(&verb_consoles);
01895 
01896    /* Default to the root console verbosity. */
01897    verb_level = option_verbose;
01898 
01899    /* Determine max remote console level. */
01900    AST_LIST_TRAVERSE(&verb_consoles, console, node) {
01901       if (verb_level < *console->level) {
01902          verb_level = *console->level;
01903       }
01904    }
01905    AST_RWLIST_UNLOCK(&verb_consoles);
01906 
01907    /* Determine max logger channel level. */
01908    AST_RWLIST_RDLOCK(&logchannels);
01909    AST_RWLIST_TRAVERSE(&logchannels, log, list) {
01910       if (verb_level < log->verbosity) {
01911          verb_level = log->verbosity;
01912       }
01913    }
01914    AST_RWLIST_UNLOCK(&logchannels);
01915 
01916    ast_verb_sys_level = verb_level;
01917 
01918    ast_mutex_unlock(&verb_update_lock);
01919 }

void ast_verbose ( const char *  fmt,
  ... 
)

Definition at line 1860 of file logger.c.

References __ast_verbose_ap(), and ast_read_threadstorage_callid().

01861 {
01862    ast_callid callid;
01863    va_list ap;
01864 
01865    callid = ast_read_threadstorage_callid();
01866 
01867    va_start(ap, fmt);
01868    __ast_verbose_ap("", 0, "", 0, callid, fmt, ap);
01869    va_end(ap);
01870 }

void close_logger ( void   ) 

Provided by logger.c

Definition at line 1448 of file logger.c.

References ARRAY_LEN, ast_cli_unregister_multiple(), ast_cond_signal, ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, AST_PTHREADT_NULL, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, cli_logger, close_logger_thread, f, logchannel::fileptr, logchannel::list, logcond, logthread, NULL, and qlog.

Referenced by really_quit().

01449 {
01450    struct logchannel *f = NULL;
01451    struct verb *cur = NULL;
01452 
01453    ast_cli_unregister_multiple(cli_logger, ARRAY_LEN(cli_logger));
01454 
01455    logger_initialized = 0;
01456 
01457    /* Stop logger thread */
01458    AST_LIST_LOCK(&logmsgs);
01459    close_logger_thread = 1;
01460    ast_cond_signal(&logcond);
01461    AST_LIST_UNLOCK(&logmsgs);
01462 
01463    if (logthread != AST_PTHREADT_NULL)
01464       pthread_join(logthread, NULL);
01465 
01466    AST_RWLIST_WRLOCK(&verbosers);
01467    while ((cur = AST_LIST_REMOVE_HEAD(&verbosers, list))) {
01468       ast_free(cur);
01469    }
01470    AST_RWLIST_UNLOCK(&verbosers);
01471 
01472    AST_RWLIST_WRLOCK(&logchannels);
01473 
01474    if (qlog) {
01475       fclose(qlog);
01476       qlog = NULL;
01477    }
01478 
01479    while ((f = AST_LIST_REMOVE_HEAD(&logchannels, list))) {
01480       if (f->fileptr && (f->fileptr != stdout) && (f->fileptr != stderr)) {
01481          fclose(f->fileptr);
01482          f->fileptr = NULL;
01483       }
01484       ast_free(f);
01485    }
01486 
01487    closelog(); /* syslog */
01488 
01489    AST_RWLIST_UNLOCK(&logchannels);
01490 }

static char* handle_logger_add_channel ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1003 of file logger.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_RWLIST_INSERT_HEAD, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, logchannel::filename, logchannel::list, logchannel::logmask, make_logchannel(), NULL, and ast_cli_entry::usage.

01004 {
01005    struct logchannel *chan;
01006 
01007    switch (cmd) {
01008    case CLI_INIT:
01009       e->command = "logger add channel";
01010       e->usage =
01011          "Usage: logger add channel <name> <levels>\n"
01012          "       Adds a temporary logger channel. This logger channel\n"
01013          "       will exist until removed or until Asterisk is restarted.\n"
01014          "       <levels> is a comma-separated list of desired logger\n"
01015          "       levels such as: verbose,warning,error\n";
01016       return NULL;
01017    case CLI_GENERATE:
01018       return NULL;
01019    }
01020 
01021    if (a->argc < 5) {
01022       return CLI_SHOWUSAGE;
01023    }
01024 
01025    AST_RWLIST_WRLOCK(&logchannels);
01026    AST_RWLIST_TRAVERSE(&logchannels, chan, list) {
01027       if (!strcmp(chan->filename, a->argv[3])) {
01028          break;
01029       }
01030    }
01031 
01032    if (chan) {
01033       AST_RWLIST_UNLOCK(&logchannels);
01034       ast_cli(a->fd, "Logger channel '%s' already exists\n", a->argv[3]);
01035       return CLI_SUCCESS;
01036    }
01037 
01038    chan = make_logchannel(a->argv[3], a->argv[4], 0, 1);
01039    if (chan) {
01040       AST_RWLIST_INSERT_HEAD(&logchannels, chan, list);
01041       global_logmask |= chan->logmask;
01042       AST_RWLIST_UNLOCK(&logchannels);
01043       return CLI_SUCCESS;
01044    }
01045 
01046    AST_RWLIST_UNLOCK(&logchannels);
01047    ast_cli(a->fd, "ERROR: Unable to create log channel '%s'\n", a->argv[3]);
01048 
01049    return CLI_FAILURE;
01050 }

static char* handle_logger_reload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 879 of file logger.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, NULL, reload_logger(), and ast_cli_entry::usage.

00880 {
00881    switch (cmd) {
00882    case CLI_INIT:
00883       e->command = "logger reload";
00884       e->usage =
00885          "Usage: logger reload [<alt-conf>]\n"
00886          "       Reloads the logger subsystem state.  Use after restarting syslogd(8) if you are using syslog logging.\n";
00887       return NULL;
00888    case CLI_GENERATE:
00889       return NULL;
00890    }
00891    if (reload_logger(0, a->argc == 3 ? a->argv[2] : NULL)) {
00892       ast_cli(a->fd, "Failed to reload the logger\n");
00893       return CLI_FAILURE;
00894    }
00895    return CLI_SUCCESS;
00896 }

static char* handle_logger_remove_channel ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1052 of file logger.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_free, AST_RWLIST_RDLOCK, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strdup, ast_strlen_zero, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, logchannel::dynamic, ast_cli_args::fd, logchannel::filename, logchannel::fileptr, logchannel::list, ast_cli_args::n, NULL, ast_cli_args::pos, and ast_cli_entry::usage.

01053 {
01054    struct logchannel *chan;
01055    int gen_count = 0;
01056    char *gen_ret = NULL;
01057 
01058    switch (cmd) {
01059    case CLI_INIT:
01060       e->command = "logger remove channel";
01061       e->usage =
01062          "Usage: logger remove channel <name>\n"
01063          "       Removes a temporary logger channel.\n";
01064       return NULL;
01065    case CLI_GENERATE:
01066       if (a->argc > 4 || (a->argc == 4 && a->pos > 3)) {
01067          return NULL;
01068       }
01069       AST_RWLIST_RDLOCK(&logchannels);
01070       AST_RWLIST_TRAVERSE(&logchannels, chan, list) {
01071          if (chan->dynamic && (ast_strlen_zero(a->argv[3])
01072             || !strncmp(a->argv[3], chan->filename, strlen(a->argv[3])))) {
01073             if (gen_count == a->n) {
01074                gen_ret = ast_strdup(chan->filename);
01075                break;
01076             }
01077             gen_count++;
01078          }
01079       }
01080       AST_RWLIST_UNLOCK(&logchannels);
01081       return gen_ret;
01082    }
01083 
01084    if (a->argc < 4) {
01085       return CLI_SHOWUSAGE;
01086    }
01087 
01088    AST_RWLIST_WRLOCK(&logchannels);
01089    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&logchannels, chan, list) {
01090       if (chan->dynamic && !strcmp(chan->filename, a->argv[3])) {
01091          AST_RWLIST_REMOVE_CURRENT(list);
01092          break;
01093       }
01094    }
01095    AST_RWLIST_TRAVERSE_SAFE_END;
01096    AST_RWLIST_UNLOCK(&logchannels);
01097 
01098    if (!chan) {
01099       ast_cli(a->fd, "Unable to find dynamic logger channel '%s'\n", a->argv[3]);
01100       return CLI_SUCCESS;
01101    }
01102 
01103    ast_cli(a->fd, "Removed dynamic logger channel '%s'\n", chan->filename);
01104    if (chan->fileptr) {
01105       fclose(chan->fileptr);
01106       chan->fileptr = NULL;
01107    }
01108    ast_free(chan);
01109    chan = NULL;
01110 
01111    return CLI_SUCCESS;
01112 }

static char* handle_logger_rotate ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 898 of file logger.c.

References ast_cli(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, NULL, reload_logger(), and ast_cli_entry::usage.

00899 {
00900    switch (cmd) {
00901    case CLI_INIT:
00902       e->command = "logger rotate";
00903       e->usage =
00904          "Usage: logger rotate\n"
00905          "       Rotates and Reopens the log files.\n";
00906       return NULL;
00907    case CLI_GENERATE:
00908       return NULL;
00909    }
00910    if (reload_logger(1, NULL)) {
00911       ast_cli(a->fd, "Failed to reload the logger and rotate log files\n");
00912       return CLI_FAILURE;
00913    }
00914    return CLI_SUCCESS;
00915 }

static char* handle_logger_set_level ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 922 of file logger.c.

References ast_cli_args::argc, ast_cli_args::argv, ARRAY_LEN, ast_cli(), ast_console_toggle_loglevel(), AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_true(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, levels, NULL, and ast_cli_entry::usage.

00923 {
00924    int x;
00925    int state;
00926    int level = -1;
00927 
00928    switch (cmd) {
00929    case CLI_INIT:
00930       e->command = "logger set level {DEBUG|NOTICE|WARNING|ERROR|VERBOSE|DTMF} {on|off}";
00931       e->usage =
00932          "Usage: logger set level {DEBUG|NOTICE|WARNING|ERROR|VERBOSE|DTMF} {on|off}\n"
00933          "       Set a specific log level to enabled/disabled for this console.\n";
00934       return NULL;
00935    case CLI_GENERATE:
00936       return NULL;
00937    }
00938 
00939    if (a->argc < 5)
00940       return CLI_SHOWUSAGE;
00941 
00942    AST_RWLIST_WRLOCK(&logchannels);
00943 
00944    for (x = 0; x < ARRAY_LEN(levels); x++) {
00945       if (levels[x] && !strcasecmp(a->argv[3], levels[x])) {
00946          level = x;
00947          break;
00948       }
00949    }
00950 
00951    AST_RWLIST_UNLOCK(&logchannels);
00952 
00953    state = ast_true(a->argv[4]) ? 1 : 0;
00954 
00955    if (level != -1) {
00956       ast_console_toggle_loglevel(a->fd, level, state);
00957       ast_cli(a->fd, "Logger status for '%s' has been set to '%s'.\n", levels[level], state ? "on" : "off");
00958    } else
00959       return CLI_SHOWUSAGE;
00960 
00961    return CLI_SUCCESS;
00962 }

static char* handle_logger_show_channels ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

CLI command to show logging system configuration.

Definition at line 965 of file logger.c.

References ARRAY_LEN, ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, logchannel::disabled, ast_cli_args::fd, logchannel::filename, FORMATL, levels, logchannel::list, logchannel::logmask, LOGTYPE_CONSOLE, LOGTYPE_SYSLOG, NULL, logchannel::type, and ast_cli_entry::usage.

00966 {
00967 #define FORMATL   "%-35.35s %-8.8s %-9.9s "
00968    struct logchannel *chan;
00969    switch (cmd) {
00970    case CLI_INIT:
00971       e->command = "logger show channels";
00972       e->usage =
00973          "Usage: logger show channels\n"
00974          "       List configured logger channels.\n";
00975       return NULL;
00976    case CLI_GENERATE:
00977       return NULL;
00978    }
00979    ast_cli(a->fd, FORMATL, "Channel", "Type", "Status");
00980    ast_cli(a->fd, "Configuration\n");
00981    ast_cli(a->fd, FORMATL, "-------", "----", "------");
00982    ast_cli(a->fd, "-------------\n");
00983    AST_RWLIST_RDLOCK(&logchannels);
00984    AST_RWLIST_TRAVERSE(&logchannels, chan, list) {
00985       unsigned int level;
00986 
00987       ast_cli(a->fd, FORMATL, chan->filename, chan->type == LOGTYPE_CONSOLE ? "Console" : (chan->type == LOGTYPE_SYSLOG ? "Syslog" : "File"),
00988          chan->disabled ? "Disabled" : "Enabled");
00989       ast_cli(a->fd, " - ");
00990       for (level = 0; level < ARRAY_LEN(levels); level++) {
00991          if ((chan->logmask & (1 << level)) && levels[level]) {
00992             ast_cli(a->fd, "%s ", levels[level]);
00993          }
00994       }
00995       ast_cli(a->fd, "\n");
00996    }
00997    AST_RWLIST_UNLOCK(&logchannels);
00998    ast_cli(a->fd, "\n");
00999 
01000    return CLI_SUCCESS;
01001 }

int init_logger ( void   ) 

Provided by logger.c

Definition at line 1410 of file logger.c.

References ARRAY_LEN, ast_cli_register_multiple(), ast_cond_destroy, ast_cond_init, ast_config_AST_LOG_DIR, ast_log, ast_mkdir(), ast_mutex_destroy, ast_mutex_init, ast_pthread_create, ast_verb_update(), cli_logger, handle_SIGXFSZ, init_logger_chain(), LOG_ERROR, logcond, logger_thread(), logthread, and NULL.

Referenced by main().

01411 {
01412    int res;
01413    /* auto rotate if sig SIGXFSZ comes a-knockin */
01414    sigaction(SIGXFSZ, &handle_SIGXFSZ, NULL);
01415 
01416    /* Re-initialize the logmsgs mutex.  The recursive mutex can be accessed prior
01417     * to Asterisk being forked into the background, which can cause the thread
01418     * ID tracked by the underlying pthread mutex to be different than the ID of
01419     * the thread that unlocks the mutex.  Since init_logger is called after the
01420     * fork, it is safe to initialize the mutex here for future accesses.
01421     */
01422    ast_mutex_destroy(&logmsgs.lock);
01423    ast_mutex_init(&logmsgs.lock);
01424    ast_cond_init(&logcond, NULL);
01425 
01426    /* start logger thread */
01427    if (ast_pthread_create(&logthread, NULL, logger_thread, NULL) < 0) {
01428       ast_cond_destroy(&logcond);
01429       return -1;
01430    }
01431 
01432    /* register the logger cli commands */
01433    ast_cli_register_multiple(cli_logger, ARRAY_LEN(cli_logger));
01434 
01435    ast_mkdir(ast_config_AST_LOG_DIR, 0777);
01436 
01437    /* create log channels */
01438    res = init_logger_chain(0 /* locked */, NULL);
01439    ast_verb_update();
01440    logger_initialized = 1;
01441    if (res) {
01442       ast_log(LOG_ERROR, "Errors detected in logger.conf.  Default console logging is being used.\n");
01443    }
01444 
01445    return 0;
01446 }

static int init_logger_chain ( int  locked,
const char *  altconf 
) [static]

Definition at line 370 of file logger.c.

References __LOG_ERROR, __LOG_NOTICE, __LOG_WARNING, ast_calloc, ast_config_destroy(), ast_config_load2(), ast_console_puts_mutable(), ast_copy_string(), ast_free, AST_RWLIST_INSERT_HEAD, AST_RWLIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_true(), ast_variable_browse(), ast_variable_retrieve(), CONFIG_STATUS_FILEINVALID, errno, ast_variable::lineno, logchannel::list, logfiles, logchannel::logmask, LOGTYPE_CONSOLE, make_logchannel(), ast_variable::name, ast_variable::next, NONE, NULL, qlog, ROTATE, S_OR, SEQUENTIAL, TIMESTAMP, logchannel::type, ast_variable::value, and var.

Referenced by init_logger(), and reload_logger().

00371 {
00372    struct logchannel *chan;
00373    struct ast_config *cfg;
00374    struct ast_variable *var;
00375    const char *s;
00376    struct ast_flags config_flags = { 0 };
00377 
00378    display_callids = 1;
00379 
00380    if (!(cfg = ast_config_load2(S_OR(altconf, "logger.conf"), "logger", config_flags)) || cfg == CONFIG_STATUS_FILEINVALID) {
00381       cfg = NULL;
00382    }
00383 
00384    /* delete our list of log channels */
00385    if (!locked) {
00386       AST_RWLIST_WRLOCK(&logchannels);
00387    }
00388    while ((chan = AST_RWLIST_REMOVE_HEAD(&logchannels, list))) {
00389       ast_free(chan);
00390    }
00391    global_logmask = 0;
00392    if (!locked) {
00393       AST_RWLIST_UNLOCK(&logchannels);
00394    }
00395 
00396    errno = 0;
00397    /* close syslog */
00398    closelog();
00399 
00400    /* If no config file, we're fine, set default options. */
00401    if (!cfg) {
00402       if (!(chan = ast_calloc(1, sizeof(*chan)))) {
00403          fprintf(stderr, "Failed to initialize default logging\n");
00404          return -1;
00405       }
00406       chan->type = LOGTYPE_CONSOLE;
00407       chan->logmask = __LOG_WARNING | __LOG_NOTICE | __LOG_ERROR;
00408 
00409       if (!locked) {
00410          AST_RWLIST_WRLOCK(&logchannels);
00411       }
00412       AST_RWLIST_INSERT_HEAD(&logchannels, chan, list);
00413       global_logmask |= chan->logmask;
00414       if (!locked) {
00415          AST_RWLIST_UNLOCK(&logchannels);
00416       }
00417 
00418       return -1;
00419    }
00420 
00421    if ((s = ast_variable_retrieve(cfg, "general", "appendhostname"))) {
00422       if (ast_true(s)) {
00423          if (gethostname(hostname, sizeof(hostname) - 1)) {
00424             ast_copy_string(hostname, "unknown", sizeof(hostname));
00425             fprintf(stderr, "What box has no hostname???\n");
00426          }
00427       } else
00428          hostname[0] = '\0';
00429    } else
00430       hostname[0] = '\0';
00431    if ((s = ast_variable_retrieve(cfg, "general", "display_callids"))) {
00432       display_callids = ast_true(s);
00433    }
00434    if ((s = ast_variable_retrieve(cfg, "general", "dateformat")))
00435       ast_copy_string(dateformat, s, sizeof(dateformat));
00436    else
00437       ast_copy_string(dateformat, "%b %e %T", sizeof(dateformat));
00438    if ((s = ast_variable_retrieve(cfg, "general", "queue_log"))) {
00439       logfiles.queue_log = ast_true(s);
00440    }
00441    if ((s = ast_variable_retrieve(cfg, "general", "queue_log_to_file"))) {
00442       logfiles.queue_log_to_file = ast_true(s);
00443    }
00444    if ((s = ast_variable_retrieve(cfg, "general", "queue_log_name"))) {
00445       ast_copy_string(queue_log_name, s, sizeof(queue_log_name));
00446    }
00447    if ((s = ast_variable_retrieve(cfg, "general", "queue_log_realtime_use_gmt"))) {
00448       logfiles.queue_log_realtime_use_gmt = ast_true(s);
00449    }
00450    if ((s = ast_variable_retrieve(cfg, "general", "exec_after_rotate"))) {
00451       ast_copy_string(exec_after_rotate, s, sizeof(exec_after_rotate));
00452    }
00453    if ((s = ast_variable_retrieve(cfg, "general", "rotatestrategy"))) {
00454       if (strcasecmp(s, "timestamp") == 0) {
00455          rotatestrategy = TIMESTAMP;
00456       } else if (strcasecmp(s, "rotate") == 0) {
00457          rotatestrategy = ROTATE;
00458       } else if (strcasecmp(s, "sequential") == 0) {
00459          rotatestrategy = SEQUENTIAL;
00460       } else if (strcasecmp(s, "none") == 0) {
00461          rotatestrategy = NONE;
00462       } else {
00463          fprintf(stderr, "Unknown rotatestrategy: %s\n", s);
00464       }
00465    } else {
00466       if ((s = ast_variable_retrieve(cfg, "general", "rotatetimestamp"))) {
00467          rotatestrategy = ast_true(s) ? TIMESTAMP : SEQUENTIAL;
00468          fprintf(stderr, "rotatetimestamp option has been deprecated.  Please use rotatestrategy instead.\n");
00469       }
00470    }
00471 
00472    if (!locked) {
00473       AST_RWLIST_WRLOCK(&logchannels);
00474    }
00475    var = ast_variable_browse(cfg, "logfiles");
00476    for (; var; var = var->next) {
00477       if (!(chan = make_logchannel(var->name, var->value, var->lineno, 0))) {
00478          /* Print error message directly to the consoles since the lock is held
00479           * and we don't want to unlock with the list partially built */
00480          ast_console_puts_mutable("ERROR: Unable to create log channel '", __LOG_ERROR);
00481          ast_console_puts_mutable(var->name, __LOG_ERROR);
00482          ast_console_puts_mutable("'\n", __LOG_ERROR);
00483          continue;
00484       }
00485       AST_RWLIST_INSERT_HEAD(&logchannels, chan, list);
00486       global_logmask |= chan->logmask;
00487    }
00488 
00489    if (qlog) {
00490       fclose(qlog);
00491       qlog = NULL;
00492    }
00493 
00494    if (!locked) {
00495       AST_RWLIST_UNLOCK(&logchannels);
00496    }
00497 
00498    ast_config_destroy(cfg);
00499 
00500    return 0;
00501 }

static void logger_print_normal ( struct logmsg logmsg  )  [static]

Print a normal log message to the channels.

Definition at line 1195 of file logger.c.

References __LOG_VERBOSE, ast_console_puts_mutable(), ast_free, ast_log_vsyslog(), AST_RWLIST_EMPTY, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_string_field_set, ast_strlen_zero, ast_verb, buf, logmsg::callid, COLOR_BRWHITE, COLORIZE, COLORIZE_FMT, colors, logmsg::date, logchannel::disabled, errno, EVENT_FLAG_SYSTEM, logmsg::file, logchannel::filename, logchannel::fileptr, logmsg::function, logmsg::level, logmsg::level_name, logmsg::line, logchannel::list, logger_strip_verbose_magic(), logchannel::logmask, LOGTYPE_CONSOLE, LOGTYPE_FILE, LOGTYPE_SYSLOG, logmsg::lwp, manager_event, logmsg::message, NULL, option_verbose, reload_logger(), term_strip(), logchannel::type, VERBOSE_MAGIC2LEVEL, verb::verboser, and logchannel::verbosity.

Referenced by ast_log_full(), and logger_thread().

01196 {
01197    struct logchannel *chan = NULL;
01198    char buf[BUFSIZ];
01199    struct verb *v = NULL;
01200    char *tmpmsg;
01201    int level = 0;
01202 
01203    if (logmsg->level == __LOG_VERBOSE) {
01204 
01205       /* Iterate through the list of verbosers and pass them the log message string */
01206       AST_RWLIST_RDLOCK(&verbosers);
01207       AST_RWLIST_TRAVERSE(&verbosers, v, list)
01208          v->verboser(logmsg->message);
01209       AST_RWLIST_UNLOCK(&verbosers);
01210 
01211       level = VERBOSE_MAGIC2LEVEL(logmsg->message);
01212 
01213       tmpmsg = logger_strip_verbose_magic(logmsg->message, level);
01214       if (tmpmsg) {
01215          ast_string_field_set(logmsg, message, tmpmsg);
01216          ast_free(tmpmsg);
01217       }
01218    }
01219 
01220    AST_RWLIST_RDLOCK(&logchannels);
01221 
01222    if (!AST_RWLIST_EMPTY(&logchannels)) {
01223       AST_RWLIST_TRAVERSE(&logchannels, chan, list) {
01224          char call_identifier_str[13];
01225 
01226          if (logmsg->callid) {
01227             snprintf(call_identifier_str, sizeof(call_identifier_str), "[C-%08x]", logmsg->callid);
01228          } else {
01229             call_identifier_str[0] = '\0';
01230          }
01231 
01232 
01233          /* If the channel is disabled, then move on to the next one */
01234          if (chan->disabled) {
01235             continue;
01236          }
01237          if (logmsg->level == __LOG_VERBOSE
01238             && (((chan->verbosity < 0) ? option_verbose : chan->verbosity)) < level) {
01239             continue;
01240          }
01241 
01242          /* Check syslog channels */
01243          if (chan->type == LOGTYPE_SYSLOG && (chan->logmask & (1 << logmsg->level))) {
01244             ast_log_vsyslog(logmsg);
01245          /* Console channels */
01246          } else if (chan->type == LOGTYPE_CONSOLE && (chan->logmask & (1 << logmsg->level))) {
01247             char linestr[128];
01248 
01249             /* If the level is verbose, then skip it */
01250             if (logmsg->level == __LOG_VERBOSE)
01251                continue;
01252 
01253             /* Turn the numerical line number into a string */
01254             snprintf(linestr, sizeof(linestr), "%d", logmsg->line);
01255             /* Build string to print out */
01256             snprintf(buf, sizeof(buf), "[%s] " COLORIZE_FMT "[%d]%s: " COLORIZE_FMT ":" COLORIZE_FMT " " COLORIZE_FMT ": %s",
01257                 logmsg->date,
01258                 COLORIZE(colors[logmsg->level], 0, logmsg->level_name),
01259                 logmsg->lwp,
01260                 call_identifier_str,
01261                 COLORIZE(COLOR_BRWHITE, 0, logmsg->file),
01262                 COLORIZE(COLOR_BRWHITE, 0, linestr),
01263                 COLORIZE(COLOR_BRWHITE, 0, logmsg->function),
01264                 logmsg->message);
01265             /* Print out */
01266             ast_console_puts_mutable(buf, logmsg->level);
01267          /* File channels */
01268          } else if (chan->type == LOGTYPE_FILE && (chan->logmask & (1 << logmsg->level))) {
01269             int res = 0;
01270 
01271             /* If no file pointer exists, skip it */
01272             if (!chan->fileptr) {
01273                continue;
01274             }
01275 
01276             /* Print out to the file */
01277             res = fprintf(chan->fileptr, "[%s] %s[%d]%s %s: %s",
01278                      logmsg->date, logmsg->level_name, logmsg->lwp, call_identifier_str,
01279                      logmsg->file, term_strip(buf, logmsg->message, BUFSIZ));
01280             if (res <= 0 && !ast_strlen_zero(logmsg->message)) {
01281                fprintf(stderr, "**** Asterisk Logging Error: ***********\n");
01282                if (errno == ENOMEM || errno == ENOSPC)
01283                   fprintf(stderr, "Asterisk logging error: Out of disk space, can't log to log file %s\n", chan->filename);
01284                else
01285                   fprintf(stderr, "Logger Warning: Unable to write to log file '%s': %s (disabled)\n", chan->filename, strerror(errno));
01286                /*** DOCUMENTATION
01287                   <managerEventInstance>
01288                      <synopsis>Raised when a logging channel is disabled.</synopsis>
01289                      <syntax>
01290                         <parameter name="Channel">
01291                            <para>The name of the logging channel.</para>
01292                         </parameter>
01293                      </syntax>
01294                   </managerEventInstance>
01295                ***/
01296                manager_event(EVENT_FLAG_SYSTEM, "LogChannel", "Channel: %s\r\nEnabled: No\r\nReason: %d - %s\r\n", chan->filename, errno, strerror(errno));
01297                chan->disabled = 1;
01298             } else if (res > 0) {
01299                fflush(chan->fileptr);
01300             }
01301          }
01302       }
01303    } else if (logmsg->level != __LOG_VERBOSE) {
01304       fputs(logmsg->message, stdout);
01305    }
01306 
01307    AST_RWLIST_UNLOCK(&logchannels);
01308 
01309    /* If we need to reload because of the file size, then do so */
01310    if (filesize_reload_needed) {
01311       reload_logger(-1, NULL);
01312       ast_verb(1, "Rotated Logs Per SIGXFSZ (Exceeded file size limit)\n");
01313    }
01314 
01315    return;
01316 }

static void logger_queue_init ( void   )  [static]

Definition at line 1362 of file logger.c.

References ast_config_AST_LOG_DIR, ast_log, ast_unload_realtime(), errno, LOG_ERROR, logfiles, logger_queue_rt_start(), and qlog.

Referenced by logger_queue_start().

01363 {
01364    ast_unload_realtime("queue_log");
01365    if (logfiles.queue_log) {
01366       char qfname[PATH_MAX];
01367 
01368       if (logger_queue_rt_start()) {
01369          return;
01370       }
01371 
01372       /* Open the log file. */
01373       snprintf(qfname, sizeof(qfname), "%s/%s", ast_config_AST_LOG_DIR,
01374          queue_log_name);
01375       if (qlog) {
01376          /* Just in case it was already open. */
01377          fclose(qlog);
01378       }
01379       qlog = fopen(qfname, "a");
01380       if (!qlog) {
01381          ast_log(LOG_ERROR, "Unable to create queue log: %s\n", strerror(errno));
01382       }
01383    }
01384 }

static int logger_queue_restart ( int  queue_rotate  )  [static]

Definition at line 766 of file logger.c.

References ast_config_AST_LOG_DIR, ast_log, errno, LOG_ERROR, logger_queue_rt_start(), NULL, qlog, and rotate_file().

Referenced by reload_logger().

00767 {
00768    int res = 0;
00769    char qfname[PATH_MAX];
00770 
00771    if (logger_queue_rt_start()) {
00772       return res;
00773    }
00774 
00775    snprintf(qfname, sizeof(qfname), "%s/%s", ast_config_AST_LOG_DIR, queue_log_name);
00776    if (qlog) {
00777       /* Just in case it was still open. */
00778       fclose(qlog);
00779       qlog = NULL;
00780    }
00781    if (queue_rotate) {
00782       rotate_file(qfname);
00783    }
00784 
00785    /* Open the log file. */
00786    qlog = fopen(qfname, "a");
00787    if (!qlog) {
00788       ast_log(LOG_ERROR, "Unable to create queue log: %s\n", strerror(errno));
00789       res = -1;
00790    }
00791    return res;
00792 }

static int logger_queue_rt_start ( void   )  [static]

Definition at line 731 of file logger.c.

References ast_check_realtime(), ast_realtime_require_field(), logfiles, RQ_CHAR, RQ_DATETIME, and SENTINEL.

Referenced by logger_queue_init(), and logger_queue_restart().

00732 {
00733    if (ast_check_realtime("queue_log")) {
00734       if (!ast_realtime_require_field("queue_log",
00735          "time", RQ_DATETIME, 26,
00736          "data1", RQ_CHAR, 20,
00737          "data2", RQ_CHAR, 20,
00738          "data3", RQ_CHAR, 20,
00739          "data4", RQ_CHAR, 20,
00740          "data5", RQ_CHAR, 20,
00741          SENTINEL)) {
00742          logfiles.queue_adaptive_realtime = 1;
00743       } else {
00744          logfiles.queue_adaptive_realtime = 0;
00745       }
00746 
00747       if (!logfiles.queue_log_to_file) {
00748          /* Don't open the log file. */
00749          return 1;
00750       }
00751    }
00752    return 0;
00753 }

void logger_queue_start ( void   ) 

Start the ast_queue_log() logger.

Note:
Called when the system is fully booted after startup so preloaded realtime modules can get up.
Returns:
Nothing

Definition at line 1394 of file logger.c.

References ast_assert, ast_queue_log(), AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and logger_queue_init().

Referenced by ast_queue_log(), and main().

01395 {
01396    /* Must not be called before the logger is initialized. */
01397    ast_assert(logger_initialized);
01398 
01399    AST_RWLIST_WRLOCK(&logchannels);
01400    if (!queuelog_init) {
01401       logger_queue_init();
01402       queuelog_init = 1;
01403       AST_RWLIST_UNLOCK(&logchannels);
01404       ast_queue_log("NONE", "NONE", "NONE", "QUEUESTART", "%s", "");
01405    } else {
01406       AST_RWLIST_UNLOCK(&logchannels);
01407    }
01408 }

int logger_reload ( void   ) 

Reload the logger module without rotating log files (also used from loader.c during a full Asterisk reload).

Reload logger without rotating log files.

Definition at line 871 of file logger.c.

References NULL, reload_logger(), RESULT_FAILURE, and RESULT_SUCCESS.

00872 {
00873    if (reload_logger(0, NULL)) {
00874       return RESULT_FAILURE;
00875    }
00876    return RESULT_SUCCESS;
00877 }

static char* logger_strip_verbose_magic ( const char *  message,
int  level 
) [static]

Definition at line 1166 of file logger.c.

References ast_malloc, end, len(), and NULL.

Referenced by logger_print_normal().

01167 {
01168    const char *begin, *end;
01169    char *stripped_message, *dst;
01170    char magic = -(level + 1);
01171 
01172    if (!(stripped_message = ast_malloc(strlen(message) + 1))) {
01173       return NULL;
01174    }
01175 
01176    begin = message;
01177    dst = stripped_message;
01178    do {
01179       end = strchr(begin, magic);
01180       if (end) {
01181          size_t len = end - begin;
01182          memcpy(dst, begin, len);
01183          begin = end + 1;
01184          dst += len;
01185       } else {
01186          strcpy(dst, begin); /* safe */
01187          break;
01188       }
01189    } while (1);
01190 
01191    return stripped_message;
01192 }

static void* logger_thread ( void *  data  )  [static]

Actual logging thread.

Definition at line 1319 of file logger.c.

References ast_cond_wait, AST_LIST_EMPTY, AST_LIST_FIRST, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_LOCK, AST_LIST_NEXT, AST_LIST_UNLOCK, close_logger_thread, logchannel::list, logcond, logger_print_normal(), logmsg_free(), logchannel::next, and NULL.

Referenced by init_logger().

01320 {
01321    struct logmsg *next = NULL, *msg = NULL;
01322 
01323    for (;;) {
01324       /* We lock the message list, and see if any message exists... if not we wait on the condition to be signalled */
01325       AST_LIST_LOCK(&logmsgs);
01326       if (AST_LIST_EMPTY(&logmsgs)) {
01327          if (close_logger_thread) {
01328             AST_LIST_UNLOCK(&logmsgs);
01329             break;
01330          } else {
01331             ast_cond_wait(&logcond, &logmsgs.lock);
01332          }
01333       }
01334       next = AST_LIST_FIRST(&logmsgs);
01335       AST_LIST_HEAD_INIT_NOLOCK(&logmsgs);
01336       AST_LIST_UNLOCK(&logmsgs);
01337 
01338       /* Otherwise go through and process each message in the order added */
01339       while ((msg = next)) {
01340          /* Get the next entry now so that we can free our current structure later */
01341          next = AST_LIST_NEXT(msg, list);
01342 
01343          /* Depending on the type, send it to the proper function */
01344          logger_print_normal(msg);
01345 
01346          /* Free the data since we are done */
01347          logmsg_free(msg);
01348       }
01349    }
01350 
01351    return NULL;
01352 }

static void logmsg_free ( struct logmsg msg  )  [static]

Definition at line 161 of file logger.c.

References ast_free.

Referenced by ast_log_full(), and logger_thread().

00162 {
00163    ast_free(msg);
00164 }

static void make_components ( struct logchannel chan  )  [static]

Definition at line 237 of file logger.c.

References __LOG_VERBOSE, ARRAY_LEN, ast_strdupa, ast_strip(), ast_strlen_zero, logchannel::components, levels, logchannel::logmask, LOGTYPE_CONSOLE, strsep(), logchannel::type, and logchannel::verbosity.

Referenced by make_logchannel(), and update_logchannels().

00238 {
00239    char *w;
00240    unsigned int logmask = 0;
00241    char *stringp = ast_strdupa(chan->components);
00242    unsigned int x;
00243    unsigned int verb_level;
00244 
00245    /* Default to using option_verbose as the verbosity level of the logging channel.  */
00246    verb_level = -1;
00247 
00248    while ((w = strsep(&stringp, ","))) {
00249       w = ast_strip(w);
00250       if (ast_strlen_zero(w)) {
00251          continue;
00252       }
00253       if (!strcmp(w, "*")) {
00254          logmask = 0xFFFFFFFF;
00255       } else if (!strncasecmp(w, "verbose(", 8)) {
00256          if (levels[__LOG_VERBOSE] && sscanf(w + 8, "%30u)", &verb_level) == 1) {
00257             logmask |= (1 << __LOG_VERBOSE);
00258          }
00259       } else {
00260          for (x = 0; x < ARRAY_LEN(levels); ++x) {
00261             if (levels[x] && !strcasecmp(w, levels[x])) {
00262                logmask |= (1 << x);
00263                break;
00264             }
00265          }
00266       }
00267    }
00268    if (chan->type == LOGTYPE_CONSOLE) {
00269       /*
00270        * Force to use the root console verbose level so if the
00271        * user specified any verbose level then it does not interfere
00272        * with calculating the ast_verb_sys_level value.
00273        */
00274       chan->verbosity = -1;
00275    } else {
00276       chan->verbosity = verb_level;
00277    }
00278    chan->logmask = logmask;
00279 }

static struct logchannel* make_logchannel ( const char *  channel,
const char *  components,
int  lineno,
int  dynamic 
) [static, read]

Definition at line 281 of file logger.c.

References __LOG_ERROR, ast_build_date, ast_build_hostname, ast_build_machine, ast_build_os, ast_build_user, ast_calloc, ast_config_AST_LOG_DIR, ast_console_puts_mutable(), ast_copy_string(), ast_free, ast_get_version(), ast_localtime(), ast_strftime(), ast_strlen_zero, ast_syslog_facility(), ast_tvnow(), logchannel::components, logchannel::dynamic, errno, logchannel::facility, logchannel::filename, logchannel::fileptr, logchannel::lineno, LOGTYPE_CONSOLE, LOGTYPE_FILE, LOGTYPE_SYSLOG, make_components(), NULL, and logchannel::type.

Referenced by handle_logger_add_channel(), and init_logger_chain().

00282 {
00283    struct logchannel *chan;
00284    char *facility;
00285    struct ast_tm tm;
00286    struct timeval now = ast_tvnow();
00287    char datestring[256];
00288 
00289    if (ast_strlen_zero(channel) || !(chan = ast_calloc(1, sizeof(*chan) + strlen(components) + 1)))
00290       return NULL;
00291 
00292    strcpy(chan->components, components);
00293    chan->lineno = lineno;
00294    chan->dynamic = dynamic;
00295 
00296    if (!strcasecmp(channel, "console")) {
00297       chan->type = LOGTYPE_CONSOLE;
00298    } else if (!strncasecmp(channel, "syslog", 6)) {
00299       /*
00300       * syntax is:
00301       *  syslog.facility => level,level,level
00302       */
00303       facility = strchr(channel, '.');
00304       if (!facility++ || !facility) {
00305          facility = "local0";
00306       }
00307 
00308       chan->facility = ast_syslog_facility(facility);
00309 
00310       if (chan->facility < 0) {
00311          fprintf(stderr, "Logger Warning: bad syslog facility in logger.conf\n");
00312          ast_free(chan);
00313          return NULL;
00314       }
00315 
00316       chan->type = LOGTYPE_SYSLOG;
00317       ast_copy_string(chan->filename, channel, sizeof(chan->filename));
00318       openlog("asterisk", LOG_PID, chan->facility);
00319    } else {
00320       const char *log_dir_prefix = "";
00321       const char *log_dir_separator = "";
00322 
00323       if (channel[0] != '/') {
00324          log_dir_prefix = ast_config_AST_LOG_DIR;
00325          log_dir_separator = "/";
00326       }
00327 
00328       if (!ast_strlen_zero(hostname)) {
00329          snprintf(chan->filename, sizeof(chan->filename), "%s%s%s.%s",
00330             log_dir_prefix, log_dir_separator, channel, hostname);
00331       } else {
00332          snprintf(chan->filename, sizeof(chan->filename), "%s%s%s",
00333             log_dir_prefix, log_dir_separator, channel);
00334       }
00335 
00336       if (!(chan->fileptr = fopen(chan->filename, "a"))) {
00337          /* Can't do real logging here since we're called with a lock
00338           * so log to any attached consoles */
00339          ast_console_puts_mutable("ERROR: Unable to open log file '", __LOG_ERROR);
00340          ast_console_puts_mutable(chan->filename, __LOG_ERROR);
00341          ast_console_puts_mutable("': ", __LOG_ERROR);
00342          ast_console_puts_mutable(strerror(errno), __LOG_ERROR);
00343          ast_console_puts_mutable("'\n", __LOG_ERROR);
00344          ast_free(chan);
00345          return NULL;
00346       } else {
00347          /* Create our date/time */
00348          ast_localtime(&now, &tm, NULL);
00349          ast_strftime(datestring, sizeof(datestring), dateformat, &tm);
00350 
00351          fprintf(chan->fileptr, "[%s] Asterisk %s built by %s @ %s on a %s running %s on %s\n",
00352             datestring, ast_get_version(), ast_build_user, ast_build_hostname,
00353             ast_build_machine, ast_build_os, ast_build_date);
00354          fflush(chan->fileptr);
00355       }
00356       chan->type = LOGTYPE_FILE;
00357    }
00358    make_components(chan);
00359 
00360    return chan;
00361 }

static int reload_logger ( int  rotate,
const char *  altconf 
) [static]

Definition at line 794 of file logger.c.

References ast_config_AST_LOG_DIR, ast_mkdir(), ast_queue_log(), AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_unload_realtime(), ast_verb, ast_verb_update(), logchannel::disabled, EVENT_FLAG_SYSTEM, f, logchannel::filename, logchannel::fileptr, init_logger_chain(), logchannel::list, logfiles, logger_queue_restart(), manager_event, NONE, NULL, qlog, and rotate_file().

Referenced by ast_logger_rotate(), handle_logger_reload(), handle_logger_rotate(), logger_print_normal(), and logger_reload().

00795 {
00796    int queue_rotate = rotate;
00797    struct logchannel *f;
00798    int res = 0;
00799 
00800    AST_RWLIST_WRLOCK(&logchannels);
00801 
00802    if (qlog) {
00803       if (rotate < 0) {
00804          /* Check filesize - this one typically doesn't need an auto-rotate */
00805          if (ftello(qlog) > 0x40000000) { /* Arbitrarily, 1 GB */
00806             fclose(qlog);
00807             qlog = NULL;
00808          } else {
00809             queue_rotate = 0;
00810          }
00811       } else {
00812          fclose(qlog);
00813          qlog = NULL;
00814       }
00815    } else {
00816       queue_rotate = 0;
00817    }
00818 
00819    ast_mkdir(ast_config_AST_LOG_DIR, 0777);
00820 
00821    AST_RWLIST_TRAVERSE(&logchannels, f, list) {
00822       if (f->disabled) {
00823          f->disabled = 0;  /* Re-enable logging at reload */
00824          /*** DOCUMENTATION
00825             <managerEventInstance>
00826                <synopsis>Raised when a logging channel is re-enabled after a reload operation.</synopsis>
00827                <syntax>
00828                   <parameter name="Channel">
00829                      <para>The name of the logging channel.</para>
00830                   </parameter>
00831                </syntax>
00832             </managerEventInstance>
00833          ***/
00834          manager_event(EVENT_FLAG_SYSTEM, "LogChannel", "Channel: %s\r\nEnabled: Yes\r\n", f->filename);
00835       }
00836       if (f->fileptr && (f->fileptr != stdout) && (f->fileptr != stderr)) {
00837          int rotate_this = 0;
00838          if (rotatestrategy != NONE && ftello(f->fileptr) > 0x40000000) { /* Arbitrarily, 1 GB */
00839             /* Be more proactive about rotating massive log files */
00840             rotate_this = 1;
00841          }
00842          fclose(f->fileptr);  /* Close file */
00843          f->fileptr = NULL;
00844          if (rotate || rotate_this) {
00845             rotate_file(f->filename);
00846          }
00847       }
00848    }
00849 
00850    filesize_reload_needed = 0;
00851 
00852    init_logger_chain(1 /* locked */, altconf);
00853 
00854    ast_unload_realtime("queue_log");
00855    if (logfiles.queue_log) {
00856       res = logger_queue_restart(queue_rotate);
00857       AST_RWLIST_UNLOCK(&logchannels);
00858       ast_verb_update();
00859       ast_queue_log("NONE", "NONE", "NONE", "CONFIGRELOAD", "%s", "");
00860       ast_verb(1, "Asterisk Queue Logger restarted\n");
00861    } else {
00862       AST_RWLIST_UNLOCK(&logchannels);
00863       ast_verb_update();
00864    }
00865 
00866    return res;
00867 }

static int rotate_file ( const char *  filename  )  [static]

Definition at line 627 of file logger.c.

References ARRAY_LEN, ast_channel_unref, ast_dummy_channel_alloc(), ast_log, ast_safe_system(), ast_strlen_zero, buf, c, LOG_WARNING, NONE, NULL, pbx_builtin_setvar_helper(), pbx_substitute_variables_helper(), ROTATE, SEQUENTIAL, and TIMESTAMP.

Referenced by logger_queue_restart(), and reload_logger().

00628 {
00629    char old[PATH_MAX];
00630    char new[PATH_MAX];
00631    int x, y, which, found, res = 0, fd;
00632    char *suffixes[4] = { "", ".gz", ".bz2", ".Z" };
00633 
00634    switch (rotatestrategy) {
00635    case NONE:
00636       /* No rotation */
00637       break;
00638    case SEQUENTIAL:
00639       for (x = 0; ; x++) {
00640          snprintf(new, sizeof(new), "%s.%d", filename, x);
00641          fd = open(new, O_RDONLY);
00642          if (fd > -1)
00643             close(fd);
00644          else
00645             break;
00646       }
00647       if (rename(filename, new)) {
00648          fprintf(stderr, "Unable to rename file '%s' to '%s'\n", filename, new);
00649          res = -1;
00650       } else {
00651          filename = new;
00652       }
00653       break;
00654    case TIMESTAMP:
00655       snprintf(new, sizeof(new), "%s.%ld", filename, (long)time(NULL));
00656       if (rename(filename, new)) {
00657          fprintf(stderr, "Unable to rename file '%s' to '%s'\n", filename, new);
00658          res = -1;
00659       } else {
00660          filename = new;
00661       }
00662       break;
00663    case ROTATE:
00664       /* Find the next empty slot, including a possible suffix */
00665       for (x = 0; ; x++) {
00666          found = 0;
00667          for (which = 0; which < ARRAY_LEN(suffixes); which++) {
00668             snprintf(new, sizeof(new), "%s.%d%s", filename, x, suffixes[which]);
00669             fd = open(new, O_RDONLY);
00670             if (fd > -1) {
00671                close(fd);
00672                found = 1;
00673                break;
00674             }
00675          }
00676          if (!found) {
00677             break;
00678          }
00679       }
00680 
00681       /* Found an empty slot */
00682       for (y = x; y > 0; y--) {
00683          for (which = 0; which < ARRAY_LEN(suffixes); which++) {
00684             snprintf(old, sizeof(old), "%s.%d%s", filename, y - 1, suffixes[which]);
00685             fd = open(old, O_RDONLY);
00686             if (fd > -1) {
00687                /* Found the right suffix */
00688                close(fd);
00689                snprintf(new, sizeof(new), "%s.%d%s", filename, y, suffixes[which]);
00690                if (rename(old, new)) {
00691                   fprintf(stderr, "Unable to rename file '%s' to '%s'\n", old, new);
00692                   res = -1;
00693                }
00694                break;
00695             }
00696          }
00697       }
00698 
00699       /* Finally, rename the current file */
00700       snprintf(new, sizeof(new), "%s.0", filename);
00701       if (rename(filename, new)) {
00702          fprintf(stderr, "Unable to rename file '%s' to '%s'\n", filename, new);
00703          res = -1;
00704       } else {
00705          filename = new;
00706       }
00707    }
00708 
00709    if (!ast_strlen_zero(exec_after_rotate)) {
00710       struct ast_channel *c = ast_dummy_channel_alloc();
00711       char buf[512];
00712 
00713       pbx_builtin_setvar_helper(c, "filename", filename);
00714       pbx_substitute_variables_helper(c, exec_after_rotate, buf, sizeof(buf));
00715       if (c) {
00716          c = ast_channel_unref(c);
00717       }
00718       if (ast_safe_system(buf) == -1) {
00719          ast_log(LOG_WARNING, "error executing '%s'\n", buf);
00720       }
00721    }
00722    return res;
00723 }

static void update_logchannels ( void   )  [static]

Definition at line 2048 of file logger.c.

References AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, logchannel::list, logchannel::logmask, and make_components().

Referenced by ast_logger_register_level(), and ast_logger_unregister_level().

02049 {
02050    struct logchannel *cur;
02051 
02052    AST_RWLIST_WRLOCK(&logchannels);
02053 
02054    global_logmask = 0;
02055 
02056    AST_RWLIST_TRAVERSE(&logchannels, cur, list) {
02057       make_components(cur);
02058       global_logmask |= cur->logmask;
02059    }
02060 
02061    AST_RWLIST_UNLOCK(&logchannels);
02062 }

static void verb_console_free ( void *  v_console  )  [static]

Definition at line 1939 of file logger.c.

References ast_free, and verb_console_unregister().

01940 {
01941    struct verb_console *console = v_console;
01942 
01943    verb_console_unregister(console);
01944    ast_free(console);
01945 }

static void verb_console_unregister ( struct verb_console console  )  [static]

Definition at line 1929 of file logger.c.

References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and ast_verb_update().

Referenced by ast_verb_console_unregister(), and verb_console_free().

01930 {
01931    AST_RWLIST_WRLOCK(&verb_consoles);
01932    console = AST_RWLIST_REMOVE(&verb_consoles, console, node);
01933    AST_RWLIST_UNLOCK(&verb_consoles);
01934    if (console) {
01935       ast_verb_update();
01936    }
01937 }


Variable Documentation

struct ast_cli_entry cli_logger[] [static]

Definition at line 1121 of file logger.c.

Referenced by close_logger(), and init_logger().

int close_logger_thread = 0 [static]

Definition at line 169 of file logger.c.

Referenced by ast_log_full(), close_logger(), and logger_thread().

const int colors[NUMLOGLEVELS] [static]

Colors used in the console for logging.

Definition at line 195 of file logger.c.

Referenced by logger_print_normal().

char dateformat[256] = "%b %e %T" [static]

Definition at line 76 of file logger.c.

Referenced by build_device().

int display_callids [static]

Definition at line 86 of file logger.c.

char exec_after_rotate[256] = "" [static]

Definition at line 79 of file logger.c.

int filesize_reload_needed [static]

Definition at line 81 of file logger.c.

unsigned int global_logmask = 0xFFFF [static]

Definition at line 82 of file logger.c.

struct sigaction handle_SIGXFSZ [static]

Initial value:

 {
   .sa_handler = _handle_SIGXFSZ,
   .sa_flags = SA_RESTART,
}

Definition at line 1136 of file logger.c.

Referenced by init_logger().

char hostname[MAXHOSTNAMELEN] [static]

Definition at line 104 of file logger.c.

char* levels[NUMLOGLEVELS] [static]

Logging channels used in the Asterisk logging system.

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.

Definition at line 184 of file logger.c.

Referenced by ast_log_full(), ast_log_vsyslog(), ast_logger_register_level(), ast_logger_unregister_level(), ast_network_puts_mutable(), handle_logger_set_level(), handle_logger_show_channels(), make_components(), and network_verboser().

struct ast_threadstorage log_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_log_buf , .custom_init = NULL , } [static]

Definition at line 234 of file logger.c.

Referenced by ast_log_full().

ast_cond_t logcond [static]

Definition at line 168 of file logger.c.

Referenced by ast_log_full(), close_logger(), init_logger(), and logger_thread().

struct { ... } logfiles [static]

int logger_initialized [static]

Definition at line 84 of file logger.c.

pthread_t logthread = AST_PTHREADT_NULL [static]

Definition at line 167 of file logger.c.

Referenced by ast_log_full(), close_logger(), and init_logger().

struct ast_threadstorage my_verb_console = { .once = PTHREAD_ONCE_INIT , .key_init = __init_my_verb_console , .custom_init = NULL , } [static]

volatile int next_unique_callid = 1 [static]

Definition at line 85 of file logger.c.

FILE* qlog [static]

Definition at line 100 of file logger.c.

unsigned int queue_log

Definition at line 98 of file logger.c.

char queue_log_name[256] = QUEUELOG [static]

Definition at line 78 of file logger.c.

Definition at line 101 of file logger.c.

unsigned int queue_log_to_file

Definition at line 99 of file logger.c.

int queuelog_init [static]

Definition at line 83 of file logger.c.

struct ast_threadstorage unique_callid = { .once = PTHREAD_ONCE_INIT , .key_init = __init_unique_callid , .custom_init = NULL , } [static]

ast_mutex_t verb_update_lock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 } [static]

ast_verb_update() reentrancy protection lock.

Definition at line 1884 of file logger.c.

struct ast_threadstorage verbose_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_verbose_buf , .custom_init = NULL , } [static]

Definition at line 230 of file logger.c.

Referenced by __ast_verbose_ap().

struct ast_threadstorage verbose_build_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_verbose_build_buf , .custom_init = NULL , } [static]

Definition at line 231 of file logger.c.

Referenced by __ast_verbose_ap().


Generated on Thu Apr 16 06:31:50 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6