]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
merge mod_cdr changes to trunk
authorMichael Jerris <mike@jerris.com>
Thu, 27 Jul 2006 17:05:27 +0000 (17:05 +0000)
committerMichael Jerris <mike@jerris.com>
Thu, 27 Jul 2006 17:05:27 +0000 (17:05 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@2188 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/mod/event_handlers/mod_cdr/Makefile
src/mod/event_handlers/mod_cdr/README
src/mod/event_handlers/mod_cdr/basecdr.cpp
src/mod/event_handlers/mod_cdr/mysqlcdr.cpp
src/mod/event_handlers/mod_cdr/mysqlcdr.h
w32/vsnet/Freeswitch.sln

index 878409293d19f8a19a11a1f55013483b4732c027..5fc52e3fe8c4ce4e8a3685e80774f43922389a9a 100644 (file)
@@ -1,7 +1,7 @@
 LDFLAGS += -I/usr/include/mysql -L/usr/lib64/mysql -lmysqlclient -lz -lcrypt -lnsl -lm -lssl -lcrypto
 CFLAGS += -I/usr/include/mysql -L/usr/lib64/mysql 
 CPPCC = g++
-OBJS=cdrcontainer.o basecdr.o baseregistry.o mysqlcdr.o pddcdr.o
+OBJS=cdrcontainer.o basecdr.o baseregistry.o mysqlcdr.o pddcdr.o csvcdr.o
 
 
 all:   depends $(OBJS) $(MODNAME).$(DYNAMIC_LIB_EXTEN)
index 0187ceb08c07318252d5bc294712bda821e95d88..a7166e35ce8ff94fc5fd5c544742752692e5d236 100644 (file)
@@ -49,7 +49,7 @@ Configuration:        Section name: <pddcdr>
 
 Class:         MysqlCDR, located in mysqlcdr.h and mysqlcdr.cpp
 Description:   This class logs the call detail record to a MySQL 4.1.x or greater database using prepared
-               statements.  This class is a little more complex than the prior two in that the fixed channel variables are treated as additional columns on the main freeswitchcdr database table for improved normalization of the database.  As such, you need to specify the format of each fixed channel variable as well.  If you do not specify, it will default to a varchar column type, and will not execute if the table schema does not match.  Therefore it is very important to make sure that any fixed channel variables you log exist as columns on the table.  The supplemental channel variables are stored in a separate table using a key / value pair linking to the callid of the call.
+               statements.  This class is a little more complex than the prior two in that the fixed channel variables are treated as additional columns on the main freeswitchcdr database table for improved normalization of the database.  As such, you need to specify the format of each fixed channel variable as well.  If you do not specify, it will default to a varchar column type, and will not execute if the table schema does not match.  Therefore it is very important to make sure that any fixed channel variables you log exist as columns on the table.  The supplemental channel variables are stored in a separate table using a key / value pair linking to the callid of the call.  Recommended to use at least one other logger in conjuction with this one just to be on the safe side, as failover handling of errors to write to the db are not yet implemented, and therefore there is a risk of data loss if the database connection is lost entirely (it will be limited to only those records created at the time of the loss of connection) or some other fatal error is encountered.
 Configuration: Section: <mysqlcdr>
                <param name="hostname" value=""/> value is the hostname or IP of the MySQL server (required)
                <param name="username" value=""/> value is the username to connect to the MySQL server with (required)
index bf6b1bc1e0b3f40bea83a7bdc195ef9ce1ff4758..77844f037882e757fe0629abac1eb251ea27593f 100644 (file)
@@ -59,6 +59,7 @@ BaseCDR::BaseCDR(switch_mod_cdr_newchannel_t *newchannel)
 {
        if(newchannel != 0)
        {
+               errorstate = 0;
                memset(clid,0,80);
                memset(dialplan,0,80);
                memset(myuuid,0,37);
@@ -84,9 +85,10 @@ BaseCDR::BaseCDR(switch_mod_cdr_newchannel_t *newchannel)
                if(newchannel->callerprofile->caller_id_name != 0)
                {
                        strncpy(clid,newchannel->callerprofile->caller_id_name,strlen(newchannel->callerprofile->caller_id_name));
-                       strncat(clid," ",1);
+                       strncat(clid," <",2);
                        if(newchannel->callerprofile->caller_id_number != 0 )
                                strncat(clid,newchannel->callerprofile->caller_id_number,strlen(clid)+strlen(newchannel->callerprofile->caller_id_number));
+                       strncat(clid,">",1);
                }
                
                // Get the ANI information if it's set
@@ -100,9 +102,7 @@ BaseCDR::BaseCDR(switch_mod_cdr_newchannel_t *newchannel)
        
                if(newchannel->callerprofile->network_addr != 0)
                        strncpy(network_addr,newchannel->callerprofile->network_addr,strlen(newchannel->callerprofile->network_addr));
-               
-               switch_console_printf(SWITCH_CHANNEL_LOG, "BaseCDR::BaseCDR(switch_mod_cdr_newchannel*) - Channel caller_profile loaded.\n");
-               
+                               
                originated = newchannel->originate;
        
                if(newchannel->originateprofile->uuid != 0)
@@ -146,8 +146,6 @@ BaseCDR::BaseCDR(switch_mod_cdr_newchannel_t *newchannel)
                hangupcause = switch_channel_get_cause(newchannel->channel);
                hangupcause_text = switch_channel_cause2str(hangupcause);
        
-               switch_console_printf(SWITCH_CHANNEL_LOG, "BaseCDR::BaseCDR(switch_mod_cdr_newchannel*) - Call state & length calculated.\n");
-               
                if(newchannel->callerextension != 0)
                        if(newchannel->callerextension->last_application != 0)
                        {
@@ -158,8 +156,6 @@ BaseCDR::BaseCDR(switch_mod_cdr_newchannel_t *newchannel)
                        }
                
                amaflags=0;
-               
-               switch_console_printf(SWITCH_CHANNEL_LOG, "BaseCDR::BaseCDR(switch_mod_cdr_newchannel*) - Processing completed.\n");
        }
 }
 
index b0fbd6b5a7334f1bdc01eb00151a085eb1ebeafe..86ead8e0c2059c0828322ba2d4786f373989f9cf 100644 (file)
@@ -83,10 +83,10 @@ std::list<std::string> MysqlCDR::chanvars_fixed_list;
 std::list<std::string> MysqlCDR::chanvars_supp_list;
 std::vector<switch_mod_cdr_sql_types_t> MysqlCDR::chanvars_fixed_types;
 bool MysqlCDR::activated = 0;
-char* MysqlCDR::sql_query = 0;
+char MysqlCDR::sql_query[1024] = "";
 std::string MysqlCDR::tmp_sql_query;
 char MysqlCDR::sql_query_chanvars[100] = "";
-MYSQL* MysqlCDR:: conn = 0;
+MYSQL* MysqlCDR::conn = 0;
 MYSQL_STMT* MysqlCDR::stmt=0;
 MYSQL_STMT* MysqlCDR::stmt_chanvars=0;
 char MysqlCDR::hostname[255] = "";
@@ -208,38 +208,38 @@ void MysqlCDR::connect(switch_xml_t& cfg, switch_xml_t& xml, switch_xml_t& setti
                        }
                        
                        tmp_sql_query.append(")");
-                       
-                       std::vector<char> tempfirstvector(tmp_sql_query.begin(), tmp_sql_query.end());
-                       tempfirstvector.push_back('\0');
-                       sql_query = &tempfirstvector[0];
        
                        char tempsql_query_chanvars[] = "INSERT INTO chanvars (callid,varname,varvalue) VALUES(?,?,?)";
                        memset(sql_query_chanvars,0,100);
                        strncpy(sql_query_chanvars,tempsql_query_chanvars,strlen(tempsql_query_chanvars));
 
-                       conn = mysql_init(NULL);
-                       mysql_options(conn, MYSQL_READ_DEFAULT_FILE, "");
-                       if(mysql_real_connect(conn,hostname,username,password,dbname,0,NULL,0) == NULL)
-                       {
-                               char *error1 = "Cannot connect to MySQL Server.  The error was: ";
-                               const char *error2 = mysql_error(conn);
-                               strncat(error1,error2,strlen(error2));
-                               switch_console_printf(SWITCH_CHANNEL_LOG,error1);
-                       }
-                       else
-                               connectionstate = 1;
+                       strncpy(sql_query,tmp_sql_query.c_str(),tmp_sql_query.size());
+                       connect_to_database();
+               }
+       }
+}
+
+void MysqlCDR::connect_to_database()
+{
+       conn = mysql_init(NULL);
+       mysql_options(conn, MYSQL_READ_DEFAULT_FILE, "");
+       if(mysql_real_connect(conn,hostname,username,password,dbname,0,NULL,0) == NULL)
+       {
+               const char *error1 = mysql_error(conn);
+               switch_console_printf(SWITCH_CHANNEL_LOG,"Cannot connect to MySQL Server.  The error was: %s\n",error1);
+       }
+       else
+               connectionstate = 1;
        
-                       mysql_autocommit(conn,0);
-                       stmt = mysql_stmt_init(conn);
+       mysql_autocommit(conn,0);
+       stmt = mysql_stmt_init(conn);
                
-                       mysql_stmt_prepare(stmt,sql_query,(long unsigned int)strlen(sql_query));
+       mysql_stmt_prepare(stmt,sql_query,(long unsigned int)strlen(sql_query));
                
-                       if(logchanvars)
-                       {
-                               stmt_chanvars = mysql_stmt_init(conn);
-                               mysql_stmt_prepare(stmt_chanvars,sql_query_chanvars,(long unsigned int)strlen(sql_query_chanvars));
-                       }
-               }
+       if(logchanvars)
+       {
+               stmt_chanvars = mysql_stmt_init(conn);
+               mysql_stmt_prepare(stmt_chanvars,sql_query_chanvars,(long unsigned int)strlen(sql_query_chanvars));
        }
 }
 
