Tue Aug 20 16:34:49 2013

Asterisk developer's documentation


cdr_syslog.c File Reference

syslog CDR logger More...

#include "asterisk.h"
#include "asterisk/module.h"
#include "asterisk/lock.h"
#include "asterisk/cdr.h"
#include "asterisk/pbx.h"
#include <syslog.h>

Go to the source code of this file.

Data Structures

struct  cdr_config

Functions

 AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER,"Customizable syslog CDR Backend",.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CDR_DRIVER,)
static AST_RWLIST_HEAD_STATIC (sinks, cdr_config)
 AST_THREADSTORAGE (syslog_buf)
static void free_config (void)
static int load_config (int reload)
static enum ast_module_load_result load_module (void)
static int reload (void)
static int syslog_log (struct ast_cdr *cdr)
static int unload_module (void)

Variables

static const char CONFIG [] = "cdr_syslog.conf"
static const char name [] = "cdr-syslog"

Detailed Description

syslog CDR logger

Author:
Sean Bright <sean@malleable.com>

See also

Definition in file cdr_syslog.c.


Function Documentation

AST_MODULE_INFO ( ASTERISK_GPL_KEY  ,
AST_MODFLAG_LOAD_ORDER  ,
"Customizable syslog CDR Backend"  ,
load = load_module,
unload = unload_module,
reload = reload,
load_pri = AST_MODPRI_CDR_DRIVER 
)
static AST_RWLIST_HEAD_STATIC ( sinks  ,
cdr_config   
) [static]
AST_THREADSTORAGE ( syslog_buf   ) 
static void free_config ( void   )  [static]

Definition at line 67 of file cdr_syslog.c.

References ast_free, ast_mutex_destroy, AST_RWLIST_REMOVE_HEAD, and cdr_config::lock.

Referenced by load_config(), reload(), and unload_module().

00068 {
00069    struct cdr_config *sink;
00070    while ((sink = AST_RWLIST_REMOVE_HEAD(&sinks, list))) {
00071       ast_mutex_destroy(&sink->lock);
00072       ast_free(sink);
00073    }
00074 }

static int load_config ( int  reload  )  [static]

Definition at line 124 of file cdr_syslog.c.

References ast_calloc_with_stringfields, ast_category_browse(), ast_config_destroy(), ast_config_load, ast_log(), AST_LOG_ERROR, AST_LOG_WARNING, ast_mutex_init, AST_RWLIST_EMPTY, AST_RWLIST_INSERT_TAIL, ast_string_field_set, ast_strlen_zero(), ast_syslog_facility(), ast_syslog_facility_name(), ast_syslog_priority(), ast_syslog_priority_name(), ast_variable_retrieve(), CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, cdr_config::facility, format, free_config(), cdr_config::lock, and cdr_config::priority.

Referenced by load_module(), and reload().

00125 {
00126    struct ast_config *cfg;
00127    struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
00128    int default_facility = LOG_LOCAL4;
00129    int default_priority = LOG_INFO;
00130    const char *catg = NULL, *tmp;
00131 
00132    cfg = ast_config_load(CONFIG, config_flags);
00133    if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) {
00134       ast_log(AST_LOG_ERROR,
00135          "Unable to load %s. Not logging custom CSV CDRs to syslog.\n", CONFIG);
00136       return -1;
00137    } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
00138       return 0;
00139    }
00140 
00141    if (reload) {
00142       free_config();
00143    }
00144 
00145    if (!(ast_strlen_zero(tmp = ast_variable_retrieve(cfg, "general", "facility")))) {
00146       int facility = ast_syslog_facility(tmp);
00147       if (facility < 0) {
00148          ast_log(AST_LOG_WARNING,
00149             "Invalid facility '%s' specified, defaulting to '%s'\n",
00150             tmp, ast_syslog_facility_name(default_facility));
00151       } else {
00152          default_facility = facility;
00153       }
00154    }
00155 
00156    if (!(ast_strlen_zero(tmp = ast_variable_retrieve(cfg, "general", "priority")))) {
00157       int priority = ast_syslog_priority(tmp);
00158       if (priority < 0) {
00159          ast_log(AST_LOG_WARNING,
00160             "Invalid priority '%s' specified, defaulting to '%s'\n",
00161             tmp, ast_syslog_priority_name(default_priority));
00162       } else {
00163          default_priority = priority;
00164       }
00165    }
00166 
00167    while ((catg = ast_category_browse(cfg, catg))) {
00168       struct cdr_config *sink;
00169 
00170       if (!strcasecmp(catg, "general")) {
00171          continue;
00172       }
00173 
00174       if (ast_strlen_zero(tmp = ast_variable_retrieve(cfg, catg, "template"))) {
00175          ast_log(AST_LOG_WARNING,
00176             "No 'template' parameter found for '%s'.  Skipping.\n", catg);
00177          continue;
00178       }
00179 
00180       sink = ast_calloc_with_stringfields(1, struct cdr_config, 1024);
00181 
00182       if (!sink) {
00183          ast_log(AST_LOG_ERROR,
00184             "Unable to allocate memory for configuration settings.\n");
00185          free_config();
00186          break;
00187       }
00188 
00189       ast_mutex_init(&sink->lock);
00190       ast_string_field_set(sink, ident, catg);
00191       ast_string_field_set(sink, format, tmp);
00192 
00193       if (ast_strlen_zero(tmp = ast_variable_retrieve(cfg, catg, "facility"))) {
00194          sink->facility = default_facility;
00195       } else {
00196          int facility = ast_syslog_facility(tmp);
00197          if (facility < 0) {
00198             ast_log(AST_LOG_WARNING,
00199                "Invalid facility '%s' specified for '%s,' defaulting to '%s'\n",
00200                tmp, catg, ast_syslog_facility_name(default_facility));
00201          } else {
00202             sink->facility = facility;
00203          }
00204       }
00205 
00206       if (ast_strlen_zero(tmp = ast_variable_retrieve(cfg, catg, "priority"))) {
00207          sink->priority = default_priority;
00208       } else {
00209          int priority = ast_syslog_priority(tmp);
00210          if (priority < 0) {
00211             ast_log(AST_LOG_WARNING,
00212                "Invalid priority '%s' specified for '%s,' defaulting to '%s'\n",
00213                tmp, catg, ast_syslog_priority_name(default_priority));
00214          } else {
00215             sink->priority = priority;
00216          }
00217       }
00218 
00219       AST_RWLIST_INSERT_TAIL(&sinks, sink, list);
00220    }
00221 
00222    ast_config_destroy(cfg);
00223 
00224    return AST_RWLIST_EMPTY(&sinks) ? -1 : 0;
00225 }

