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" |
syslog CDR logger
See also
Definition in file cdr_syslog.c.
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 }
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.