...
Описание работы HMED-C
HMED-C (Hydra Mediation — Collector) занимается сбором и парсингом первичным разбором CDR для последующей передачи их на обработку в ядро предбиллинга (HMED-M).
Обработка проходит несколько этапов:
- Получение CDR — производится с помощью коллекторов. Для одного типа коллектора можно задать несколько спецификаций. Каждая спецификация коллектора связана с парсером для передачи ему на разбор полученных CDR.
- Разбор CDR — производится парсерами. Для одного типа парсера можно задать несколько спецификаций.
- Отправка обработанной CDR в выходную очередь, которая является входной для HMED-M. Имеется возможность задать несколько выходных очередей. В случае, если CDR была разобрана с ошибкой, она отправляется в отдельные выходные очереди.
Основные настройки
Помимо общих настроек доступны следующие параметры:
Code Block |
---|
# настройки точек назначения обработанных CDR
destinations:
amqp:
mediation:
# выходная очередь обработанных CDR во входную очередь HMED-M
# значение должно совпадать со значением настройки sources.amqp.mediation.consumer в конфигурации HMED-M
producer: amqp/mediation
error:
# выходная очередь CDR, обработанных с ошибкой
producer: amqp/error
# выходы для разобранных CDR
handlers:
default:
destinations:
# список выходных очередей CDR; задаются из точек назначения, описанных в секции destinations, в формате тип/спецификация
- amqp/mediation
error:
destinations:
# список выходных очередей CDR, обработанных с ошибкой
- amqp/error
# обрабатывающие процессы
workers:
# процесс collector реализует файловый коллектор со спецификацией switch
# спецификации коллекторов задаются в секции collectors, описанной ниже
- collector: file/switch |
Настройка сбора CDR из файлов
Предположим, АТС настроена таким образом, что сохраняет CDR в файлах CDR, поступающие с АТС, сохраняются в файлы с именем в формате cdr_12345.log в директории /tmp/cdr.
В таком случае коллектор нужно настроить следующим образом:
Code Block | ||
---|---|---|
| ||
collectors: # файловые коллекторы file: # спецификация коллектора switch: # спецификация парсера для разбора прочитанных CDR parser: plain/switch_2 # спецификации путей к файлам CDR paths: - directory: /tmpvar/cdr/ # путь к файлам с CDR filename_pattern: ^cdr_\d+\.log$ # регулярное выражение, соответствующее формату имени файлов с CDR |
...
Коллектор реагирует на событие create файловой системы, таким образом обработка файла с CDR начинается немедленно после его создания.
Настройка парсинга CDR
Допустим, файл с CDR имеет следующий вид:
Code Block | ||
---|---|---|
| ||
C2905117 4999224453 C2505821 84997242904 31-01-12 18:58:10 4 16
C2905111 4999224453 C2505808 84957491303 31-01-12 18:56:25 108 16
C2905118 4999224453 C2505822 84952589899 31-01-12 18:58:12 0 21 |
Каждая CDR начинается с новой строки и содержит поля: транк А, номер А, транк Б, номер Б, дата и время звонка, кол-во секунд и код причины завершения вызова.
Для разбора файла такого вида используются следующие параметры конфигурации:
Code Block | ||
---|---|---|
| ||
parsers: plain: # спецификация парсера switch_2: cdr_delimiter: "\n" # разделитель между CDR в файле (новаясимвол строкановой строки) preprocessors: # предобработчики строки перед разбором - type: trim # обрезание краевых символов direction: left # край строки, возможные значения: left, right, both char: ' ' # символ - type: substring # взятие подстроки ('test' -> 'es') begin: 1 # начальная позиция (будет обрезан первый символ строки) end: -1 # конечная позиция (значение -1 означает, что подстрока будет взята до предпоследнего символа строки) records: - matcher: # регулярное выражение для разбора CDR на поля # 1 2 3 4 5 6 7 # trk_a station_a trk_b station_b day month year hour minute second dur status pattern: ^(\w+) (\d+|-)[^\s]* (\w+) (\d+)[^\s]* (\d{2}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) (\d+) (\d+)$ fields: map: # соответствие полей CDR и строки, разобранной регулярным выражением # первое поле $g1, второе $g2 и т.д. # подстановка $g0 содержит всю строку trunk_a: $g1 station_a: $g2 trunk_b: $g3 station_b: $g4 call_datetime: $g5 duration_sec: int($g6) # приведение к целому числу termination_code: $g7 - matcher: min_length: 50 # для тех CDR, которые не удовлетворяют первому регулярному выражению и имеют длину >= 50 символов fields: delimiter: '\s+' # используем разделитель для получения полей (поддерживаются регулярные выражения) map: trunk_a: $f1 # первое поле в массиве строк после разбиения исходной строки station_a: $f2 # второе поле и т. д. trunk_b: $f3 station_b: $f4 call_datetime: $f5 duration_sec: int($f6) termination_code: $f7 entire_cdr: $f0 # в переменной $f хранится вся строка с CDR |
Таким образом на выходе коллектора получатся разобранные CDR в формате JSON вида:
Code Block | ||
---|---|---|
| ||
[
{trunk_a: 'C2905117',
station_a: '4999224453',
trunk_b: 'C2505821',
station_b: '84997242904',
call_datetime: '31-01-2012 18:58:10',
duration_sec: 4,
termination_code: '16'},
...
] |