Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

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 <string.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
#include <sys/stat.h>
#include "asterisk.h"
#include "astconf.h"
#include <syslog.h>
#include <asterisk/logger.h>

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

Functions

int reload_logger (int rotate)
int init_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 MAX_MSG_QUEUE   200
 

Definition at line 49 of file logger.c.

Referenced by ast_verbose().

#define SYSLOG_NAMES
 

Value:

/* so we can map syslog facilities names to their numeric values,
              from <syslog.h> which is included by logger.h */

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 408 of file logger.c.

References __LOG_DEBUG, __LOG_EVENT, __LOG_VERBOSE, ast_console_puts(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_verbose(), COLOR_BRWHITE, LOG_EVENT, option_debug, option_verbose, reload_logger(), and term_color().

00408 {
00409     struct logchannel *chan;
00410     char buf[BUFSIZ];
00411     time_t t;
00412     struct tm tm;
00413     char date[256];
00414 
00415     va_list ap;
00416    
00417     if (!option_verbose && !option_debug && (level == __LOG_DEBUG)) {
00418    return;
00419     }
00420 
00421     /* begin critical section */
00422     ast_mutex_lock(&loglock);
00423 
00424     time(&t);
00425     localtime_r(&t, &tm);
00426     strftime(date, sizeof(date), "%b %e %T", &tm);
00427 
00428 
00429     if (level == __LOG_EVENT) {
00430        va_start(ap, fmt);
00431 
00432        fprintf(eventlog, "%s asterisk[%d]: ", date, getpid());
00433        vfprintf(eventlog, fmt, ap);
00434        fflush(eventlog);
00435 
00436        va_end(ap);
00437        ast_mutex_unlock(&loglock);
00438        return;
00439     }
00440 
00441     if (logchannels) {
00442    chan = logchannels;
00443    while(chan) {
00444        if (chan->syslog && (chan->logmask & (1 << level))) {
00445       va_start(ap, fmt);
00446       ast_log_vsyslog(level, file, line, function, fmt, ap);
00447       va_end(ap);
00448        } else if ((chan->logmask & (1 << level)) && (chan->console)) {
00449       char linestr[128];
00450       char tmp1[80], tmp2[80], tmp3[80], tmp4[80];
00451 
00452       if(level != __LOG_VERBOSE) {
00453           sprintf(linestr, "%d", line);
00454           snprintf(buf, sizeof(buf), "%s %s[%ld]: %s:%s %s: ",
00455               date,
00456               term_color(tmp1, levels[level], colors[level], 0, sizeof(tmp1)),
00457               (long)pthread_self(),
00458               term_color(tmp2, file, COLOR_BRWHITE, 0, sizeof(tmp2)),
00459               term_color(tmp3, linestr, COLOR_BRWHITE, 0, sizeof(tmp3)),
00460               term_color(tmp4, function, COLOR_BRWHITE, 0, sizeof(tmp4)));
00461           
00462           ast_console_puts(buf);
00463           va_start(ap, fmt);
00464           vsnprintf(buf, sizeof(buf), fmt, ap);
00465           va_end(ap);
00466           ast_console_puts(buf);
00467       }
00468        } else if ((chan->logmask & (1 << level)) && (chan->fileptr)) {
00469           snprintf(buf, sizeof(buf), "%s %s[%ld]: ", date,
00470               levels[level], (long)pthread_self());
00471           fprintf(chan->fileptr, buf);
00472           va_start(ap, fmt);
00473           vsnprintf(buf, sizeof(buf), fmt, ap);
00474           va_end(ap);
00475           fputs(buf, chan->fileptr);
00476           fflush(chan->fileptr);
00477        }
00478        chan = chan->next;
00479    }
00480     } else {
00481        /* 
00482         * we don't have the logger chain configured yet,
00483         * so just log to stdout 
00484         */
00485       if (level != __LOG_VERBOSE) {
00486           va_start(ap, fmt);
00487           vsnprintf(buf, sizeof(buf), fmt, ap);
00488           va_end(ap);
00489           fputs(buf, stdout);
00490       }
00491     }
00492 
00493     ast_mutex_unlock(&loglock);
00494     /* end critical section */
00495    if (pending_logger_reload) {
00496        reload_logger(1);
00497        ast_log(LOG_EVENT,"Rotated Logs Per SIGXFSZ\n");
00498        if (option_verbose)
00499           ast_verbose("Rotated Logs Per SIGXFSZ\n");
00500    }
00501 }
00502 

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

Definition at line 582 of file logger.c.

References ast_mutex_lock, ast_mutex_unlock, and malloc.

Referenced by main().

00582 {
00583    struct msglist *m;
00584    struct verb *tmp;
00585    /* XXX Should be more flexible here, taking > 1 verboser XXX */
00586    if ((tmp = malloc(sizeof (struct verb)))) {
00587       tmp->verboser = v;
00588       ast_mutex_lock(&msglist_lock);
00589       tmp->next = verboser;
00590       verboser = tmp;
00591       m = list;
00592       while(m) {
00593          /* Send all the existing entries that we have queued (i.e. they're likely to have missed) */
00594          v(m->msg, 0, 0, 1);
00595          m = m->next;
00596       }
00597       ast_mutex_unlock(&msglist_lock);
00598       return 0;
00599    }
00600    return -1;
00601 }
00602 

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

Definition at line 604 of file logger.c.

References ast_mutex_lock, ast_mutex_unlock, and free.

00604 {
00605    int res = -1;
00606    struct verb *tmp, *tmpl=NULL;
00607    ast_mutex_lock(&msglist_lock);
00608    tmp = verboser;
00609    while(tmp) {
00610       if (tmp->verboser == v) {
00611          if (tmpl)
00612             tmpl->next = tmp->next;
00613          else
00614             verboser = tmp->next;
00615          free(tmp);
00616          break;
00617       }
00618       tmpl = tmp;
00619       tmp = tmp->next;
00620    }
00621    if (tmp)
00622       res = 0;
00623    ast_mutex_unlock(&msglist_lock);
00624    return res;
00625 }
00626 }

