Asterisk - The Open Source Telephony Project  18.5.0
Macros | Functions | Variables
cel_beanstalkd.c File Reference

Asterisk Channel Event Beanstalkd backend. More...

#include "asterisk.h"
#include "asterisk/channel.h"
#include "asterisk/cel.h"
#include "asterisk/module.h"
#include "asterisk/logger.h"
#include "asterisk/utils.h"
#include "asterisk/manager.h"
#include "asterisk/config.h"
#include "asterisk/json.h"
#include "beanstalk.h"
Include dependency graph for cel_beanstalkd.c:

Go to the source code of this file.

Macros

#define BEANSTALK_JOB_DELAY   0
 
#define BEANSTALK_JOB_PRIORITY   99
 
#define BEANSTALK_JOB_SIZE   4096
 
#define BEANSTALK_JOB_TTR   60
 
#define CEL_BACKEND_NAME   "Beanstalk Event Logging"
 
#define CEL_BEANSTALK_ENABLED_DEFAULT   0
 Beanstalk CEL is off by default. More...
 
#define CEL_SHOW_USERDEF_DEFAULT   0
 show_user_def is off by default More...
 
#define DEFAULT_BEANSTALK_HOST   "127.0.0.1"
 
#define DEFAULT_BEANSTALK_PORT   11300
 
#define DEFAULT_BEANSTALK_TUBE   "asterisk-cel"
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static void cel_bs_put (struct ast_event *event)
 
static int load_config (int reload)
 
static int load_module (void)
 
static int reload (void)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Beanstalkd CEL 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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CDR_DRIVER, .requires = "cel", }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static char * bs_host
 
static int bs_port
 
static char * bs_tube
 
static const char CONF_FILE [] = "cel_beanstalkd.conf"
 
static ast_rwlock_t config_lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} }
 
static const char DATE_FORMAT [] = "%Y-%m-%d %T"
 
static int enablecel
 
static int priority
 

Detailed Description

Asterisk Channel Event Beanstalkd backend.

This module requires the beanstalk-client library, avaialble from https://github.com/deepfryed/beanstalk-client

See also

Definition in file cel_beanstalkd.c.

Macro Definition Documentation

◆ BEANSTALK_JOB_DELAY

#define BEANSTALK_JOB_DELAY   0

Definition at line 77 of file cel_beanstalkd.c.

Referenced by cel_bs_put().

◆ BEANSTALK_JOB_PRIORITY

#define BEANSTALK_JOB_PRIORITY   99

Definition at line 75 of file cel_beanstalkd.c.

Referenced by load_config().

◆ BEANSTALK_JOB_SIZE

#define BEANSTALK_JOB_SIZE   4096

Definition at line 74 of file cel_beanstalkd.c.

◆ BEANSTALK_JOB_TTR

#define BEANSTALK_JOB_TTR   60

Definition at line 76 of file cel_beanstalkd.c.

Referenced by cel_bs_put().

◆ CEL_BACKEND_NAME

#define CEL_BACKEND_NAME   "Beanstalk Event Logging"

Definition at line 72 of file cel_beanstalkd.c.

Referenced by load_config(), and unload_module().

◆ CEL_BEANSTALK_ENABLED_DEFAULT

#define CEL_BEANSTALK_ENABLED_DEFAULT   0

Beanstalk CEL is off by default.

Definition at line 65 of file cel_beanstalkd.c.

Referenced by load_config().

◆ CEL_SHOW_USERDEF_DEFAULT

#define CEL_SHOW_USERDEF_DEFAULT   0

show_user_def is off by default

Definition at line 70 of file cel_beanstalkd.c.

◆ DEFAULT_BEANSTALK_HOST

#define DEFAULT_BEANSTALK_HOST   "127.0.0.1"

Definition at line 78 of file cel_beanstalkd.c.

Referenced by load_config().

◆ DEFAULT_BEANSTALK_PORT

#define DEFAULT_BEANSTALK_PORT   11300

Definition at line 79 of file cel_beanstalkd.c.

Referenced by load_config().

◆ DEFAULT_BEANSTALK_TUBE

#define DEFAULT_BEANSTALK_TUBE   "asterisk-cel"

Definition at line 80 of file cel_beanstalkd.c.

Referenced by load_config().

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 276 of file cel_beanstalkd.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 276 of file cel_beanstalkd.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 276 of file cel_beanstalkd.c.

◆ cel_bs_put()

static void cel_bs_put ( struct ast_event event)
static

Definition at line 89 of file cel_beanstalkd.c.

