www.samag.ru
     
Поиск   
              
 www.samag.ru    Web  0 товаров , сумма 0 руб.
E-mail
Пароль  
 Запомнить меня
Регистрация | Забыли пароль?
Журнал "Системный администратор"
Журнал «БИТ»
Подписка
Архив номеров
Где купить
Авторам
Рекламодателям
Контакты
   

  Опросы
  Статьи

Мониторинг  

Какая задача мониторинга отнимает больше всего времени?

Многие системные администраторы тратят до 30% рабочего времени на рутину мониторинга. Но

 Читать далее...

Рынок труда  

Какие навыки вы хотите развивать в 2026 году?

Рынок труда меняется быстро. Еще вчера его называли рынком соискателей, а сегодня

 Читать далее...

Книжная полка  

От сисадмина до архитектора: книги, которые прокачают ваш стек в этом году

Новинки от издательства «БХВ» отличаются тем, что в них часто делается упор

 Читать далее...

Автоматизация  

Автоматизируем рутину: что реально работает?

Многие сисадмины автоматизировали что-то за последний год. Но далеко не все остались

 Читать далее...

Защита ИТ-системы  

Практическая защита: что вы внедрили и что мешает?

Какие меры безопасности реально внедрить в реальных условиях – и что не

 Читать далее...

Вопрос-ответ  

Обеспечиваем безопасную эксплуатацию базы данных

Что для вас чаще всего является причиной инцидентов с БД? Как вы

 Читать далее...

Книжная полка  

От «безопасного» Linux до Контролируемого взлома

Издательство «БХВ» продолжает радовать читателей интересными новинками и в наступившем году. Вы можете

 Читать далее...

1001 и 1 книга  
19.03.2018г.
Просмотров: 13503
Комментарии: 0
Машинное обучение с использованием библиотеки Н2О

 Читать далее...

12.03.2018г.
Просмотров: 13615
Комментарии: 0
Особенности киберпреступлений в России: инструменты нападения и защита информации

 Читать далее...

12.03.2018г.
Просмотров: 11075
Комментарии: 0
Глубокое обучение с точки зрения практика

 Читать далее...

12.03.2018г.
Просмотров: 5936
Комментарии: 0
Изучаем pandas

 Читать далее...

12.03.2018г.
Просмотров: 6784
Комментарии: 0
Программирование на языке Rust (Цветное издание)

 Читать далее...

19.12.2017г.
Просмотров: 6663
Комментарии: 0
Глубокое обучение

 Читать далее...

19.12.2017г.
Просмотров: 9500
Комментарии: 0
Анализ социальных медиа на Python

 Читать далее...

19.12.2017г.
Просмотров: 6107
Комментарии: 0
Основы блокчейна

 Читать далее...

19.12.2017г.
Просмотров: 6322
Комментарии: 0
Java 9. Полный обзор нововведений

 Читать далее...

16.02.2017г.
Просмотров: 10484
Комментарии: 0
Опоздавших не бывает, или книга о стеке

 Читать далее...

17.05.2016г.
Просмотров: 13956
Комментарии: 0
Теория вычислений для программистов

 Читать далее...

30.03.2015г.
Просмотров: 15406
Комментарии: 0
От математики к обобщенному программированию

 Читать далее...

18.02.2014г.
Просмотров: 17731
Комментарии: 0
Рецензия на книгу «Читаем Тьюринга»

 Читать далее...

13.02.2014г.
Просмотров: 12580
Комментарии: 0
Читайте, размышляйте, действуйте

 Читать далее...

12.02.2014г.
Просмотров: 10587
Комментарии: 0
Рисуем наши мысли

 Читать далее...

10.02.2014г.
Просмотров: 8795
Комментарии: 4
Страна в цифрах

 Читать далее...

18.12.2013г.
Просмотров: 7395
Комментарии: 0
Большие данные меняют нашу жизнь

 Читать далее...

18.12.2013г.
Просмотров: 6202
Комментарии: 0
Компьютерные технологии – корень зла для точки роста

 Читать далее...

04.12.2013г.
Просмотров: 5827
Комментарии: 0
Паутина в облаках

 Читать далее...

03.12.2013г.
Просмотров: 6148
Комментарии: 1
Рецензия на книгу «MongoDB в действии»

 Читать далее...

Друзья сайта  

 Создаём систему учета исходящих телефонных звонков

Архив номеров / 2005 / Выпуск №8 (33) / Создаём систему учета исходящих телефонных звонков

