Call Detail Record (CDR)

Um Call Detail Record é um registro que mostra as chamadas realizadas e recebidas de um determinado usuário ou conta. Em uma central de telefonia ele é vital para que possamos mensurar o volume de chamadas e até mesmo controlar os custos.

Na maioria dos casos utilizamos um banco de dados para armazená-los e posteriormente extraí-los para geração de relatórios, tarifação e estatísticas. O Asterisk tem a capacidade de inserir essas informações  em diversos bancos de dados, seja ele local ou remoto, mas não tem a capacidade de adivinhar que fizemos um update de segurança em nosso database e o mesmo acabou causando a paralização do serviço. Neste momento iremos perder as estatisticas que estão acontecendo naquela hora e as que estão por vir. Mas nem tudo está perdido, o Asterisk também grava os CDR’s em um arquivo texto chamado Master.csv e para reconstituirmos nosso database pode-se fazer uma engenharia reversa e inseri-los novamente em um nova tabela ou na que acabamos de reparar.

Para isso iremos utilizar um código PHP que faz a leitura do Master.csv e o insere novamente na tabela em questão.

Importando os registros do arquivo Master.csv para o Mysql

Caso seu Asterisk ainda não esteja inserindo os registros das chamadas no banco de dados você poderá fazer isso agora seguindo os passos:

1. Instalar o banco de dados Mysql.  No nosso Treinamento Asterisk Grátis podemos ver como fazer: Instalação e atualização dos pacotes necessários

2. Compilar o pacote asterisk-addons. Veja em: Instalação do Asterisk

3. Criar a database asterisk no Mysql:


# mysql -u root -p
mysql> create database asterisk;
mysql> GRANT ALL PRIVILEGES ON asterisk.* TO 'root'@'localhost' IDENTIFIED BY 'mestre';
mysql> flush privileges;

4. Criar a tabela CDR:


create table cdr (
accountcode varchar (30),
src varchar(64),
dst varchar(64),
dcontext varchar(32),
clid varchar(32),
channel varchar(32),
dstchannel varchar(32),
lastapp varchar(32),
lastdata varchar(64),
calldate timestamp NOT NULL,
answerdate timestamp NOT NULL,
hangupdate timestamp NOT NULL,
duration int(8) unsigned default NULL,
billsec int(8) unsigned default NULL,
disposition varchar(32),
amaflags varchar(128),
uniqueid varchar(128),
userfield varchar(128),
PRIMARY KEY (clid,channel,calldate,uniqueid)
);

Agora que já temos nossa base de dados podemos criar nosso script de importação em PHP

Release: Testado com Mysql 5.0.5, Asterisk 1.6.x e PHP 5.2.6-1
Este script verifica se ja existem registros no banco e garante que os mesmos serão únicos, ou seja, não duplicará registros.

Crie um arquivo chamado importaCDR.php e insira essas linhas:


<?php
/ *** Processo de Importação Master.csv para Mysql)
* Aqui está o que o script faz:
*
* Analisa cada linha de texto e insere no banco de dados após verificar
* os campos "calldate", "src," e "duration" do registro.
* Note que nem todos os campos são testados.
*
* O script só irá inserir novos registros por isso é seguro!
*
* Se você tem um grande banco de dados já existentes é recomendável
* que você adicione um índice para o campo calldate que irá acelerar bastante esta importação.
*/
$locale_db_host = 'localhost';
$locale_db_name = 'asterisk';
$locale_db_login = 'root';
$locale_db_pass = 'mestre';
if($argc == 2) {
$logfile = $argv[1];
} else {
print("Use".$argv[0]." <filename>n");
print("Onde filename é o path do Asterisk csv para importar o (Master.csv)n");
print("Este script pode ser executados varias vezes sobre um arquivo de log crescenten");
exit(0);
}
// connect to db
$linkmb = mysql_connect($locale_db_host, $locale_db_login, $locale_db_pass) or die("Could not connect : " . mysql_error());
mysql_select_db($locale_db_name, $linkmb) or die("Could not select database $locale_db_name");
//** 1) Procura por registros no arquivo de log. **/
$rows = 0;
$handle = fopen($logfile, "r");
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
//** NOTA: Os campos do Master.csv podem variar. Esse script trabalha sobre uma instalação default,mas se você tem campos customizados basta editar a linha abaixo**/
list($accountcode,$src, $dst, $dcontext, $clid, $channel, $dstchannel, $lastapp, $lastdata, $start, $answer, $end, $duration, $billsec, $disposition, $amaflags ) = $data;
/** 2) Teste para verificar se a entrada é única **/
$sql="SELECT calldate, src, duration".
" FROM cdr".
" WHERE calldate='$end'".
" AND src='$src'".
" AND duration='$duration'".
" LIMIT 1";
if(!($result = mysql_query($sql, $linkmb))) {
print("Invalid query: " . mysql_error()."n");
print("SQL: $sqln");
die();
}
if(mysql_num_rows($result) == 0) { // we found a new record so add it to the DB
// 3) Insere cada linha no database
$sql = "INSERT INTO cdr (calldate, clid, src, dst, dcontext, channel, dstchannel, lastapp, lastdata, duration,billsec, disposition, amaflags, accountcode) VALUES('$end', '".mysql_real_escape_string($clid)."', '$src', '$dst','$dcontext', '$channel', '$dstchannel', '$lastapp', '$lastdata', '$duration', '$billsec', '$disposition', '$amaflags','$accountcode')";
if(!($result2 = mysql_query($sql, $linkmb))) {
print("Invalid query: " . mysql_error()."n");
print("SQL: $sqln");
die();
}
print("Inserido: $end $src $durationn");
$rows++;
} else {
print("Não único: $end $src $durationn");
}
}
fclose($handle);
print("$rows importedn");
?>

Pronto, agora que temos nosso banco de dados e script de importação basta executar:

php importaCDR.php Master.csv

NOTA: Eu recomendo que faça uma cópia do arquivo Master.csv e coloque no mesmo diretório que está o script.

DICA: Você também pode criar rotinas de importação utilizando o crontab do linux(agendador de tarefas)

Bom, acho que isso é tudo. Espero que possa ajudar!

Related Posts with Thumbnails

5 Comentarios para “Import Asterisk Master.csv > Mysql”

  1. Muito bom o tutorial.
    Mas tenhu uma dúvida.
    Instalei o banco mySql, criei a tabela (seguindo os passos http://www.voip-info.org/wiki/view/Asterisk+cdr+mysql). Mas qndo realizo ligações elas nao são gravadas no banco.
    Alguma dica?
    configurei também o arquivo cdr_mysql.conf
    Obrigado

  2. Rode no prompt do asterisk o comando cdr mysql status e veja o resultado.

  3. Elton Estevam says:

    Muito bom, vai me ajudar bastante no que estou fazendo, Obrigado.

Deixe um comentario