References ast_cel_event_record::account_code, ast_cel_event_record::amaflag, ast_cel_event_record::application_data, ast_cel_event_record::application_name, AST_CEL_EVENT_RECORD_VERSION, ast_cel_fill_record(), ast_channel_amaflags2string(), ast_json_dump_string, ast_json_free(), ast_json_pack(), ast_json_unref(), ast_localtime(), ast_log, ast_rwlock_rdlock, ast_rwlock_unlock, ast_strftime(), BEANSTALK_JOB_DELAY, BEANSTALK_JOB_TTR, bs_host, bs_port, bs_tube, ast_cel_event_record::caller_id_ani, ast_cel_event_record::caller_id_dnid, ast_cel_event_record::caller_id_name, ast_cel_event_record::caller_id_num, ast_cel_event_record::caller_id_rdnis, ast_cel_event_record::channel_name, config_lock, ast_cel_event_record::context, DATE_FORMAT, enablecel, ast_cel_event_record::event_name, ast_cel_event_record::event_time, ast_cel_event_record::extension, ast_cel_event_record::extra, ast_cel_event_record::linked_id, LOG_DEBUG, LOG_ERROR, NULL, ast_cel_event_record::peer_account, priority, S_OR, ast_cel_event_record::unique_id, ast_cel_event_record::user_field, and ast_cel_event_record::version.

Referenced by load_config().

90 {
91  struct ast_tm timeresult;
92  char start_time[80];
93  char *cel_buffer;
94  int bs_id;
95  int bs_socket;
96  struct ast_json *t_cel_json;
97 
98  struct ast_cel_event_record record = {
100  };
101 
102  if (!enablecel) {
103  return;
104  }
105 
106  if (ast_cel_fill_record(event, &record)) {
107  return;
108  }
109 
111  bs_socket = bs_connect(bs_host, bs_port);
112 
113  if (bs_use(bs_socket, bs_tube) != BS_STATUS_OK) {
114  ast_log(LOG_ERROR, "Connection to Beanstalk tube %s @ %s:%d had failed", bs_tube, bs_host, bs_port);
116  return;
117  }
118 
119  ast_localtime(&record.event_time, &timeresult, NULL);
120  ast_strftime(start_time, sizeof(start_time), DATE_FORMAT, &timeresult);
121 
123 
124  t_cel_json = ast_json_pack("{s:s, s:s, s:s, s:s, s:s, s:s, s:s, s:s, s:s, s:s, s:s, s:s, s:s, s:s, s:s, s:s, s:s, s:s, s:s, s:s}",
125  "EventName", S_OR(record.event_name, ""),
126  "AccountCode", S_OR(record.account_code, ""),
127  "CallerIDnum", S_OR(record.caller_id_num, ""),
128  "CallerIDname", S_OR(record.caller_id_name, ""),
129  "CallerIDani", S_OR(record.caller_id_ani, ""),
130  "CallerIDrdnis", S_OR(record.caller_id_rdnis, ""),
131  "CallerIDdnid", S_OR(record.caller_id_dnid, ""),
132  "Exten", S_OR(record.extension, ""),
133  "Context", S_OR(record.context, ""),
134  "Channel", S_OR(record.channel_name, ""),
135  "Application", S_OR(record.application_name, ""),
136  "AppData", S_OR(record.application_data, ""),
137  "EventTime", S_OR(start_time, ""),
138  "AMAFlags", S_OR(ast_channel_amaflags2string(record.amaflag), ""),
139  "UniqueID", S_OR(record.unique_id, ""),
140  "LinkedID", S_OR(record.linked_id, ""),
141  "Userfield", S_OR(record.user_field, ""),
142  "Peer", S_OR(record.peer_account, ""),
143  "PeerAccount", S_OR(record.peer_account, ""),
144  "Extra", S_OR(record.extra, "")
145 
146  );
147 
148  cel_buffer = ast_json_dump_string(t_cel_json);
149 
150  ast_json_unref(t_cel_json);
151 
152  bs_id = bs_put(bs_socket, priority, BEANSTALK_JOB_DELAY, BEANSTALK_JOB_TTR, cel_buffer, strlen(cel_buffer));
153 
154  if (bs_id > 0) {
155  ast_log(LOG_DEBUG, "Successfully created job %d with %s\n", bs_id, cel_buffer);
156  } else {
157  ast_log(LOG_ERROR, "CDR job creation failed for %s\n", cel_buffer);
158  }
159 
160  bs_disconnect(bs_socket);
161  ast_json_free(cel_buffer);
162 }
const char * account_code
Definition: cel.h:161
const char * caller_id_name
Definition: cel.h:151
Helper struct for getting the fields out of a CEL event.
Definition: cel.h:136
#define ast_rwlock_rdlock(a)
Definition: lock.h:233
const char * linked_id
Definition: cel.h:164
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
static char * bs_host
const char * application_data
Definition: cel.h:160
const char * application_name
Definition: cel.h:159
void ast_json_free(void *p)
Asterisk's custom JSON allocator. Exposed for use by unit tests.
Definition: json.c:52
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
const char * extension
Definition: cel.h:156
#define ast_json_dump_string(root)
Encode a JSON value to a compact string.
Definition: json.h:763
const char * ast_channel_amaflags2string(enum ama_flags flags)
Convert the enum representation of an AMA flag to a string representation.
Definition: channel.c:4418
const char * caller_id_num
Definition: cel.h:152
#define NULL
Definition: resample.c:96
#define LOG_DEBUG
Definition: logger.h:241
#define ast_rwlock_unlock(a)
Definition: lock.h:232
const char * extra
Definition: cel.h:168
static int bs_port
static int priority
#define ast_log
Definition: astobj2.c:42
const char * context
Definition: cel.h:157
uint32_t version
struct ABI version
Definition: cel.h:146
static char * bs_tube
#define LOG_ERROR
Definition: logger.h:285
const char * caller_id_rdnis
Definition: cel.h:154
static ast_rwlock_t config_lock
#define BEANSTALK_JOB_DELAY
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2524
const char * caller_id_ani
Definition: cel.h:153
const char * user_field
Definition: cel.h:166
#define AST_CEL_EVENT_RECORD_VERSION
struct ABI version
Definition: cel.h:141
static int enablecel
const char * peer_account
Definition: cel.h:162
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const char * unique_id
Definition: cel.h:163
#define BEANSTALK_JOB_TTR
Abstract JSON element (object, array, string, int, ...).
const char * caller_id_dnid
Definition: cel.h:155
const char * channel_name
Definition: cel.h:158
const char * event_name
Definition: cel.h:149
struct timeval event_time
Definition: cel.h:148
int ast_cel_fill_record(const struct ast_event *event, struct ast_cel_event_record *r)
Fill in an ast_cel_event_record from a CEL event.
Definition: cel.c:819
static const char DATE_FORMAT[]