Рубрика: Администрирование /  Продукты и решения   | Дополнительные материалы

ДЕНИС СОКОЛОВ

Создаём систему учета исходящих телефонных звонков

Сегодня мы займемся созданием системы учета исходящих телефонных звонков на примере УАТС LG GDK-162. От вас требуется: навыки работы в UNIX-подобных операционных системах, умение программировать на Perl и базовые знания в SQL.

Недавно руководство поставило задачу – необходимо вести учет всех исходящих телефонных звонков. В офисе установлена УАТС LG GDK-162 емкостью 48 внутренних номеров и 8 внешних линий. Различные программы тарификации имеются в избытке. Но ни одна меня не устроила. Большинство из них платные и написаны под Windows, из некоммерческих только SMDR 1.0 поддерживает LG GDK-162.

Для операционных систем Linux и FreeBSD существует очень интересный проект ATSlog: http://www.atslog.dp.ua. Вот описание с сайта программы: «ATSlog предоставляет удобный интерфейс с доступом через веб-браузер для просмотра и анализа звонков различных моделей мини-АТС. Программа бесплатная, распространяется под лицензией GPL, имеет полностью открытый код. Программа успешно работает с моделями Panasonic KX-TA308, KX-TA308RU, KX-TA616RU, KX-TD816RU, KX-TD1232; Samsung SKP-816». К сожалению, не нашел в списке поддерживаемых АТС LG GDK. Для добавления поддержки нужной модели можно отослать автору образцы текстовых лог-файлов. Но это требует времени. Я решил попробовать справиться с задачей своими силами. Это оказалось несложным. Надеюсь, что мой опыт окажется вам полезен.

Рисунок 1. Схема учета исходящих телефонных звонков

Рисунок 1. Схема учета исходящих телефонных звонков

LG GDK-162, как и большинство офисных АТС, можно подключить к компьютеру через порт RS-232. Параметры порта: 9600 бит/с, 8 бит данных, без контроля паритета, 1 стоповый бит.

Таблица 1. Распайка кабеля (стандартный нуль-модем)

PBX (9 pin)

PC (9 pin)

PC (25 pin)

2 (TX)

2 (RX)

3 (RX)

3 (RX)

3 (TX)

2 (TX)

5 (GND)

5 (GND)

7 (GND)

Я подключился к последовательному порту УАТС при помощи терминальной программы и стал анализировать считываемые данные. Оказалось, что LG GDK-162 протоколирует свою работу в режиме реального времени, а записи об исходящих звонках выглядят следующим образом:

1035 144 06      00:11 21/08/2005 16:21  O1234567    **

Рассмотрим её содержимое:

  • первое поле – порядковый номер записи;
  • второе – номер станции, с которой сделан вызов;
  • третье – номер внешней линии;
  • четвертое – длительность звонка (mm:ss);
  • пятое – дата;
  • шестое – время (hh:mm);
  • седьмое – вызванный номер с ведущим символом O. Седьмое поле может кроме цифр содержать символы «#» и «*» – это происходит при звонках на голосовые шлюзы операторов IP-телефонии.

Таким образом, задача учета исходящих телефонных звонков свелась к написанию программы для считывания журнала работы УАТС через порт RS-232, обработки и сохранения соответствующих записей. Можно приступать к реализации.

Исходные данные: учет будет осуществляться на машине Cel 1200/RAM 128 Мб/HDD 20 Гб, операционная система – Debian GNU/Linux 3.1r Sarg, СУБД – PostgreSQL v. 7.4.7, УАТС подключена к последовательному порту /dev/ttyS1.

Создадим пользователя, от которого будет работать программа и рабочий каталог. Кроме этого, изменим права доступа к /dev/ttyS1:

# sudo useradd -d /var/gdklog -s /bin/sh gdk

# sudo passwd gdk

# sudo mkdir /var/gdklog

# sudo chown gdk:gdk /var/gdklog

# sudo chown root:gdk /dev/ttyS1

# sudo chmod 640 /dev/ttyS1

Создадим пользователя и базу данных в PostgreSQL:

# createuser -U postgres -A -D gdk

# createdb -U postgres -O gdk pbxbilling

Создадим таблицу gdklog для хранения статистики. Таблица имеет пять полей:

  • d_time – дата и время;
  • station – станция;
  • line – внешняя линия;
  • t_call – продолжительность разговора;
  • c_number – вызванный номер (я выбрал для этого поля тип numeric, т.е. номер телефона сохраняется, как число, при этом ведущие нули усекаются, например, номер 01 сохранится в БД как 1).

