/ #linux 

IP-телефонія на базі Asterisk. Частина 5: Деталізований звіт про виклики (Call Detail Records, CDR)

Цикл статей по розгортанню IP-телефонії на базі Asterisk. Фактично це моя проектна робота на отримання відповідного сертифікату одного з навчальних центрів. Робота була захищена, сертифікат отриманий, все написане тестувалось і є повтінстю робочою реалізацією. Інформація в статті і версії програмного забезбечення актуальні на 2017 рік.

5. Деталізований звіт про виклики (Call Detail Records, CDR)

Налаштуємо зберігання статистики в БД MySQL.

Встановимо MySQL:

wget https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm
rpm -ivh mysql57-community-release-el7-11.noarch.rpm
yum install mysql-server

Оскільки будемо використовувати для перегляду статистики дзвінків веб-застосунок CDR Viewer, то встановлюємо і налаштовуємо веб-сервер:

cd /usr/src/
wget https://nginx.org/download/nginx-1.13.0.tar.gz
tar vxfz nginx-1.13.0.tar.gz 
cd nginx-1.13.0/
./configure 
make && make install
useradd -r nginx
ln -s /usr/local/nginx/conf/ /etc/nginx
ln -s /usr/local/nginx/sbin/nginx /usr/sbin/nginx
wget -O /etc/init.d/nginx https://gist.github.com/sairam/5892520/raw/b8195a71e944d46271c8a49f2717f70bcd04bf1a/etc-init.d-nginx
chmod +x /etc/init.d/nginx

Створюємо файл /lib/systemd/system/nginx.service:

[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target
Запускаем сервер:
systemctl enable nginx
systemctl start nginx
[root@asterisk-centos conf]# nginx -V
nginx version: nginx/1.13.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC) 

Встановлюємо php:

yum install php-fpm
systemctl start php-fpm

Налаштовуємо веб-сервер:

user  nginx;
worker_processes  1;
error_log  logs/error.log;
pid        /run/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  192.168.1.201;
	  root /var/www;
        location / {
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
        location ~* \.php$ {
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_pass 127.0.0.1:9000;
            try_files $uri @yii =404;
        }
    }
}

Для роботи з CDR забезпечуємо коректну синхронізацію часу на сервері

yum install ntp
systemctl enable ntpd
service ntpd restart

Встановлюємо програму для керування БД:

cd /var/www/
wget https://github.com/vrana/adminer/releases/download/v4.3.1/adminer-4.3.1-mysql.php -O adminer.php

Входимо в adminer за адресою http://192.168.1.201/adminer.php, створюємо базу asteriskcdr і користувача з правами запису в цю базу - asteriskuser, а також таблицю для зберігання даних:

CREATE TABLE `cdr` (
  `id` int(11) unsigned NOT NULL auto_increment,
  `calldate` datetime NOT NULL default '0000-00-00 00:00:00',
  `clid` varchar(80) NOT NULL default '',
  `src` varchar(80) NOT NULL default '',
  `dst` varchar(80) NOT NULL default '',
  `dcontext` varchar(80) NOT NULL default '',
  `channel` varchar(80) NOT NULL default '',
  `dstchannel` varchar(80) NOT NULL default '',
  `lastapp` varchar(80) NOT NULL default '',
  `lastdata` varchar(80) NOT NULL default '',
  `duration` int(11) NOT NULL default '0',
  `billsec` int(11) NOT NULL default '0',
  `start` datetime NULL default NULL,
  `answer` datetime NULL default NULL,
  `end` datetime NULL default NULL,
  `disposition` varchar(45) NOT NULL default '',
  `amaflags` int(11) NOT NULL default '0',
  `accountcode` varchar(20) NOT NULL default '',
  `uniqueid` varchar(32) NOT NULL default '',
  `userfield` varchar(255) NOT NULL default '',
  PRIMARY KEY  (`id`),
  KEY `calldate` (`calldate`),
  KEY `accountcode` (`accountcode`),
  KEY `uniqueid` (`uniqueid`),
  KEY `dst` (`dst`),
  KEY `src` (`src`)
);

Відкриваємо файл /etc/asterisk/cdrmysql.conf і налаштовуємо підключення до MySQL:

[global]
hostname=localhost
dbname=asteriskcdr
table=cdr
password=asterisk_password
user=asterisk_user
port=3306

В файлі /etc/asterisk/cdr.conf відключаємо стандартне логування дзвінків в csv-файл:

;[csv]
;usegmtime=yes    ; log date/time in GMT.  Default is "no"
;loguniqueid=yes  ; log uniqueid.  Default is "no"
;loguserfield=yes ; log user field.  Default is "no"
;accountlogs=yes  ; create separate log file for each account code. Default is "yes"

Перезапустимо Asterisk:

service asterisk restart

Встановлюємо CDR Viewer:

cd /var/www/html
wget https://github.com/g613/asterisk-cdr-viewer/raw/master/asterisk-cdr-viewer-latest.tgz
tar xzfv asterisk-cdr-viewer-latest.tgz

В файлі include/config.inc.php налаштовуємо підключення до БД:

$db_type = 'mysql';
$db_host = 'localhost';
$db_port = '3306';
$db_user = 'asterisk_user';
$db_pass = 'asterisk_password';
$db_name = 'asteriskcdr';
$db_table_name = 'cdr';
$db_options = array();

В файлі /etc/extension.conf расширюємо макрос запису дзвінків для можливості роботи з БД:

;MixMonitor
[macro-recording]
exten => s,1,GoToIf($["${RECORDING}" = "1"]?yes:no);
exten => s,n(yes),Set(fname=${STRFTIME(${EPOCH},,%Y)}/${STRFTIME(${EPOCH},,%Y-%m)}/${STRFTIME(${EPOCH},,%Y-%m-%d)}/${UNIQUEID}-${STRFTIME(${EPOCH},,%Y-%m-%d-%H_%M)}-${ARG1}-${ARG2})
exten => s,n,Set(fname=${STRFTIME(${EPOCH},,%Y)}/${STRFTIME(${EPOCH},,%Y-%m)}/${STRFTIME(${EPOCH},,%Y-%m-%d)}/${UNIQUEID}-${STRFTIME(${EPOCH},,%Y-%m-%d-%H_%M)}-${ARG1}-${ARG2})
exten => s,n,Set(DIR_RECORDS=/var/spool/asterisk/monitor/)
exten => s,n,NoOp(Dir  - ${STRFTIME(${EPOCH},,%Y)}/${STRFTIME(${EPOCH},,%Y-%m)}/${STRFTIME(${EPOCH},,%Y-%m-%d)})
exten => s,n,Set(monopt=nice -n 19 /usr/local/bin/lame -b 32  --silent "${DIR_RECORDS}${fname}.wav"  "${DIR_RECORDS}${fname}.mp3" && rm -f "${DIR_RECORDS}${fname}.wav" && chmod o+r "${DIR_RECORDS}${fname}.mp3");
exten => s,n,Set(CDR(filename)=${fname}.mp3);
exten => s,n,Set(CDR(realdst)=${called});
exten => s,n,MixMonitor(${DIR_RECORDS}${fname}.wav,b,${monopt});
exten => s,n(no),Verbose(Exit record);

Здійснюємо кілька дзвінків і перевіряємо роботу CDR Viewer.

В наступній статті поговоримо про додаткові функції Asterisk.

Author

Олександр Бобилєв

Залишаю собі право використовувати ненормативну (але інформативну) лексику там, де звичайні слова втрачають сенс і не відображають всієї палітри почуттів, від споглядання навколишньої дійсності.