◆ load_config()

static int load_config ( int  reload)
static

Definition at line 164 of file cel_beanstalkd.c.

References ast_category_browse(), ast_cel_backend_register(), ast_cel_backend_unregister(), ast_config_destroy(), ast_config_load, ast_free, ast_log, ast_rwlock_unlock, ast_rwlock_wrlock, ast_strdup, ast_true(), ast_variable_browse(), BEANSTALK_JOB_PRIORITY, bs_host, bs_port, bs_tube, CEL_BACKEND_NAME, CEL_BEANSTALK_ENABLED_DEFAULT, cel_bs_put(), CONF_FILE, CONFIG_FLAG_FILEUNCHANGED, config_lock, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, DEFAULT_BEANSTALK_HOST, DEFAULT_BEANSTALK_PORT, DEFAULT_BEANSTALK_TUBE, enablecel, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_variable::name, ast_variable::next, NULL, priority, and ast_variable::value.

Referenced by load_module(), and reload().

165 {
166  const char *cat = NULL;
167  struct ast_config *cfg;
168  struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
169  struct ast_variable *v;
170  int newenablecel = CEL_BEANSTALK_ENABLED_DEFAULT;
171 
172  cfg = ast_config_load(CONF_FILE, config_flags);
173  if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
174  return 0;
175  }
176 
177  if (cfg == CONFIG_STATUS_FILEINVALID) {
178  ast_log(LOG_WARNING, "Configuration file '%s' is invalid. CEL Beanstalkd Module not activated.\n",
179  CONF_FILE);
180  return -1;
181  } else if (!cfg) {
182  ast_log(LOG_WARNING, "Failed to load configuration file. CEL Beanstalkd Module not activated.\n");
183  if (enablecel) {
185  }
186  enablecel = 0;
187  return -1;
188  }
189 
190  if (reload) {
192  ast_free(bs_host);
193  ast_free(bs_tube);
194  }
195 
196  /* Bootstrap the default configuration */
201 
202  while ((cat = ast_category_browse(cfg, cat))) {
203 
204  if (strcasecmp(cat, "general")) {
205  continue;
206  }
207 
208  for (v = ast_variable_browse(cfg, cat); v; v = v->next) {
209  if (!strcasecmp(v->name, "enabled")) {
210  newenablecel = ast_true(v->value) ? 1 : 0;
211  } else if (!strcasecmp(v->name, "host")) {
212  ast_free(bs_host);
213  bs_host = ast_strdup(v->value);
214  } else if (!strcasecmp(v->name, "port")) {
215  bs_port = atoi(v->value);
216  } else if (!strcasecmp(v->name, "tube")) {
217  ast_free(bs_tube);
218  bs_tube = ast_strdup(v->value);
219  } else if (!strcasecmp(v->name, "priority")) {
220  priority = atoi(v->value);
221  } else {
222  ast_log(LOG_NOTICE, "Unknown option '%s' specified "
223  "for CEL beanstalk backend.\n", v->name);
224  }
225  }
226  }
227 
228  if (reload) {
230  }
231 
232  ast_config_destroy(cfg);
233 
234  if (enablecel && !newenablecel) {
236  } else if (!enablecel && newenablecel) {
238  ast_log(LOG_ERROR, "Unable to register Beanstalkd CEL handling\n");
239  }
240  }
241 
242  enablecel = newenablecel;
243 
244  return 0;
245 }
struct ast_variable * next
static int reload(void)
static const char CONF_FILE[]
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1216
int ast_cel_backend_register(const char *name, ast_cel_backend_cb backend_callback)
Register a CEL backend.
Definition: cel.c:1740
static char * bs_host
#define CEL_BEANSTALK_ENABLED_DEFAULT
Beanstalk CEL is off by default.
#define LOG_WARNING
Definition: logger.h:274
#define CONFIG_STATUS_FILEINVALID
#define CEL_BACKEND_NAME
Structure for variables, used for configurations and for channel variables.
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3328
#define NULL
Definition: resample.c:96
#define ast_rwlock_unlock(a)
Definition: lock.h:232
static int bs_port
#define DEFAULT_BEANSTALK_PORT
static int priority
#define ast_log
Definition: astobj2.c:42
#define ast_config_load(filename, flags)
Load a config file.
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
static char * bs_tube
int ast_cel_backend_unregister(const char *name)
Unregister a CEL backend.
Definition: cel.c:1728
#define CONFIG_STATUS_FILEUNCHANGED
#define LOG_ERROR
Definition: logger.h:285
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
#define LOG_NOTICE
Definition: logger.h:263
#define ast_free(a)
Definition: astmm.h:182
#define BEANSTALK_JOB_PRIORITY
static ast_rwlock_t config_lock
Structure used to handle boolean flags.
Definition: utils.h:199
static int enablecel
#define ast_rwlock_wrlock(a)
Definition: lock.h:234
#define DEFAULT_BEANSTALK_HOST
#define DEFAULT_BEANSTALK_TUBE
static void cel_bs_put(struct ast_event *event)

◆ load_module()

static int load_module ( void  )
static

Definition at line 255 of file cel_beanstalkd.c.

References AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, and load_config().

Referenced by reload().

256 {
257  if (load_config(0)) {
259  }
260 
262 }
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static int load_config(int reload)

◆ reload()

static int reload ( void  )
static

Definition at line 264 of file cel_beanstalkd.c.

References AST_MODFLAG_LOAD_ORDER, AST_MODPRI_CDR_DRIVER, AST_MODULE_INFO(), AST_MODULE_SUPPORT_EXTENDED, ASTERISK_GPL_KEY, load_config(), load_module(), and unload_module().

265 {
266  return load_config(1);
267 }
static int load_config(int reload)

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 247 of file cel_beanstalkd.c.

References ast_cel_backend_unregister(), ast_free, bs_host, bs_tube, and CEL_BACKEND_NAME.

Referenced by reload().

248 {
250  ast_free(bs_host);
251  ast_free(bs_tube);
252  return 0;
253 }
static char * bs_host
#define CEL_BACKEND_NAME
static char * bs_tube
int ast_cel_backend_unregister(const char *name)
Unregister a CEL backend.
Definition: cel.c:1728
#define ast_free(a)
Definition: astmm.h:182

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Beanstalkd CEL 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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CDR_DRIVER, .requires = "cel", }
static

Definition at line 276 of file cel_beanstalkd.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 276 of file cel_beanstalkd.c.

◆ bs_host

char* bs_host
static

Definition at line 82 of file cel_beanstalkd.c.

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

◆ bs_port

int bs_port
static

Definition at line 83 of file cel_beanstalkd.c.

Referenced by cel_bs_put(), and load_config().

◆ bs_tube

char* bs_tube
static

Definition at line 84 of file cel_beanstalkd.c.

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

◆ CONF_FILE

const char CONF_FILE[] = "cel_beanstalkd.conf"
static

Definition at line 62 of file cel_beanstalkd.c.

Referenced by load_config().

◆ config_lock

ast_rwlock_t config_lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} }
static

Definition at line 87 of file cel_beanstalkd.c.

Referenced by cel_bs_put(), and load_config().

◆ DATE_FORMAT

const char DATE_FORMAT[] = "%Y-%m-%d %T"
static

Definition at line 60 of file cel_beanstalkd.c.

Referenced by cel_bs_put().

◆ enablecel

int enablecel
static

Definition at line 67 of file cel_beanstalkd.c.

Referenced by cel_bs_put(), and load_config().

◆ priority

int priority
static

Definition at line 85 of file cel_beanstalkd.c.

Referenced by cel_bs_put(), and load_config().