# vi gdklog.sql

CREATE TABLE gdklog (

    "d_time"            timestamp,

    "station"           int2,

    "line"       int2,

    "t_call"            time,

    "c_number"   numeric (30, 0)

);

REVOKE ALL on "gdklog" from PUBLIC;

GRANT ALL on "gdklog" to "gdk";

# psql -U gdk -d pbxbilling < gdklog.sql

Писать программу учета я решил на perl. Полный текст вы можете скачать с сайта www.samag.ru, раздел «Исходный код». Для чтения данных из последовательного порта вполне подойдут стандартные функции для работы с файлами. Естественно, порт необходимо предварительно настроить. Для этого я использовал вызов программы sty:

my $ttys = "/dev/ttyS1";

# Количество строк журнала, кэшируемых в памяти

my $m_cache = 50;

system ("/bin/stty -F $ttys 9600 cs8 -parenb -cstopb");

# Читаем данные из последовательного порта

open (TTYS, "< $ttys") or die "Can’t open $ttys!";

while (<TTYS>)

{

    parse_log;

}

Функция parse_log – единственная в программе, специфичная для LG GDK-162.

sub parse_log

{

# Если массив log содержит m_cache строк, то заносим данные в БД

if (@log >= $m_cache)

{

           push_to_db;

}

    # Отбираем строки фиксирующие исходящие звонки

    if (/O\d+/)

    {

           # Удаляем символы *, #, O

           s/[\*,O,\#]+//g;

           # Сохраняем полученную строку в массив log

           push (@log, $_);

}

print;

}

Допустим, надо добавить поддержку АТС, пишущую протокол в формате:

2005-08-21 16-21-00 06 1234567 00:00:11 144

Для этого достаточно будет дописать еще одну конструкцию if в функцию parse_log (кроме этого, надо не забыть проверить параметры последовательного порта).

if (/^(d{4}-d{2}-d{2})s+(d{2}-d{2}-d{2})s+(d{2})s+(d+)s+(d{2}:d{2}:d{2})s+

{

    push (@log, "00 $6 $3 $5 $1 $2 $4");

}

Постоянно держать открытым соединение с базой данных – не очень хорошая идея. Поэтому все строки, соответствующие регулярному выражению «/Od/g» (журнал исходящих вызовов), сначала заносятся в массив @log. Как только в нем накапливается $m_cache строк – вызывается процедура push_to_db, которая устанавливает соединение с базой pbxbilling и записывает данные в таблицу gdklog:

# $d_time        // Дата и время

# $station       // Внутренний номер

# $line          // Внешняя линия

# $t_call        // Продолжительность вызова

# $date          // Дата

# $time          // Время

# $c_number      // Вызванный номер

my ($d_time, $station, $line, $t_call, $date,

    $time, $c_number, @log);

# Параметры соединения с базой данных

my $base = "pbxbilling";

my $user = "gdk";

my $pass = "";

sub push_to_db

{

    # Подготовка соединения

    my $dbh=DBI->connect("DBI:Pg:dbname=$base",

          "$user", "$pass",

           {PrintError => 0, RaiseError => 0}

    ) or return 2;

    # Подготовка запроса

    my $ins = $dbh->prepare(q{

           INSERT INTO gdklog (d_time , station, line, t_call, c_number)

           VALUES (?, ?, ?, ?, ?)

    });

    # Перебираем в цикле все сохраненные строки

    foreach my $log (@log)

    {

           # Разбираем строку

           (undef, $station, $line, $t_call, $date, $time, $c_number) = split (/\s+/, $log);

           if (length ($t_call) < 6)

           {

                 $t_call="00:$t_call";

           }

           $d_time = "$date $time";

           # Выполняем INSERT

           $ins->execute($d_time, $station, $line, $t_call, $c_number)

                 or return 2;

    }

    # Очистим массив

    undef (@log);

    $dbh->disconnect();

    return 0;

}

Кроме этого, мне нужно было, чтобы программа могла работать в режиме демона:

# В режиме демона в этот файл перенаправляем все сообщения об ошибках

my $err_file = "/var/gdklog/gdklogd.err";

# PID-файл

my $pid_file = "/var/gdklog/gdklogd.pid";

sub begin_daemon

{

    # Делаем fork

    my $pid = fork;

    exit if $pid;

           die "Couldn’t fork: $!" unless defined($pid);

    # Сохраняем PID в файл

    open (F_PID, ">$pid_file") or die "Can’t open $pid_file: $!";

    print F_PID "$$\n";

    close F_PID;

    # Перенаправляем вывод STDERR  в файл

    open (*STDERR, ">> $err_file") or die "Can’t reopen *STDERR to $err_file: $!";

    # Перенаправляем STDIN и STDOUT в /dev/null

    for my $handle (*STDIN, *STDOUT)

    {

           open ($handle, "> /dev/null") or die "Can’t reopen $handle to /dev/null: $!";

    }

    # Установка sid процесса

    POSIX::setsid()

           or die "Can’t start a new session: $!";

}

Чтобы обеспечить целостность данных, я установил обработчики сигналов INT и TERM. Получая один из них, программа будет пытаться немедленно записать данные в базу, если это окончится неудачей (например, сервер БД отключен), то выполнится процедура dump_to_file, которая просто запишет содержимое @log в текстовый файл. После этого работа программы будет завершена. Второй обработчик добавляет возможность записи данных в базу по  сигналу HUP без выхода из программы.

$SIG{INT} = $SIG{TERM} = sub { dump_to_file if push_to_db; exit };

$SIG{HUP} = sub { dump_to_file if push_to_db };

Меняем владельца и права доступа:

# sudo chown root:gdk /usr/local/sbin/gdklogd

# sudo chmod 750 /usr/local/sbin/gdklogd

Напишем стартовый сценарий:

# vi /etc/init.d/gdklogd

#!/bin/sh

DAEMON=/usr/local/sbin/gdklogd

DAEMONFLAGS="-D"

KILL=/bin/kill

PID=/var/gdklog/gdklogd.pid

CAT=/bin/cat

SU=/bin/su

start ()

{

    echo -n $"Starting $DAEMON: "

    # Запуск с правами непривилегированного пользователя

    $SU -c "$DAEMON $DAEMONFLAGS" gdk 2>/dev/null 1>&2

}

stop ()

{

    echo -n $"Stopping $DAEMON: "

    $KILL `$CAT $PID` 2>/dev/null 1>&2

}

case "$1" in

start)  

    start

    ;;

stop)   

    stop

    ;;

