logger.c File Reference

#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <asterisk/lock.h>
#include <asterisk/options.h>
#include <asterisk/channel.h>
#include <asterisk/config.h>
#include <asterisk/term.h>
#include <asterisk/cli.h>
#include <asterisk/utils.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/stat.h>
#include "asterisk.h"
#include "astconf.h"
#include <syslog.h>
#include <asterisk/logger.h>

Include dependency graph for logger.c:

Go to the source code of this file.

Data Structures

struct  msglist
struct  logchannel
struct  verb

Defines

#define SYSLOG_NAMES
#define SYSLOG_NLEVELS   6
#define MAX_MSG_QUEUE   200
#define GETTID()   getpid()

Functions

 AST_MUTEX_DEFINE_STATIC (msglist_lock)
 AST_MUTEX_DEFINE_STATIC (loglock)
 AST_MUTEX_DEFINE_STATIC (qloglock)
void ast_queue_log (const char *queuename, const char *callid, const char *agent, const char *event, const char *fmt,...)
int reload_logger (int rotate)
int init_logger (void)
void close_logger (void)
void ast_log (int level, const char *file, int line, const char *function, const char *fmt,...)
void ast_verbose (const char *fmt,...)
int ast_verbose_dmesg (void(*v)(const char *string, int opos, int replacelast, int complete))
int ast_register_verbose (void(*v)(const char *string, int opos, int replacelast, int complete))
int ast_unregister_verbose (void(*v)(const char *string, int opos, int replacelast, int complete))


Define Documentation

 
#define GETTID (  )     getpid()

Definition at line 55 of file logger.c.

#define MAX_MSG_QUEUE   200

Definition at line 49 of file logger.c.

#define SYSLOG_NAMES

Definition at line 33 of file logger.c.

#define SYSLOG_NLEVELS   6

Definition at line 45 of file logger.c.


Function Documentation

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

Definition at line 538 of file logger.c.

00539 {
00540    struct logchannel *chan;
00541    char buf[BUFSIZ];
00542    time_t t;
00543    struct tm tm;
00544    char date[256];
00545 
00546    va_list ap;
00547    
00548    if (!option_verbose && !option_debug && (level == __LOG_DEBUG)) {
00549       return;
00550    }
00551 
00552    /* begin critical section */
00553    ast_mutex_lock(&loglock);
00554 
00555    time(&t);
00556    localtime_r(&t, &tm);
00557    strftime(date, sizeof(date), dateformat, &tm);
00558 
00559    if (level == __LOG_EVENT) {
00560       va_start(ap, fmt);
00561 
00562       fprintf(eventlog, "%s asterisk[%d]: ", date, getpid());
00563       vfprintf(eventlog, fmt, ap);
00564       fflush(eventlog);
00565 
00566       va_end(ap);
00567       ast_mutex_unlock(&loglock);
00568       return;
00569    }
00570 
00571    if (logchannels) {
00572       chan = logchannels;
00573       while(chan) {
00574          if (chan->syslog && (chan->logmask & (1 << level))) {
00575             va_start(ap, fmt);
00576             ast_log_vsyslog(level, file, line, function, fmt, ap);
00577             va_end(ap);
00578          } else if ((chan->logmask & (1 << level)) && (chan->console)) {
00579             char linestr[128];
00580             char tmp1[80], tmp2[80], tmp3[80], tmp4[80];
00581 
00582             if (level != __LOG_VERBOSE) {
00583                sprintf(linestr, "%d", line);
00584                snprintf(buf, sizeof(buf), "%s %s[%ld]: %s:%s %s: ",
00585                   date,
00586                   term_color(tmp1, levels[level], colors[level], 0, sizeof(tmp1)),
00587                   (long)GETTID(),
00588                   term_color(tmp2, file, COLOR_BRWHITE, 0, sizeof(tmp2)),
00589                   term_color(tmp3, linestr, COLOR_BRWHITE, 0, sizeof(tmp3)),
00590                   term_color(tmp4, function, COLOR_BRWHITE, 0, sizeof(tmp4)));
00591           
00592                ast_console_puts(buf);
00593                va_start(ap, fmt);
00594                vsnprintf(buf, sizeof(buf), fmt, ap);
00595                va_end(ap);
00596                ast_console_puts(buf);
00597             }
00598          } else if ((chan->logmask & (1 << level)) && (chan->fileptr)) {
00599             snprintf(buf, sizeof(buf), "%s %s[%ld]: ", date,
00600                levels[level], (long)GETTID());
00601             fprintf(chan->fileptr, buf);
00602             va_start(ap, fmt);
00603             vsnprintf(buf, sizeof(buf), fmt, ap);
00604             strip_coloring(buf); 
00605             va_end(ap);
00606             fputs(buf, chan->fileptr);
00607             fflush(chan->fileptr);
00608          }
00609          chan = chan->next;
00610       }
00611    } else {
00612       /* 
00613        * we don't have the logger chain configured yet,
00614        * so just log to stdout 
00615       */
00616       if (level != __LOG_VERBOSE) {
00617          va_start(ap, fmt);
00618          vsnprintf(buf, sizeof(buf), fmt, ap);
00619          va_end(ap);
00620          fputs(buf, stdout);
00621       }
00622    }
00623 
00624    ast_mutex_unlock(&loglock);
00625    /* end critical section */
00626    if (pending_logger_reload) {
00627       reload_logger(1);
00628       ast_log(LOG_EVENT,"Rotated Logs Per SIGXFSZ\n");
00629       if (option_verbose)
00630          ast_verbose("Rotated Logs Per SIGXFSZ\n");
00631    }
00632 }

