Как лучше реализовать парсинг журнала событий (операции в системе обслуживания клиентов)?
Есть достаточно подробный журнал (лог) событий из некого приложения для обслуживания клиентов организации (грубо говоря, пришел клиент - оператор его обслужил и отразил операцию в приложении). Сам журнал неплохо структурирован - из каждой записи легко извлекается дата/время события, пользователь системы, описание события и т.д. Описание содержит самый различный текст от "пользователь такой-то вошел в систему" до "пользователь произвел такую-то операцию с такими-то параметрами, результат операции такой-то", причем само описание операции не имеет какого-то единого формата, так как фактически есть несколько подсистем с разным функционалом, которые пишут лог в один файл (отметка о подсистеме в логе тоже присутствует). По предварительной оценке в журнале хранится порядка нескольких сотен различных типов записей. Объем самого журнала - сотни тысяч записей.
С точки зрения пользователя одно его действие (к примеру "оплата услуги") в системе порождает в журнале одну или сразу несколько отдельных записей в журнале (к примеру "вход в подсистему", "выбор объекта", "попытка операции", "подтверждение", "результат"). Для какого-то конкретного действия набор операций и их последовательность на 100% не зафиксирована, возможны небольшие вариации. Теперь моя задача - распознать в журнале действия пользователей в системе, определить их длительность, и отнести распознанное действие к одной из групп действий с одинаковой/похожей последовательностью записей в журнале.
Уточнения:
1. Для каждого действия пользователя ( а вариантов действий достаточно много, и у меня сейчас даже нет их исчерпывающего списка) набор записей в журнале имеет некоторую вариативность, например, в процессе совершения операции оператор ошибся, или клиент отказался. Но на первом этапе вариативностью можно пренебречь.
2. Я привел пример набора записей одного действия пользователя просто для понимания структуры журнала, на самом деле у разных действий пользователя могут быть наборы записей, совсем не похожие на мой пример, и мне они заранее неизвестны. Соответственно надо как-то автоматизированным способом определить конечный набор повторяющихся последовательностей записей, встречающихся в журнале.
Прошу дельный совет - с какой стороны подойти к этой задаче, и описать свое видение алгоритма решения.
Что-то не понятно в чём загвозка, если вам не нужно всё разбирать, а определить только длительность. У вас есть чётко "вход в подсистему" - начало и "результат", "ошибка" или следующий "вход в подсистему" как конец. Или я что-то не уловил?
freeExec,
Я, возможно, не совсем корректно написал вопрос. Мне надо не только определить длительность, но и определить, какое конкретно действие пользователем совершено.
То есть на выходе у меня должен быть другой журнал:
дата/время, пользователь, действие, длительность.
Для меня в построении четкого алгоритма решения трудность составляют вот эти проблемы:
1. Для каждого действия пользователя ( а вариантов действий достаточно много, и у меня сейчас даже нет их исчерпывающего списка) набор записей в журнале имеет некоторую вариативность, например, в процессе совершения операции оператор ошибся, или клиент отказался.
2. Я привел пример набора записей одного действия пользователя просто для понимания структуры журнала, на самом деле у разных действий пользователя могут быть наборы записей, совсем не похожие на мой пример.
Тогда я не вижу никаких вариантов, кроме как вы описываете всё возможно дерево вариантов и пытаетесь текущую последовательность на него натянуть с вариантами возврата назад и ошибок.
freeExec, В первом приближении, видимо, так. Я рассчитывал максимально автоматизировать весь процесс. Описывать каждое действие вручную с учетом вариативности я уже попробовал - долго и результат не стопроцентный. Это как пытаться написать алгоритм игры в шахматы, для каждого возможного хода создавая отдельное условие. Возможно, есть класс близких задач из областей Big Data/машинное обучение, и можно подобрать уже существующее решение.
Как я уже написал ранее, основная проблема не в обработке исходных данных, как таковых - журнал в текущем виде можно без проблем загрузить в любую СУБД. Вопрос в обнаружении повторяющихся последовательностей идущих друг за другом записей в журнале, причем я сейчас не знаю все существующие в журнале повторяющиеся последовательности. Немного подробнее в комментариях выше. Какой для этого подойдет алгоритм, можно ли его реализовать на SQL - я не знаю.
lumaxy, нужно начать с графа действий - это записать все действия в виде узлов, соединённых векторами - возможными связями. Например, от события "оплата услуги" будет идти стрелка к событию "вход в подсистему". Этот граф можно будет использовать для того, чтобы определить длительность действия. Например, если действие начинается в момент "оплата услуги", то условие его окончания - это самое позднее из событий, подчинённых первому (главному). В этом случае можно даже говорить об иерархии событий. Тогда длительность любого родительского события будет примерно равна разнице во времени первого и последнего подчинённого события.
Alexey Epsilon, Как способ хранения описания действий и некого представления журнала с учетом задачи - выглядит достаточно удобно.По грубой оценке в журнале может быть несколько сотен уникальных видов действий, каждое со своей последовательностью записей, и ловить их вручную по журналу достаточно трудоемко. Хотелось бы автоматизировать поиск повторов, но пока мысль о том, как это сделать на предлагаемом графе, от меня ускользает :)
lumaxy, есть два способа построить граф последовательностей.
Первый - знать как работает система и в каком порядке она может вызывать те или иные события.
Второй - проанализировать весь журнал, собрать статистику (что за чем обычно идёт) и на основании этих данных построить граф.
Чудес не бывает, и если у вас есть просто большой лог без информации как он был получен, то придётся потратить существенное количество усилий на его систематизацию.
Alexey Epsilon, Если идти по второму пути, то как раз алгоритм накопления такой статистики меня и интересует. То есть опять мы приходим к задаче поиска повторов в упорядоченной последовательности, решения которой у меня нет.
lumaxy, нужно идти по списку от начала до конца. И, встретив, например, событие "оплата услуги", создавать для него объект в статистическом массиве. Далее необходимо каждую следующую запись сопоставлять со списком уже созданных объектов, и сохранять связь "предыдущее-следующее". Таким образом на первом уровне анализа у нас будет что-то вроде
24 события "оплата услуги", за ним следующее событие
в 12 случаях - "вход в систему"
в 8 случаях - "звонок в Sales"
Так у нас уже есть 3 связанных кружочка.
Далее можно выяснить, что между "вход в систему" тоже есть связь к "звонок в Sales". И выяснить, что в большинстве случаев "просмотр документации" не следует ни за одним из событий, подчинённых событию "оплата услуги".
В общем, это всё решаемо. Нужно усидчиво сидеть и анализировать. Ну или нанять понимающего фрилансера.
Alexey Epsilon, В общем-то на бытовом уровне идея понятна, но пока есть сомнения в том, что длительность анализа журнала таким путем будет разумной, так как предполагается многократный проход по всему журналу. Хотя, возможно, что по другому никак. С фрилансером вариант исключен :)
Нашел интересный инструмент для работы с последовательностями - суффиксное дерево, похоже, что его можно использовать для поиска повторов.