#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_info * | ast_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 , } |
Definition in file cdr_syslog.c.
static void __init_syslog_buf | ( | void | ) | [static] |
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 }
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] |