@@ -390,10 +390,8 @@ bool MysqlCDR::process_record()
                                        *x = 0;
                                        bool* is_null = new bool;
                                        *is_null = 0;
-                                       std::cout << "CDR_TINY: " << iItr->second << " and its size is " << iItr->second.size() << " bytes." << std::endl << std::endl;
                                        if(iItr->second.size() > 0)
                                        {
-                                               std::cout << "Converting iItr->second to type char." << std::endl;
                                                std::istringstream istring(iItr->second);
                                                istring >> *x;
                                        }
@@ -433,76 +431,94 @@ bool MysqlCDR::process_record()
        bindmetemp = new MYSQL_BIND[bindme.size()];
        copy(bindme.begin(), bindme.end(), bindmetemp);
        
-       mysql_stmt_bind_param(stmt,bindmetemp);
-       int bah = mysql_stmt_execute(stmt);
-       switch_console_printf(SWITCH_CHANNEL_LOG,"MysqlCDR::process_record() - Statement executed? Error: %d\n",bah);
-       
-       const char* bah2 = mysql_stmt_error(stmt);
-       switch_console_printf(SWITCH_CHANNEL_LOG,"MySQL encountered error: %s\n",bah2);
-               
-       if(logchanvars && chanvars_supp.size() > 0)
+       for(int mysql_ping_result = -1, count = 0, mysql_stmt_error_code = -1; mysql_ping_result != 0 && count < 5 && mysql_stmt_error_code != 0 ; count++)
        {
-               long long insertid = mysql_stmt_insert_id(stmt);
-
-               std::map<std::string,std::string>::iterator iItr,iBeg,iEnd;
-               iEnd = chanvars_supp.end();
-               for(iItr = chanvars_supp.begin(); iItr != iEnd; iItr++)
+               mysql_ping_result = mysql_ping(conn);
+               if(mysql_ping_result)
+               {
+                       switch(mysql_ping_result)
+                       {
+                               case CR_SERVER_GONE_ERROR:
+                               case CR_SERVER_LOST:
+                               {
+                                       switch_console_printf(SWITCH_CHANNEL_LOG,"We lost connection to the MySQL server.  Trying to reconnect.\n");
+                                       connect_to_database();
+                                       break;
+                               }
+                               default:
+                               {
+                                       switch_console_printf(SWITCH_CHANNEL_LOG,"We have encountered an unknown error when pinging the MySQL server.  Attempting to reconnect anyways.\n");
+                                       connect_to_database();
+                               }
+                       }
+               }
+               else
                {
-                       MYSQL_BIND bindme_chanvars[3];
-                       memset(bindme_chanvars,0,sizeof(bindme_chanvars));
+                       mysql_stmt_bind_param(stmt,bindmetemp);
+                       mysql_stmt_error_code = mysql_stmt_execute(stmt);
+                       
+                       if(mysql_stmt_error_code != 0)
+                       {
+                               errorstate = 1;
+                               switch_console_printf(SWITCH_CHANNEL_LOG,"MysqlCDR::process_record() - Statement executed? Error: %d\n",mysql_stmt_error_code);
+                       
+                               const char* mysql_stmt_error_string = mysql_stmt_error(stmt);
+                               switch_console_printf(SWITCH_CHANNEL_LOG,"MySQL encountered error: %s\n",mysql_stmt_error_string);
+                       }
+                       else
+                               errorstate = 0;
                        
-                       bindme_chanvars[0].buffer_type = MYSQL_TYPE_LONGLONG;
-                       bindme_chanvars[0].buffer = &insertid;
+                       if(logchanvars && chanvars_supp.size() > 0 && errorstate == 0)
+                       {
+                               long long insertid = mysql_stmt_insert_id(stmt);
+
+                               std::map<std::string,std::string>::iterator iItr,iBeg,iEnd;
+                               iEnd = chanvars_supp.end();
+                               for(iItr = chanvars_supp.begin(); iItr != iEnd; iItr++)
+                               {
+                                       MYSQL_BIND bindme_chanvars[3];
+                                       memset(bindme_chanvars,0,sizeof(bindme_chanvars));
                        
-                       std::vector<char> tempfirstvector(iItr->first.begin(), iItr->first.end());
-                       tempfirstvector.push_back('\0');
-                       char* varname_temp = &tempfirstvector[0];
+                                       bindme_chanvars[0].buffer_type = MYSQL_TYPE_LONGLONG;
+                                       bindme_chanvars[0].buffer = &insertid;
+                       
+                                       std::vector<char> tempfirstvector(iItr->first.begin(), iItr->first.end());
+                                       tempfirstvector.push_back('\0');
+                                       char* varname_temp = &tempfirstvector[0];
 
-                       bindme_chanvars[1].buffer_type = MYSQL_TYPE_VAR_STRING;
-                       long unsigned int varname_length = (long unsigned int)(iItr->first.size());
-                       bindme_chanvars[1].length = &varname_length;
-                       bindme_chanvars[1].buffer_length = varname_length;
-                       bindme_chanvars[1].buffer = varname_temp;
+                                       bindme_chanvars[1].buffer_type = MYSQL_TYPE_VAR_STRING;
+                                       long unsigned int varname_length = (long unsigned int)(iItr->first.size());
+                                       bindme_chanvars[1].length = &varname_length;
+                                       bindme_chanvars[1].buffer_length = varname_length;
+                                       bindme_chanvars[1].buffer = varname_temp;
                        
-                       std::vector<char> tempsecondvector(iItr->second.begin(), iItr->second.end());
-                       tempsecondvector.push_back('\0');
-                       char* varvalue_temp = &tempsecondvector[0];
+                                       std::vector<char> tempsecondvector(iItr->second.begin(), iItr->second.end());
+                                       tempsecondvector.push_back('\0');
+                                       char* varvalue_temp = &tempsecondvector[0];
                        
-                       bindme_chanvars[2].buffer_type = MYSQL_TYPE_VAR_STRING;
-                       if(iItr->second.size() == 0)
-                               bindme_chanvars[2].is_null = (my_bool*)1;
-                       else
-                       {
-                               long unsigned int varvalue_length = (long unsigned int)(iItr->second.size());
-                               bindme_chanvars[2].length = &varvalue_length;
-                               bindme_chanvars[2].buffer_length = varvalue_length;
-                               bindme_chanvars[2].buffer = varvalue_temp;
+                                       bindme_chanvars[2].buffer_type = MYSQL_TYPE_VAR_STRING;
+                                       if(iItr->second.size() == 0)
+                                               bindme_chanvars[2].is_null = (my_bool*)1;
+                                       else
+                                       {
+                                               long unsigned int varvalue_length = (long unsigned int)(iItr->second.size());
+                                               bindme_chanvars[2].length = &varvalue_length;
+                                               bindme_chanvars[2].buffer_length = varvalue_length;
+                                               bindme_chanvars[2].buffer = varvalue_temp;
+                                       }
+                       
+                                       mysql_stmt_bind_param(stmt_chanvars,bindme_chanvars);
+                                       mysql_stmt_execute(stmt_chanvars);
+                               }
                        }
                        
-                       mysql_stmt_bind_param(stmt_chanvars,bindme_chanvars);
-                       mysql_stmt_execute(stmt_chanvars);
+                       if(errorstate == 0)
+                               mysql_commit(conn);
+                       else
+                               mysql_rollback(conn);
                }
        }
        
-       
-       mysql_commit(conn);
-       
-       /* For future use
-       if(!mysql_stmt_execute(stmt))
-       {
-               if(errorstate == TRUE)
-                       reprocess_tempdumped_data();
-               mysql_commit(conn);
-               errorstate=FALSE();
-       }
-       else
-       {
-               errorstate = TRUE;
-               mysql_rollback(conn);
-               tempdump_data();
-       }
-       */
-       
        delete [] bindmetemp;
        if(temp_chanvars_holder.size() > 0)
        {
index 547f64f59fd101a88ef1b1f7faffa01bb2eba881..3747fbb6edaa812be34640abbedcf8f8d8c3e1ab 100644 (file)
@@ -36,6 +36,7 @@
 #include <list>
 #include <sstream>
 #include <mysql.h>
+#include <errmsg.h>
 
 #ifndef MYSQLCDR
 #define MYSQLCDR
@@ -55,7 +56,7 @@ class MysqlCDR : public BaseCDR {
 
        private:
                static bool activated;
-               static char *sql_query;
+               static char sql_query[1024];
                static std::string tmp_sql_query; // Object must exist to bind the statement, this used for generating the sql
                static char sql_query_chanvars[100];
                static MYSQL *conn;
@@ -94,6 +95,7 @@ class MysqlCDR : public BaseCDR {
                template <typename T> void add_parameter(T& param, enum_field_types type, bool *is_null=0);
                void add_string_parameter(char* param, long unsigned int& param_length, enum_field_types type, bool* is_null=0);
                void set_mysql_time(switch_time_exp_t& param, MYSQL_TIME& destination);
+               void connect_to_database();
 };
 
 #endif
index 7c92f5db934c47efda8592bddb7d53bf9cb4ab86..7071a4cbed58c2a7b4878e6a950ee24a34d6cc84 100644 (file)
@@ -384,8 +384,8 @@ Global
                {05515420-16DE-4E63-BE73-85BE85BA5142}.Debug|Win32.Build.0 = Debug|Win32\r
                {05515420-16DE-4E63-BE73-85BE85BA5142}.Release|Win32.ActiveCfg = Release|Win32\r
                {05515420-16DE-4E63-BE73-85BE85BA5142}.Release|Win32.Build.0 = Release|Win32\r
-               {3D1EED36-A510-4EDB-B4D9-4E0F4A5EC2A8}.Debug|Win32.ActiveCfg = Debug with MySql|Win32\r
-               {3D1EED36-A510-4EDB-B4D9-4E0F4A5EC2A8}.Debug|Win32.Build.0 = Debug with MySql|Win32\r
+               {3D1EED36-A510-4EDB-B4D9-4E0F4A5EC2A8}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {3D1EED36-A510-4EDB-B4D9-4E0F4A5EC2A8}.Debug|Win32.Build.0 = Debug|Win32\r
                {3D1EED36-A510-4EDB-B4D9-4E0F4A5EC2A8}.Release|Win32.ActiveCfg = Release|Win32\r
                {3D1EED36-A510-4EDB-B4D9-4E0F4A5EC2A8}.Release|Win32.Build.0 = Release|Win32\r
        EndGlobalSection\r