void ast_verbose const char *  fmt,
  ...
 

Definition at line 504 of file logger.c.

References ast_log(), ast_mutex_lock, ast_mutex_unlock, free, LOG_ERROR, LOG_VERBOSE, malloc, MAX_MSG_QUEUE, and strdup.

00504 {
00505    static char stuff[4096];
00506    static int pos = 0, opos;
00507    static int replacelast = 0, complete;
00508    struct msglist *m;
00509    struct verb *v;
00510    va_list ap;
00511    va_start(ap, fmt);
00512    ast_mutex_lock(&msglist_lock);
00513    vsnprintf(stuff + pos, sizeof(stuff) - pos, fmt, ap);
00514    opos = pos;
00515    pos = strlen(stuff);
00516    if (fmt[strlen(fmt)-1] == '\n') 
00517       complete = 1;
00518    else
00519       complete=0;
00520    if (complete) {
00521       if (msgcnt < MAX_MSG_QUEUE) {
00522          /* Allocate new structure */
00523          m = malloc(sizeof(struct msglist));
00524          msgcnt++;
00525       } else {
00526          /* Recycle the oldest entry */
00527          m = list;
00528          list = list->next;
00529          free(m->msg);
00530       }
00531       if (m) {
00532          m->msg = strdup(stuff);
00533          if (m->msg) {
00534             if (last)
00535                last->next = m;
00536             else
00537                list = m;
00538             m->next = NULL;
00539             last = m;
00540          } else {
00541             msgcnt--;
00542             ast_log(LOG_ERROR, "Out of memory\n");
00543             free(m);
00544          }
00545       }
00546    }
00547    if (verboser) {
00548       v = verboser;
00549       while(v) {
00550          v->verboser(stuff, opos, replacelast, complete);
00551          v = v->next;
00552       }
00553    } /* else
00554       fprintf(stdout, stuff + opos); */
00555 
00556    ast_log(LOG_VERBOSE, stuff);
00557 
00558    if (fmt[strlen(fmt)-1] != '\n') 
00559       replacelast = 1;
00560    else 
00561       replacelast = pos = 0;
00562    va_end(ap);
00563 
00564    ast_mutex_unlock(&msglist_lock);
00565 }
00566 

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

Definition at line 568 of file logger.c.

References ast_mutex_lock, and ast_mutex_unlock.

00568 {
00569    struct msglist *m;
00570    m = list;
00571    ast_mutex_lock(&msglist_lock);
00572    while(m) {
00573       /* Send all the existing entries that we have queued (i.e. they're likely to have missed) */
00574       v(m->msg, 0, 0, 1);
00575       m = m->next;
00576    }
00577    ast_mutex_unlock(&msglist_lock);
00578    return 0;
00579 }
00580 

int init_logger void   ) 
 

Definition at line 355 of file logger.c.

