Leksnsk
@Leksnsk

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

Добрый день.

Есть задача понять количество одновременных вызовов в определенную минуту времени имея логи вида:

11:02:25 250
11:02:14 60
11:03:08 33
11:03:10 99

Где 11:02:25 время соединения, 250 - длительность.
Естественно логов очень много, более 500 в минуту может быть. Решения типа Exel не подходят. Хотелось бы автоматизировать с помощью bash или python. На выходе надо иметь число - например, 5 одновременных в минуту 11:02.
  • Вопрос задан
  • 1252 просмотра
Решения вопроса 1
angru
@angru
интересная задачка, у меня получилось как-то так. решал для себя, но вдруг пригодится:

# -*- coding: utf-8 -*-
from pprint import pprint
from datetime import datetime, timedelta
from collections import defaultdict


INTERVAL = 15


assert 0 < INTERVAL <= 60, "алгоритм работает не совсем корректно при значениях интервала больше 60"


def get_time_list(start, end, interval):
    """
        Список "времен" в которые попадает звонок
    """
    t = start + timedelta(seconds=(interval - ((start.second % interval) or interval)))  # стартовое время в которое попадает звонок с учетом интервала
    res = []

    while t.time() <= end.time():  # используем .time() т.к. если сравнивать datetime можно перейти на следующий день
        res.append(t.time().isoformat())

        t = t + timedelta(seconds=interval)

    return res


with open('calls.log', 'r') as f:
    res = defaultdict(int)

    for line in f.readlines():
        start_time, duration = line.split()
        start_time = datetime(1, 1, 1, *map(int, start_time.split(':')))  # используем datatime вместо time, потому что к time нельзя прибавить timedelta
        end_time = start_time+ timedelta(seconds=int(duration))
        time_list = get_time_list(start_time, end_time, INTERVAL)

        for t in time_list:
            res[t] += 1

    pprint(res)


результат на вашем наборе:

{'11:02:15': 1,
'11:02:30': 2,
'11:02:45': 2,
'11:03:00': 2,
'11:03:15': 3,
'11:03:30': 3,
'11:03:45': 2,
'11:04:00': 2,
'11:04:15': 2,
'11:04:30': 2,
'11:04:45': 2,
'11:05:00': 1,
'11:05:15': 1,
'11:05:30': 1,
'11:05:45': 1,
'11:06:00': 1,
'11:06:15': 1,
'11:06:30': 1}
Ответ написан
Пригласить эксперта
Ответы на вопрос 4
@asdz
Преобразуете список звонков в список содержащий 2 поля - время, тип события. Типов события два - начало звонка, завершение звонка. Сортируете этот список по столбцу времени. Проходите последовательно по этому списку и в счетчик заносите +1 если событие начала звонка, и -1 если завершение звонка. Сравниваете значение счетчика с предыдущим значением, сохраняете максимум и время соответсвующего события. Так можно находить максимумы не только в пределах суток, но и в любом диапазоне времени.
Ответ написан
saboteur_kiev
@saboteur_kiev
software engineer
Я бы такое сделал на перл или питон, но не на баш. Большой массив и неудобно с кроссплатформенностью.

Просто проходите по всем строкам и инкрементируете в массиве, разбитом по минутам, все ваши звонки.
Затем в конце формируете отчет по массиву.
Ответ написан
Комментировать
Могу отдать свой старый исходник на Делфи и скомпилированный код именно под эту задачу.
Только в ответе будет максимальное одновременное количество занятых линий в минуту/час.
Если интересно - укажите e-mail
Ответ написан
"Логи" лучше сразу сохранять в СУБД, если это возможно. Скажем, если какая-то программа выводит данные в stdout, то другой программой можно собирать их и сразу записывать в SQLite/MySQL.
Допустим, так: call_center | sql_collector.
А аналитика сама "приклеется", имея механизм доступа к БД.

Пишется несложный SELECT запрос c использованием GROUP BY, COUNT. Затем полученную выборку анализирует умная программа-анализатор.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы