<p>Nir Simionovich (GreenfieldTech - Israel) has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/6818">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">This patch adds a beanstalk CDR backend.<br><br>Beanstalkd is a simple to use job queue. It provides a means to<br>create multiple job queues called "tubes". Each tube can store<br>multiple jobs, with varying priorities with the queue. Queue<br>processing is available via a simple TCP socket or via well defined<br>libraries, avaialble at<br>https://github.com/kr/beanstalkd/wiki/client-libraries<br><br>At the same time, I cleaned up some minor syntax correction inside<br>cdr_manager.c, per remarks by Corey Farrel<br><br>Change-Id: I44e7eb208f19520e939d3fcab403f4ec20370b61<br>---<br>M cdr/cdr_beanstalkd.c<br>M cdr/cdr_manager.c<br>M configs/samples/cdr_beanstalkd.conf.sample<br>M configure.ac<br>4 files changed, 81 insertions(+), 46 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/18/6818/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/cdr/cdr_beanstalkd.c b/cdr/cdr_beanstalkd.c<br>index e70b047..5ec6e64 100644<br>--- a/cdr/cdr_beanstalkd.c<br>+++ b/cdr/cdr_beanstalkd.c<br>@@ -1,7 +1,9 @@<br> /*<br>  * Asterisk -- An open source telephony toolkit.<br>  *<br>- * Copyright (C) 2004 - 2005<br>+ * Copyright (C) 2017<br>+ *<br>+ * Nir Simionovich <nirs@greenfieldtech.net><br>  *<br>  * See http://www.asterisk.org for more information about<br>  * the Asterisk project. Please do not directly contact<br>@@ -176,6 +178,7 @@<br> #include "asterisk/manager.h"<br> #include "asterisk/config.h"<br> #include "asterisk/pbx.h"<br>+#include "asterisk/json.h"<br> <br> #define DATE_FORMAT    "%Y-%m-%d %T"<br> #define CONF_FILE    "cdr_beanstalkd.conf"<br>@@ -199,7 +202,7 @@<br> static int beanstalk_put(struct ast_cdr *cdr);<br> <br> static int load_config(int reload) {<br>-    char *cat = NULL;<br>+    char *cat;<br>     struct ast_config *cfg;<br>     struct ast_variable *v;<br>     struct ast_flags config_flags = {reload ? CONFIG_FLAG_FILEUNCHANGED : 0};<br>@@ -238,24 +241,23 @@<br>         if (!strcasecmp(cat, "general")) {<br>             v = ast_variable_browse(cfg, cat);<br>             while (v) {<br>-                if (!strcasecmp(v->name, "enabled"))<br>-                    newenablecdr = ast_true(v->value);<br> <br>                 if (!newenablecdr) {<br>-                    enablecdr = newenablecdr;<br>-                    return 0;<br>+                    if (!strcasecmp(v->name, "enabled")) {<br>+                        newenablecdr = ast_true(v->value);<br>+                    }<br>+                } else {<br>+                    if (!strcasecmp(v->name, "host")) {<br>+                        bs_host = ast_strdup(v->value);<br>+                    } else if (!strcasecmp(v->name, "port")) {<br>+                        bs_port = atoi(v->value);<br>+                    } else if (!strcasecmp(v->name, "tube")) {<br>+                        bs_tube = ast_strdup(v->value);<br>+                    } else if (!strcasecmp(v->name, "priority")) {<br>+                        priority = atoi(v->value);<br>+                    }<br>+                    v = v->next;<br>                 }<br>-<br>-                if (!strcasecmp(v->name, "host"))<br>-                    bs_host = ast_strdup(v->value);<br>-                if (!strcasecmp(v->name, "port"))<br>-                    bs_port = atoi(v->value);<br>-                if (!strcasecmp(v->name, "tube"))<br>-                    bs_tube = ast_strdup(v->value);<br>-                if (!strcasecmp(v->name, "priority"))<br>-                    priority = atoi(v->value);<br>-<br>-                v = v->next;<br>             }<br>         }<br>         ast_log(LOG_NOTICE, "Added beanstalkd server %s at port %d with tube %s", bs_host, bs_port, bs_tube);<br>@@ -279,16 +281,20 @@<br> <br> static int beanstalk_put(struct ast_cdr *cdr) {<br>     struct ast_tm timeresult;<br>-    char strStartTime[80] = "";<br>-    char strAnswerTime[80] = "";<br>-    char strEndTime[80] = "";<br>+    char strStartTime[80];<br>+    char strAnswerTime[80];<br>+    char strEndTime[80];<br>     char buf[CUSTOM_FIELDS_BUF_SIZE];<br>-    char cdr_buffer[BEANSTALK_JOB_SIZE];<br>+    char *cdr_buffer;<br>+    int bs_id;<br>+    int bs_socket;<br>+    struct ast_json *t_cdr_json;<br> <br>-    if (!enablecdr)<br>+    if (!enablecdr) {<br>         return 0;<br>+    }<br> <br>-    int bs_id, bs_socket = bs_connect(bs_host, bs_port);<br>+    bs_socket = bs_connect(bs_host, bs_port);<br> <br>     if (bs_use(bs_socket, bs_tube) != BS_STATUS_OK) {<br>         ast_log(LOG_ERROR, "Connection to Beanstalk tube %s @ %s:%d had failed", bs_tube, bs_host, bs_port);<br>@@ -307,7 +313,7 @@<br>     ast_strftime(strEndTime, sizeof(strEndTime), DATE_FORMAT, &timeresult);<br> <br>     buf[0] = '\0';<br>-    cdr_buffer[0] = '\0';<br>+    //cdr_buffer[0] = '\0';<br> <br>     ast_rwlock_rdlock(&customfields_lock);<br>     if (customfields && ast_str_strlen(customfields)) {<br>@@ -322,6 +328,30 @@<br>     }<br>     ast_rwlock_unlock(&customfields_lock);<br> <br>+    t_cdr_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:i, s:i, s:s, s:s, s:s, s:s, s:s}",<br>+                               "AccountCode", S_OR(cdr->accountcode, ""),<br>+                               "Source", S_OR(cdr->src, ""),<br>+                               "Destination", S_OR(cdr->dst, ""),<br>+                               "DestinationContext", S_OR(cdr->dcontext, ""),<br>+                               "CallerID", S_OR(cdr->clid, ""),<br>+                               "Channel", S_OR(cdr->channel, ""),<br>+                               "DestinationChannel", S_OR(cdr->dstchannel, ""),<br>+                               "LastApplication", S_OR(cdr->lastapp, ""),<br>+                               "LastData", S_OR(cdr->lastdata, ""),<br>+                               "StartTime", S_OR(strStartTime, ""),<br>+                               "AnswerTime", S_OR(strAnswerTime, ""),<br>+                               "EndTime", S_OR(strEndTime, ""),<br>+                               "Duration", cdr->duration,<br>+                               "Billsec", cdr->billsec,<br>+                               "Disposition", S_OR(ast_cdr_disp2str(cdr->disposition), ""),<br>+                               "AMAFlags", S_OR(ast_channel_amaflags2string(cdr->amaflags), ""),<br>+                               "UniqueID", S_OR(cdr->uniqueid, ""),<br>+                               "UserField", S_OR(cdr->userfield, ""),<br>+                               "CustomFields", S_OR(buf, ""));<br>+<br>+    cdr_buffer = ast_json_dump_string(t_cdr_json);<br>+<br>+    /*<br>     snprintf(cdr_buffer, BEANSTALK_JOB_SIZE,<br>             "{ \"AccountCode\": \"%s\", \"Source\": \"%s\", \"Destination\": \"%s\", \"DestinationContext\": \"%s\", "<br>                     "\"CallerID\": \"%s\", \"Channel\": \"%s\", \"DestinationChannel\": \"%s\", \"LastApplication\": \"%s\", "<br>@@ -333,13 +363,15 @@<br>             cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition),<br>             ast_channel_amaflags2string(cdr->amaflags), cdr->uniqueid, cdr->userfield, buf<br>     );<br>+    */<br> <br>     bs_id = bs_put(bs_socket, priority, BEANSTALK_JOB_DELAY, BEANSTALK_JOB_TTR, cdr_buffer, strlen(cdr_buffer));<br> <br>-    if (bs_id > 0)<br>+    if (bs_id > 0) {<br>         ast_log(LOG_NOTICE, "Successfully created job %d with %s\n", bs_id, cdr_buffer);<br>-    else<br>+    } else {<br>         ast_log(LOG_ERROR, "CDR job creation failed for %s\n", cdr_buffer);<br>+    }<br> <br>     bs_disconnect(bs_socket);<br>     return 0;<br>@@ -350,8 +382,9 @@<br>         return -1;<br>     }<br> <br>-    if (customfields)<br>+    if (customfields) {<br>         ast_free(customfields);<br>+    }<br> <br>     return 0;<br> }<br>@@ -374,10 +407,10 @@<br> }<br> <br> AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Asterisk Beanstalkd CDR Backend",<br>-.support_level = AST_MODULE_SUPPORT_CORE,<br>-.load = load_module,<br>-.unload = unload_module,<br>-.reload = reload,<br>-.load_pri = AST_MODPRI_CDR_DRIVER,<br>+    .support_level = AST_MODULE_SUPPORT_CORE,<br>+    .load = load_module,<br>+    .unload = unload_module,<br>+    .reload = reload,<br>+    .load_pri = AST_MODPRI_CDR_DRIVER,<br> );<br> <br>diff --git a/cdr/cdr_manager.c b/cdr/cdr_manager.c<br>index 3f0cc6b..af0c372 100644<br>--- a/cdr/cdr_manager.c<br>+++ b/cdr/cdr_manager.c<br>@@ -273,13 +273,14 @@<br> static int manager_log(struct ast_cdr *cdr)<br> {<br>    struct ast_tm timeresult;<br>-    char strStartTime[80] = "";<br>-        char strAnswerTime[80] = "";<br>-       char strEndTime[80] = "";<br>+  char strStartTime[80];<br>+       char strAnswerTime[80];<br>+      char strEndTime[80];<br>  char buf[CUSTOM_FIELDS_BUF_SIZE];<br> <br>- if (!enablecdr)<br>+      if (!enablecdr) {<br>             return 0;<br>+    }<br> <br>  ast_localtime(&cdr->start, &timeresult, NULL);<br>     ast_strftime(strStartTime, sizeof(strStartTime), DATE_FORMAT, &timeresult);<br>@@ -340,8 +341,9 @@<br>          return -1;<br>    }<br> <br>- if (customfields)<br>+    if (customfields) {<br>           ast_free(customfields);<br>+      }<br> <br>  return 0;<br> }<br>diff --git a/configs/samples/cdr_beanstalkd.conf.sample b/configs/samples/cdr_beanstalkd.conf.sample<br>index 368ac6c..557f857 100644<br>--- a/configs/samples/cdr_beanstalkd.conf.sample<br>+++ b/configs/samples/cdr_beanstalkd.conf.sample<br>@@ -3,17 +3,18 @@<br> ;<br> ; Beanstalkd is a simple job queue server, that is highly versatile and simple to use.<br> ; Beanstalkd includes the capability of using multiple queues at the same time, with priorities.<br>+;<br> <br> [general]<br> enabled = no<br> <br>-host = 127.0.0.1    ; Specify the remote IP address of the Beanstalkd server<br>-port = 11300        ; Specify the remote PORT of the the Beanstalkd server<br>-tube = asterisk-cdr ; Specify the default CDR job queue to use<br>-priority = 99       ; Specify the default job priority for the queue. This parameter is useful when building<br>-                    ; platform with multiple Asterisk servers, that are used for different functions. For example,<br>-                    ; none billable CDR records can be inserted with a priority of 99, while billable ones be<br>-                    ; inserted with a priority of 1<br>+;host = 127.0.0.1    ; Specify the remote IP address of the Beanstalkd server<br>+;port = 11300        ; Specify the remote PORT of the the Beanstalkd server<br>+;tube = asterisk-cdr ; Specify the default CDR job queue to use<br>+;priority = 99       ; Specify the default job priority for the queue. This parameter is useful when building<br>+                     ; platform with multiple Asterisk servers, that are used for different functions. For example,<br>+                     ; none billable CDR records can be inserted with a priority of 99, while billable ones be<br>+                     ; inserted with a priority of 1<br> <br> <br> <br>diff --git a/configure.ac b/configure.ac<br>index 618ff8d..1ca64c8 100644<br>--- a/configure.ac<br>+++ b/configure.ac<br>@@ -2171,8 +2171,7 @@<br> <br> AST_EXT_LIB_CHECK([BLUETOOTH], [bluetooth], [ba2str], [bluetooth/bluetooth.h])<br> <br>-AST_EXT_LIB_CHECK([BEA<br>-NSTALK], [beanstalk], [bs_version], [beanstalk.h])<br>+AST_EXT_LIB_CHECK([BEANSTALK], [beanstalk], [bs_version], [beanstalk.h])<br> <br> # possible places for oss definitions<br> AST_EXT_LIB_CHECK([OSS], [ossaudio], [], [linux/soundcard.h])<br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/6818">change 6818</a>. To unsubscribe, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/6818"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I44e7eb208f19520e939d3fcab403f4ec20370b61 </div>
<div style="display:none"> Gerrit-Change-Number: 6818 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Nir Simionovich (GreenfieldTech - Israel) <nirs@greenfieldtech.net> </div>