Pulling CDRs directly from PostgreSQL is not always a viable solution for our users.

With the Thrift feature enabled, the system processes CDRs normally but you can configure an aggressive CDR purge cycle (two days or so).

The advantage of using Thrift is that you are empowered to ingest, process and analyze your CDRs autonomously.


Below is a request made by one of our users which prompted our extending of the Thrift functionality with the softswitch.

Request:

As an operator of a wholesale switch, I want to retrieve CDRs in simple text format from my switch so that I can ingest that data into other systems for external use.

The switch must write Account and Vendor CDRs in an agreed text-based format (JSON or CSV) to flat files.

  • The files must be rotated every N minutes.
  • The files must be removed in a timely manner to ensure servers do not run out of space

File Naming Convention, format:

client_<time_from_epoch>_<rotation_frequency_in_seconds>
If the rotation time is set to 3600 seconds, and the file is rotated at Wed, 11 Dec 2013 22:02:15 GMT, then the file name will be 1386799335
client_1386799335_3600.bin


Additionally, thrift files can be uploaded to an SFTP server and data can be parsed into the desired format with any 3rd party tool.


EXAMPLE FROM SERVER:

$ ls -lah /var/env2/upload/cdrs/thrift/
total 1520
drwxr-xr-x 2 sqlcached voip 512B Apr 6 11:30 .
drwxr-xr-x 3 root www 512B Jan 13 23:06 ..
-rw-r--r-- 1 sqlcached voip 99K Apr 6 11:32 balance_updates-thrift.bin
-rw-r--r-- 1 sqlcached voip 145K Apr 6 11:32 calls-thrift.bin
-rw-r--r-- 1 sqlcached voip 669K Apr 6 11:32 cdrs_connections-thrift.bin
-rw-r--r-- 1 sqlcached voip 64K Apr 6 11:32 cdrs_customers-thrift.bin
-rw-r--r-- 1 sqlcached voip 9.6K Apr 6 11:32 cdrs_dids-thrift.bin
-rw-r--r-- 1 sqlcached voip 494K Apr 6 11:32 cdrs-thrift.bin
Here is an example inside of available thrift files:

# sudo python /home/ssp-root/thrift_parser.py /var/env2/upload/cdrs/thrift/calls-thrift.bin |less
Calls(i_call_type=None, cli=u'account_b', cld=u'11122200123', i_call=32, setup_time=1640787124, parent_i_call=None, call_id=u'N2UyNWY2NzQ3NzExYTM1MDdkMjcyMTE3YjAzODAxNTI.', i_routing_group=3)

#sudo python /home/ssp-root/thrift_parser.py /var/env2/upload/cdrs/thrift/cdrs-thrift.bin |less
Cdrs(accessibility_cost=0.0, connect_time=1649236800, media_timeout_correction=0.0, lrn_cld=None, disconnect_time=1649236800, prefix=u'38063', cost=0.0, result=480, duration=0.0, interval_1=1, pdd1xx=8.70895851, i_cdr=293874140, delay=9.0, cld_in=u'11122200123', i_call=293874785, free_seconds=0, post_call_surcharge=0.0, connect_fee=0.0, remote_ip=u'1.2.3.4', grace_period=0, interval_n=1, area_name=None, lrn_cli=None, i_account=193, remote_party_id=None, release_source=u'callee', plan_duration=0.0, price_1=0.0122, lrn_cli_in=None, cli_in=u'543123456732', billed_duration=0.0, i_protocol=1, conn_proc_time=0.0, p_asserted_id=NullString(s=u'11122200123), user_agent=u'PBX', lrn_cld_in=None, price_n=0.0122)

$ sudo python /home/ssp-root/thrift_parser.py /var/env2/upload/cdrs/thrift/cdrs_connections-thrift.bin |less
CdrsConnections(call_setup_time=1649236791, i_media_relay=None, pdd100=0.008012574166059494, i_connection=929, connect_time=1649236800, media_timeout_correction=0.0, cld_out=u'+11122200123', lrn_cld=None, disconnect_time=1649236800, prefix=u'38063', cost=0.0, cli_out=u'543123456732', result=480, duration=0.0, interval_1=1, i_account_debug=193, i_cdrs_connection=360073869, pdd1xx=7.656707942485809, call_id=u'N2UyNWY2NzQ3NzExYTM1MDdkMjcyMTE3YjAzODAxNTI.', delay=8.0, i_call=293874785, free_seconds=0, post_call_surcharge=0.0, connect_fee=0.0, price_n=0.0095, grace_period=0, interval_n=1, area_name=None, i_media_relay_outcome=None, setup_time=1649236792, media_ip=u'', release_source=u'callee', price_1=0.0095, vendor_name=NullString(s=u'Global Com'), billed_duration=0.0, lrn_cli=None, i_protocol=1, user_agent=u'SipCall', huntstop=False, remote_ip=NullString(s=u'1.1.1.1'))

$ sudo python /home/ssp-root/thrift_parser.py /var/env2/upload/cdrs/thrift/cdrs_customers-thrift.bin |less
CdrsCustomers(price_1=0.012, grace_period=0, billed_duration=140.0, interval_n=1, i_cdrs_customer=73074157, i_wholesaler=1, i_cdr=293880311, i_call=32, setup_time=1649237250, duration=139.644230291, prefix=u'38063', cost=0.028, free_seconds=0, post_call_surcharge=0.0, media_timeout_correction=0.0, connect_fee=0.0, interval_1=1, area_name=None, i_customer=19, price_n=0.012)