AST_MUTEX_DEFINE_STATIC ( qloglock   ) 

AST_MUTEX_DEFINE_STATIC ( loglock   ) 

AST_MUTEX_DEFINE_STATIC ( msglist_lock   ) 

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

Definition at line 262 of file logger.c.

00263 {
00264    va_list ap;
00265    ast_mutex_lock(&qloglock);
00266    if (qlog) {
00267       va_start(ap, fmt);
00268       fprintf(qlog, "%ld|%s|%s|%s|%s|", (long)time(NULL), callid, queuename, agent, event);
00269       vfprintf(qlog, fmt, ap);
00270       fprintf(qlog, "\n");
00271       va_end(ap);
00272       fflush(qlog);
00273    }
00274    ast_mutex_unlock(&qloglock);
00275 }

int ast_register_verbose ( void(*)(const char *string, int opos, int replacelast, int complete)  v  ) 

Definition at line 712 of file logger.c.

00713 {
00714    struct msglist *m;
00715    struct verb *tmp;
00716    /* XXX Should be more flexible here, taking > 1 verboser XXX */
00717    if ((tmp = malloc(sizeof (struct verb)))) {
00718       tmp->verboser = v;
00719       ast_mutex_lock(&msglist_lock);
00720       tmp->next = verboser;
00721       verboser = tmp;
00722       m = list;
00723       while(m) {
00724          /* Send all the existing entries that we have queued (i.e. they're likely to have missed) */
00725          v(m->msg, 0, 0, 1);
00726          m = m->next;
00727       }
00728       ast_mutex_unlock(&msglist_lock);
00729       return 0;
00730    }
00731    return -1;
00732 }

int ast_unregister_verbose ( void(*)(const char *string, int opos, int replacelast, int complete)  v  ) 

Definition at line 734 of file logger.c.

00735 {
00736    int res = -1;
00737    struct verb *tmp, *tmpl=NULL;
00738    ast_mutex_lock(&msglist_lock);
00739    tmp = verboser;
00740    while(tmp) {
00741       if (tmp->verboser == v) {
00742          if (tmpl)
00743             tmpl->next = tmp->next;
00744          else
00745             verboser = tmp->next;
00746          free(tmp);
00747          break;
00748       }
00749       tmpl = tmp;
00750       tmp = tmp->next;
00751    }
00752    if (tmp)
00753       res = 0;
00754    ast_mutex_unlock(&msglist_lock);
00755    return res;
00756 }

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

Definition at line 634 of file logger.c.

00635 {
00636    static char stuff[4096];
00637    static int pos = 0, opos;
00638    static int replacelast = 0, complete;
00639    struct msglist *m;
00640    struct verb *v;
00641    va_list ap;
00642    va_start(ap, fmt);
00643    ast_mutex_lock(&msglist_lock);
00644    vsnprintf(stuff + pos, sizeof(stuff) - pos, fmt, ap);
00645    opos = pos;
00646    pos = strlen(stuff);
00647    if (fmt[strlen(fmt)-1] == '\n') 
00648       complete = 1;
00649    else
00650       complete=0;
00651    if (complete) {
00652       if (msgcnt < MAX_MSG_QUEUE) {
00653          /* Allocate new structure */
00654          m = malloc(sizeof(struct msglist));
00655          msgcnt++;
00656       } else {
00657          /* Recycle the oldest entry */
00658          m = list;
00659          list = list->next;
00660          free(m->msg);
00661       }
00662       if (m) {
00663          m->msg = strdup(stuff);
00664          if (m->msg) {
00665             if (last)
00666                last->next = m;
00667             else
00668                list = m;
00669             m->next = NULL;
00670             last = m;
00671          } else {
00672             msgcnt--;
00673             ast_log(LOG_ERROR, "Out of memory\n");
00674             free(m);
00675          }
00676       }
00677    }
00678    if (verboser) {
00679       v = verboser;
00680       while(v) {
00681          v->verboser(stuff, opos, replacelast, complete);
00682          v = v->next;
00683       }
00684    } /* else
00685       fprintf(stdout, stuff + opos); */
00686 
00687    ast_log(LOG_VERBOSE, "%s", stuff);
00688 
00689    if (fmt[strlen(fmt)-1] != '\n') 
00690       replacelast = 1;
00691    else 
00692       replacelast = pos = 0;
00693    va_end(ap);
00694 
00695    ast_mutex_unlock(&msglist_lock);
00696 }

int ast_verbose_dmesg ( void(*)(const char *string, int opos, int replacelast, int complete)  v  ) 

Definition at line 698 of file logger.c.