static enum ast_module_load_result load_module ( void   )  [static]

Definition at line 242 of file cdr_syslog.c.

References ast_cdr_register(), ast_log(), AST_LOG_ERROR, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, load_config(), and syslog_log().

00243 {
00244    int res;
00245 
00246    if (AST_RWLIST_WRLOCK(&sinks)) {
00247       ast_log(AST_LOG_ERROR, "Unable to lock sink list.  Load failed.\n");
00248       return AST_MODULE_LOAD_DECLINE;
00249    }
00250 
00251    res = load_config(0);
00252    AST_RWLIST_UNLOCK(&sinks);
00253    if (res) {
00254       return AST_MODULE_LOAD_DECLINE;
00255    }
00256    ast_cdr_register(name, ast_module_info->description, syslog_log);
00257    return AST_MODULE_LOAD_SUCCESS;
00258 }

static int reload ( void   )  [static]

Definition at line 260 of file cdr_syslog.c.

References ast_log(), AST_LOG_ERROR, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, free_config(), and load_config().

00261 {
00262    int res;
00263    if (AST_RWLIST_WRLOCK(&sinks)) {
00264       ast_log(AST_LOG_ERROR, "Unable to lock sink list.  Load failed.\n");
00265       return AST_MODULE_LOAD_DECLINE;
00266    }
00267 
00268    if ((res = load_config(1))) {
00269       free_config();
00270    }
00271 
00272    AST_RWLIST_UNLOCK(&sinks);
00273 
00274    return res ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS;
00275 }

static int syslog_log ( struct ast_cdr cdr  )  [static]

Definition at line 76 of file cdr_syslog.c.

References ast_cdr_dup(), ast_channel_unref, ast_dummy_channel_alloc, AST_LIST_TRAVERSE, ast_log(), AST_LOG_ERROR, ast_mutex_lock, ast_mutex_unlock, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_str_buffer(), ast_str_substitute_variables(), ast_str_thread_get(), ast_channel::cdr, dummy(), cdr_config::facility, cdr_config::lock, cdr_config::priority, and str.

Referenced by load_module(), and unload_module().

00077 {
00078    struct ast_channel *dummy;
00079    struct ast_str *str;
00080    struct cdr_config *sink;
00081 
00082    /* Batching saves memory management here.  Otherwise, it's the same as doing an
00083       allocation and free each time. */
00084    if (!(str = ast_str_thread_get(&syslog_buf, 16))) {
00085       return -1;
00086    }
00087 
00088    if (!(dummy = ast_dummy_channel_alloc())) {
00089       ast_log(AST_LOG_ERROR, "Unable to allocate channel for variable substitution.\n");
00090       return -1;
00091    }
00092 
00093    /* We need to dup here since the cdr actually belongs to the other channel,
00094       so when we release this channel we don't want the CDR getting cleaned
00095       up prematurely. */
00096    dummy->cdr = ast_cdr_dup(cdr);
00097 
00098    AST_RWLIST_RDLOCK(&sinks);
00099 
00100    AST_LIST_TRAVERSE(&sinks, sink, list) {
00101 
00102       ast_str_substitute_variables(&str, 0, dummy, sink->format);
00103 
00104       /* Even though we have a lock on the list, we could be being chased by
00105          another thread and this lock ensures that we won't step on anyone's
00106          toes.  Once each CDR backend gets it's own thread, this lock can be
00107          removed. */
00108       ast_mutex_lock(&sink->lock);
00109 
00110       openlog(sink->ident, LOG_CONS, sink->facility);
00111       syslog(sink->priority, "%s", ast_str_buffer(str));
00112       closelog();
00113 
00114       ast_mutex_unlock(&sink->lock);
00115    }
00116 
00117    AST_RWLIST_UNLOCK(&sinks);
00118 
00119    ast_channel_unref(dummy);
00120 
00121    return 0;
00122 }

static int unload_module ( void   )  [static]

Definition at line 227 of file cdr_syslog.c.

References ast_cdr_register(), ast_cdr_unregister(), ast_log(), AST_LOG_ERROR, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, free_config(), and syslog_log().

00228 {
00229    ast_cdr_unregister(name);
00230 
00231    if (AST_RWLIST_WRLOCK(&sinks)) {
00232       ast_cdr_register(name, ast_module_info->description, syslog_log);
00233       ast_log(AST_LOG_ERROR, "Unable to lock sink list.  Unload failed.\n");
00234       return -1;
00235    }
00236 
00237    free_config();
00238    AST_RWLIST_UNLOCK(&sinks);
00239    return 0;
00240 }


Variable Documentation

const char CONFIG[] = "cdr_syslog.conf" [static]

Definition at line 48 of file cdr_syslog.c.

const char name[] = "cdr-syslog" [static]

Definition at line 52 of file cdr_syslog.c.


Generated on 20 Aug 2013 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1