restart)

    stop

    start

    ;;

*)          

    echo $"Usage: $0 {start|stop|restart}"

    exit 1

esac

# sudo chown root:root /etc/init.d/gdklogd

# sudo chmod 700 /etc/init.d/gdklogd

Запустим:

# sudo /etc/init.d/gdklogd start

После запуска сценария с параметром -D он переходит в режим демона, настраивает последовательный порт и начинает считывать из него данные. При запуске без параметра -D сценарий не отсоединяется от терминала, а записи об исходящих звонках дублируются на экран.

Если все сделано правильно, то через некоторое время таблица gdklog начнет заполняться записями.

# sudo kill –HUP `cat /var/gdklog/gdklogd.pid`

# psql -c "SELECT * FROM gdklog;" -U gdk pbxbilling

       d_time        | station | line |  t_call  | c_number

---------------------+---------+------+----------+----------

 2005-08-21 16:21:00 |     144 |    6 | 00:00:11 |  1234567

(1 запись)

Вот и все. При минимуме усилий мы получили вполне работоспособную и переносимую систему учета исходящих звонков УАТС LG GDK-162. Работа скрипта проверялась на Debian GNU/Linux 3.1r Sarg и FreeBSD 5.2.1 (надо изменить только имя файла последовательного порта $ttys). Модуль DBI позволяет использовать любую поддерживаемую им СУБД с минимальной правкой кода, а также доступ к базе данных по сети. Для получения отчетов к нашим услугам вся мощь SQL. Несложно добавить поддержку других моделей УАТС. А при наличии свободного времени можно написать веб-интерфейс.

Успехов!


Комментарии
 
  20.09.2006 - 02:15 |  anonymous

где статья??

  20.09.2006 - 02:37 |  admin

Так вот же она.

  25.09.2006 - 05:48 |  nobody

Вообще-то, не во всех браузерах всё отображается корректно. Напримеру меня в Opera 7.10 под win саму статью не видно (только заголовок). Видимо, это и имел в виду anonymous. Проблема решается щелчком на "версия для печати".

  29.09.2006 - 09:24 |  admin

Понятно. Это фрэймы шалят.

Добавить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

               Copyright © Системный администратор

Яндекс.Метрика
Tel.: (499) 277-12-45
E-mail: sa@samag.ru