0201.CDR简介

由 jafucong 发布

通话记录是每个呼叫会话期间记录的数据。CDR 可能包含特定于每个呼叫会话以及最终呼叫的每个leg的属性。
CDR 包含发起呼叫和接收呼叫的电话号码、呼叫时间、呼叫持续时间和许多其他属性。

保存通话记录

存储“实时”通话记录的最佳方法是将所有数据字段写入磁盘或 内存上的临时缓存区域,并通话脚本来扫描此缓存区域,以便将它们存储在你的数据库。这可以避免在 FS 中因保存通话记录导致的挂起语音呼叫线程。
不要在拨号方案或 ESL 脚本的挂断事件中编写 CDR 脚本,因为这会延迟语音线程的终止,并且不适用于大型系统。允许语音线程只处理语音;单独、离线处理您的后端业务流程。这种方法适用于从小型到大型的所有业务。

流行的方式包括:

  • mod_cdr_csv - 使用您在模板中指定的变量保存 CSV 文件。
  • mod_cdr_mongodb - 将详细的 CDR 数据保存到 MongoDB 数据库,格式类似于 mod_json_cdr。
  • mod_odbc_cdr - 保存通话中的任何通道变量至您选择的 ODBC 数据库中。
  • mod_cdr_pg_csv - 使用 兼容 Asterisk CDR 模块 的 PostgreSQL 数据库。
  • mod_cdr_sqlite - 使用您在模板中指定的变量直接保存到 sqlite DB。
  • mod_json_cdr - 将通道变量和调用流程通过JSON的形式保存到文件或发布到其他。它可以直接发布到 CouchDB。
  • mod_xml_cdr - 将通道变量和调用流程通过XML的形式保存到文件或发布到其他。

    • XmlcdrdJavaCDRLogger 可以帮助您保存结果。
  • mod_radius_cdr - RADIUS CDR 模块。
  • CDR via ESL - 在 ESL 事件中检索 CDR
  • 来自bougyman 的 tiny_cdr,位于 https://github.com/rubyists/tiny_cdr

当呼叫开始响铃时,如果它有媒体,那么 将设​​置progress_media_time ;如果没有, progress_time 将被设置。未设置的值将为零。因此,ring_start_time = progress_time + progress_media_time可以计算出呼叫开始响铃的确切时间:

PDD(拨号后延迟)是呼叫开始和呼叫振铃之间的静默期,因此对于振铃的呼叫:pdd = ring_start_time - created_time

如果电话被接听,则有通话时间。如果呼叫未应答,则 应答 时间将为 0。如果 应答 时间大于零:length_of_talk_time = hangup_time - answered_time

电话响了多长时间由 hangup_time 或 answers_time确定:

if ( answered_time == 0 ) then
    length_of_phone_ringing = hangup_time - created_time
else
    length_of_phone_ringing = answered_time - created_time
end

通过 ESL 保存 CDR

ESL 允许实时检索 CDR。 CDR 信息在事件 CHANNEL_HANGUP_COMPLETE 中提供。

如果您设置通道变量 hangup_complete_with_xml=true,那么该事件的主体将是完整的 XML CDR。

另见 mod_cdr_ * 模块(例如 mod_cdr_pg_csvmod_cdr_csvmod_cdr_mongodb)。

在Perl 中使用 ESL 显示 CDR 的示例
#! /usr/bin/perl -wT
# handle_cdr.pl
# Connect to event socket, listen for CHANNEL_HANGUP_COMPLETE events
# Uses event data to create custom CDRs
 
use strict;
use warnings;
 
use lib '/usr/src/freeswitch.git/libs/esl/perl';
 
use ESL;
my $host = 'localhost';
my $port = '8021';
my $pass = 'ClueCon';
# Connect to event socket
my $con  = ESL::ESLconnection->new($host, $port, $pass);
if ( ! $con ) {
    die "Unable to establish connection to FreeSWITCH.\n";
}
# Listen for events of type CHANNEL_HANGUP_COMPLETE only
$con->events('plain','CHANNEL_HANGUP_COMPLETE');
 
print "Connected to FreeSWITCH $host:$port and waiting for events...\n\n";
while ( $con->connected() ) {
    my $e = $con->recvEvent();
    my @raw_data = split /\n/, $e->serialize();
    my %cdr;
    foreach my $item ( @raw_data ) {
        #print "$item\n";
        my ($header, $value) = split /: /, $item;
        $header =~ s/^variable_//;
        $cdr{$header} = $value;
    }
    # %cdr contains a complete list of channel variables
    print 'New CDR: ';
    print $cdr{uuid} . ', ' . $cdr{direction} . ', ';
    print $cdr{answer_epoch} . ', ' . $cdr{end_epoch} . ', ';
    print $cdr{hangup_cause} . "\n";
}

暂无评论

发表评论