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>

Include dependency graph for cdr_syslog.c:

Go to the source code of this file.

Data Structures

struct  cdr_syslog_config
struct  sinks

Functions

static void __fini_sinks (void)
static void __init_sinks (void)
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 = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .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 __fini_sinks ( void   )  [static]

Definition at line 74 of file cdr_syslog.c.

00077 {

static void __init_sinks ( void   )  [static]

Definition at line 74 of file cdr_syslog.c.

00077 {

static void __init_syslog_buf ( void   )  [static]

Definition at line 59 of file cdr_syslog.c.

00063 {

static void __reg_module ( void   )  [static]

Definition at line 294 of file cdr_syslog.c.

static void __unreg_module ( void   )  [static]

Definition at line 294 of file cdr_syslog.c.

static void free_config ( void   )  [static]

Definition at line 76 of file cdr_syslog.c.

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

00077 {
00078    struct cdr_syslog_config *sink;
00079    while ((sink = AST_RWLIST_REMOVE_HEAD(&sinks, list))) {
00080       ast_mutex_destroy(&sink->lock);
00081       ast_free(sink);
00082    }
00083 }

static int load_config ( int  reload  )  [static]

Definition at line 133 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_syslog_config::facility, cdr_syslog_config::format, free_config(), cdr_syslog_config::ident, cdr_syslog_config::list, cdr_syslog_config::lock, NULL, cdr_syslog_config::priority, and tmp().

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

static enum ast_module_load_result load_module ( void   )  [static]

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

00254 {
00255    int res;
00256 
00257    if (AST_RWLIST_WRLOCK(&sinks)) {
00258       ast_log(AST_LOG_ERROR, "Unable to lock sink list.  Load failed.\n");
00259       return AST_MODULE_LOAD_DECLINE;
00260    }
00261 
00262    res = load_config(0);
00263    AST_RWLIST_UNLOCK(&sinks);
00264    if (res) {
00265       return AST_MODULE_LOAD_DECLINE;
00266    }
00267    ast_cdr_register(name, ast_module_info->description, syslog_log);
00268    return AST_MODULE_LOAD_SUCCESS;
00269 }

static int reload ( void   )  [static]

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

00272 {
00273    int res;
00274    if (AST_RWLIST_WRLOCK(&sinks)) {
00275       ast_log(AST_LOG_ERROR, "Unable to lock sink list.  Load failed.\n");
00276       return AST_MODULE_LOAD_DECLINE;
00277    }
00278 
00279    if ((res = load_config(1))) {
00280       free_config();
00281    }
00282 
00283    AST_RWLIST_UNLOCK(&sinks);
00284 
00285    return res ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS;
00286 }

static int syslog_log ( struct ast_cdr cdr  )  [static]

Definition at line 85 of file cdr_syslog.c.

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

Referenced by load_module(), and unload_module().

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

static int unload_module ( void   )  [static]

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

00237 {
00238    if (ast_cdr_unregister(name)) {
00239       return -1;
00240    }
00241 
00242    if (AST_RWLIST_WRLOCK(&sinks)) {
00243       ast_cdr_register(name, ast_module_info->description, syslog_log);
00244       ast_log(AST_LOG_ERROR, "Unable to lock sink list.  Unload failed.\n");
00245       return -1;
00246    }
00247 
00248    free_config();
00249    AST_RWLIST_UNLOCK(&sinks);
00250    return 0;
00251 }


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 = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CDR_DRIVER, } [static]

Definition at line 294 of file cdr_syslog.c.

Definition at line 294 of file cdr_syslog.c.

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

Definition at line 57 of file cdr_syslog.c.

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

Definition at line 61 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 59 of file cdr_syslog.c.

Referenced by syslog_log().


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