References ast_cli_register(), ast_config_AST_LOG_DIR, ast_log(), ast_verbose(), EVENTLOG, LOG_ERROR, LOG_EVENT, and option_verbose.

Referenced by main().

00355 {
00356    char tmp[256];
00357 
00358    /* auto rotate if sig SIGXFSZ comes a-knockin */
00359    (void) signal(SIGXFSZ,(void *) handle_SIGXFSZ);
00360 
00361    /* register the relaod logger cli command */
00362    ast_cli_register(&reload_logger_cli);
00363    ast_cli_register(&rotate_logger_cli);
00364 
00365    /* create the eventlog */
00366    mkdir((char *)ast_config_AST_LOG_DIR, 0755);
00367    snprintf(tmp, sizeof(tmp), "%s/%s", (char *)ast_config_AST_LOG_DIR, EVENTLOG);
00368    eventlog = fopen((char *)tmp, "a");
00369    if (eventlog) {
00370       init_logger_chain();
00371       ast_log(LOG_EVENT, "Started Asterisk Event Logger\n");
00372       if (option_verbose)
00373          ast_verbose("Asterisk Event Logger Started %s\n",(char *)tmp);
00374       return 0;
00375    } else 
00376       ast_log(LOG_ERROR, "Unable to create event log: %s\n", strerror(errno));
00377 
00378    init_logger_chain();
00379 
00380    /* create log channels */
00381    init_logger_chain();
00382    return -1;
00383 }
00384 

int reload_logger int  rotate  ) 
 

Definition at line 225 of file logger.c.

References ast_config_AST_LOG_DIR, AST_CONFIG_MAX_PATH, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_verbose(), EVENTLOG, LOG_ERROR, LOG_EVENT, and option_verbose.

Referenced by ast_log().

00225 {
00226    char old[AST_CONFIG_MAX_PATH];
00227    char new[AST_CONFIG_MAX_PATH];
00228    struct logchannel *f;
00229    FILE *myf;
00230 
00231    int x;
00232    ast_mutex_lock(&loglock);
00233    if (eventlog) 
00234       fclose(eventlog);
00235    else 
00236       rotate = 0;
00237    eventlog = NULL;
00238 
00239 
00240 
00241    mkdir((char *)ast_config_AST_LOG_DIR, 0755);
00242    snprintf(old, sizeof(old), "%s/%s", (char *)ast_config_AST_LOG_DIR, EVENTLOG);
00243 
00244    if(rotate) {
00245       for(x=0;;x++) {
00246          snprintf(new, sizeof(new), "%s/%s.%d", (char *)ast_config_AST_LOG_DIR, EVENTLOG,x);
00247          myf = fopen((char *)new, "r");
00248          if(myf) 
00249             fclose(myf);
00250          else
00251             break;
00252       }
00253    
00254       /* do it */
00255       if (rename(old,new))
00256          fprintf(stderr, "Unable to rename file '%s' to '%s'\n", old, new);
00257    }
00258 
00259    eventlog = fopen(old, "a");
00260 
00261    f = logchannels;
00262    while(f) {
00263       if (f->fileptr && (f->fileptr != stdout) && (f->fileptr != stderr)) {
00264          fclose(f->fileptr);
00265          f->fileptr = NULL;
00266          if(rotate) {
00267             strncpy(old, f->filename, sizeof(old));
00268    
00269             for(x=0;;x++) {
00270                snprintf(new, sizeof(new), "%s.%d", f->filename, x);
00271                myf = fopen((char *)new, "r");
00272                if (myf) {
00273                   fclose(myf);
00274                } else {
00275                   break;
00276                }
00277             }
00278        
00279             /* do it */
00280             if (rename(old,new))
00281                fprintf(stderr, "Unable to rename file '%s' to '%s'\n", old, new);
00282          }
00283       }
00284       f = f->next;
00285    }
00286 
00287    ast_mutex_unlock(&loglock);
00288 
00289    if (eventlog) {
00290       init_logger_chain();
00291       ast_log(LOG_EVENT, "Restarted Asterisk Event Logger\n");
00292       if (option_verbose)
00293          ast_verbose("Asterisk Event Logger restarted\n");
00294       return 0;
00295    } else 
00296       ast_log(LOG_ERROR, "Unable to create event log: %s\n", strerror(errno));
00297    init_logger_chain();
00298    pending_logger_reload = 0;
00299    return -1;
00300 }
00301 


Generated on Sun Apr 18 23:34:07 2004 for Asterisk by doxygen 1.3.6-20040222