00699 {
00700    struct msglist *m;
00701    ast_mutex_lock(&msglist_lock);
00702    m = list;
00703    while(m) {
00704       /* Send all the existing entries that we have queued (i.e. they're likely to have missed) */
00705       v(m->msg, 0, 0, 1);
00706       m = m->next;
00707    }
00708    ast_mutex_unlock(&msglist_lock);
00709    return 0;
00710 }

void close_logger ( void   ) 

Definition at line 463 of file logger.c.

00464 {
00465    struct msglist *m, *tmp;
00466 
00467    ast_mutex_lock(&msglist_lock);
00468    m = list;
00469    while(m) {
00470       if (m->msg) {
00471          free(m->msg);
00472       }
00473       tmp = m->next;
00474       free(m);
00475       m = tmp;
00476    }
00477    list = last = NULL;
00478    msgcnt = 0;
00479    ast_mutex_unlock(&msglist_lock);
00480    return;
00481 }

int init_logger ( void   ) 

Definition at line 431 of file logger.c.

00432 {
00433    char tmp[256];
00434 
00435    /* auto rotate if sig SIGXFSZ comes a-knockin */
00436    (void) signal(SIGXFSZ,(void *) handle_SIGXFSZ);
00437 
00438    /* register the relaod logger cli command */
00439    ast_cli_register(&reload_logger_cli);
00440    ast_cli_register(&rotate_logger_cli);
00441 
00442    /* initialize queue logger */
00443    queue_log_init();
00444 
00445    /* create the eventlog */
00446    mkdir((char *)ast_config_AST_LOG_DIR, 0755);
00447    snprintf(tmp, sizeof(tmp), "%s/%s", (char *)ast_config_AST_LOG_DIR, EVENTLOG);
00448    eventlog = fopen((char *)tmp, "a");
00449    if (eventlog) {
00450       init_logger_chain();
00451       ast_log(LOG_EVENT, "Started Asterisk Event Logger\n");
00452       if (option_verbose)
00453          ast_verbose("Asterisk Event Logger Started %s\n",(char *)tmp);
00454       return 0;
00455    } else 
00456       ast_log(LOG_ERROR, "Unable to create event log: %s\n", strerror(errno));
00457 
00458    /* create log channels */
00459    init_logger_chain();
00460    return -1;
00461 }

int reload_logger ( int  rotate  ) 

Definition at line 296 of file logger.c.

00297 {
00298    char old[AST_CONFIG_MAX_PATH] = "";
00299    char new[AST_CONFIG_MAX_PATH];
00300    struct logchannel *f;
00301    FILE *myf;
00302 
00303    int x;
00304    ast_mutex_lock(&loglock);
00305    if (eventlog) 
00306       fclose(eventlog);
00307    else 
00308       rotate = 0;
00309    eventlog = NULL;
00310 
00311 
00312 
00313    mkdir((char *)ast_config_AST_LOG_DIR, 0755);
00314    snprintf(old, sizeof(old), "%s/%s", (char *)ast_config_AST_LOG_DIR, EVENTLOG);
00315 
00316    if(rotate) {
00317       for(x=0;;x++) {
00318          snprintf(new, sizeof(new), "%s/%s.%d", (char *)ast_config_AST_LOG_DIR, EVENTLOG,x);
00319          myf = fopen((char *)new, "r");
00320          if(myf) 
00321             fclose(myf);
00322          else
00323             break;
00324       }
00325    
00326       /* do it */
00327       if (rename(old,new))
00328          fprintf(stderr, "Unable to rename file '%s' to '%s'\n", old, new);
00329    }
00330 
00331    eventlog = fopen(old, "a");
00332 
00333    f = logchannels;
00334    while(f) {
00335       if (f->fileptr && (f->fileptr != stdout) && (f->fileptr != stderr)) {
00336          fclose(f->fileptr);
00337          f->fileptr = NULL;
00338          if(rotate) {
00339             strncpy(old, f->filename, sizeof(old) - 1);
00340    
00341             for(x=0;;x++) {
00342                snprintf(new, sizeof(new), "%s.%d", f->filename, x);
00343                myf = fopen((char *)new, "r");
00344                if (myf) {
00345                   fclose(myf);
00346                } else {
00347                   break;
00348                }
00349             }
00350        
00351             /* do it */
00352             if (rename(old,new))
00353                fprintf(stderr, "Unable to rename file '%s' to '%s'\n", old, new);
00354          }
00355       }
00356       f = f->next;
00357    }
00358 
00359    ast_mutex_unlock(&loglock);
00360 
00361    pending_logger_reload = 0;
00362 
00363    queue_log_init();
00364 
00365    if (eventlog) {
00366       init_logger_chain();
00367       ast_log(LOG_EVENT, "Restarted Asterisk Event Logger\n");
00368       if (option_verbose)
00369          ast_verbose("Asterisk Event Logger restarted\n");
00370       return 0;
00371    } else 
00372       ast_log(LOG_ERROR, "Unable to create event log: %s\n", strerror(errno));
00373    init_logger_chain();
00374    
00375    return -1;
00376 }


Generated on Wed Oct 28 17:00:58 2009 for Asterisk by  doxygen 1.5.6