Wed Apr 6 11:29:54 2011

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
struct  sinks

Functions

static void __init_syslog_buf (void)
static void __reg_module (void)
static void __unreg_module (void)
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 struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Customizable syslog CDR Backend" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CDR_DRIVER, }
static struct ast_module_infoast_module_info = &__mod_info
static const char CONFIG [] = "cdr_syslog.conf"
static const char name [] = "cdr-syslog"
static struct ast_threadstorage syslog_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_syslog_buf , .custom_init = NULL , }


Detailed Description

syslog CDR logger

Author:
Sean Bright <sean@malleable.com>
See also

Definition in file cdr_syslog.c.


Function Documentation

static void __init_syslog_buf ( void   )  [static]

Definition at line 49 of file cdr_syslog.c.

00053 {

static void __reg_module ( void   )  [static]

Definition at line 279 of file cdr_syslog.c.

static void __unreg_module ( void   )  [static]

Definition at line 279 of file cdr_syslog.c.

static void free_config ( void   )  [static]

Definition at line 66 of file cdr_syslog.c.

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

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

static int load_config ( int  reload  )  [static]

Definition at line 123 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_flags, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, cdr_config::facility, free_config(), cdr_config::ident, cdr_config::list, cdr_config::lock, and cdr_config::priority.

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

static enum ast_module_load_result load_module ( void   )  [static]

Definition at line 241 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().

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

static int reload ( void   )  [static]

Definition at line 259 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().

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

static int syslog_log ( struct ast_cdr cdr  )  [static]

Definition at line 75 of file cdr_syslog.c.

References ast_cdr_dup(), ast_channel_release(), 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(), dummy(), cdr_config::facility, cdr_config::format, cdr_config::ident, cdr_config::list, cdr_config::lock, cdr_config::priority, str, and syslog_buf.

Referenced by load_module(), and unload_module().

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

static int unload_module ( void   )  [static]

Definition at line 226 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().

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


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Customizable syslog CDR Backend" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CDR_DRIVER, } [static]

Definition at line 279 of file cdr_syslog.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 279 of file cdr_syslog.c.

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

Definition at line 47 of file cdr_syslog.c.

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

Definition at line 51 of file cdr_syslog.c.

struct ast_threadstorage syslog_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_syslog_buf , .custom_init = NULL , } [static]

Definition at line 49 of file cdr_syslog.c.

Referenced by syslog_log().


Generated on Wed Apr 6 11:29:54 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7