Интеллектуальное «Вычитание» одного текстового лог-файла из другого

360
Vi.

Пример: приложение генерирует большой текстовый файл журнала Aсо многими различными сообщениями. Он генерирует такой же большой файл журнала, Bкогда не работает правильно.

Я хочу видеть, какие сообщения в файле Bпринципиально новые, т.е. отфильтровывать все A.

Тривиальный прототип это:

  1. Сортировать | uniq оба файла
  2. Присоединяйтесь к файлам
  3. сортировать | uniq -c
  4. grep -v "^ 2"

Это дает симметричную разницу и неудобно. Как сделать это лучше? (включая несимметричную разность и сохранение порядка сообщений в B)

Программа должна сначала проанализировать Aи узнать, какие сообщения являются общими, а затем проанализировать Bпоказ с сообщениями, требующими внимания.

В идеале он должен автоматически игнорировать такие вещи, как метки времени, номера строк или другие изменчивые вещи.

Пример. A:

0:00:00.234 Received buffer 0x324234 0:00:00.237 Processeed buffer 0x324234 0:00:00.238 Send buffer 0x324255 0:00:03.334 Received buffer 0x324255 0:00:03.337 Processeed buffer 0x324255 0:00:03.339 Send buffer 0x324255 0:00:05.171 Received buffer 0x32421A 0:00:05.173 Processeed buffer 0x32421A 0:00:05.178 Send buffer 0x32421A 

B:

0:00:00.134 Received buffer 0x324111 0:00:00.137 Processeed buffer 0x324111 0:00:00.138 Send buffer 0x324111 0:00:03.334 Received buffer 0x324222 0:00:03.337 Processeed buffer 0x324222 0:00:03.338 Error processing buffer 0x324222  0:00:03.339 Send buffer 0x3242222 0:00:05.271 Received buffer 0x3242FA 0:00:05.273 Processeed buffer 0x3242FA 0:00:05.278 Send buffer 0x3242FA 0:00:07.280 Send buffer 0x3242FA failed 

Результат:

0:00:03.338 Error processing buffer 0x324222  0:00:07.280 Send buffer 0x3242FA failed 

Одним из способов ее решения может быть что-то вроде этого:

  1. Разделить каждую строку логических единиц: 0:00:00.134 Received buffer 0x324111, 0:00:00.134, Received, buffer, 0x324111, 324111, Received buffer, \d:\d\d:\d\d\.\d\d\d, \d+:\d+:\d+.\d+, 0x[0-9A-F], ... Он должен найти отдельные слова, простые узоры в цифрах, общие схемы (например, «некоторые даты, чем текст, чем многочисленнее текст, чем end_of_line»), а также обрабатывать комбинации выше. Поскольку это непростая задача, помощь пользователя (добавление регулярных выражений с явным «игнорировать это», «сделать основной фактор», «не разбивать на части», «считать датой / числом», «заботиться о заказе / количестве») таких сообщений "правила" должны быть поддержаны (но не обязательны) для него.
  2. Найдите повторяющиеся единицы и «классифицируйте» строки, отфильтруйте слишком изменчивые вещи, такие как отметки времени, адреса или номера строк.
  3. Проанализируйте второй файл, найдите вещи, которые имеют новые логические единицы (одноразовые или повторяющиеся) или что-нибудь, что «поразит» систему, привыкшую к первому файлу.

Пример выполнения некоторых действий вручную:

$ cat A | head -n 1 0:00:00.234 Received buffer 0x324234  $ cat A | egrep -v "Received buffer" | head -n 1 0:00:00.237 Processeed buffer 0x324234  $ cat A | egrep -v "Received buffer|Processeed buffer" | head -n 1 0:00:00.238 Send buffer 0x324255  $ cat A | egrep -v "Received buffer|Processeed buffer|Send buffer" | head -n 1  $ cat B | egrep -v "Received buffer|Processeed buffer|Send buffer" 0:00:03.338 Error processing buffer 0x324222  0:00:07.280 Send buffer 0x3242FA failed 

Это скучно (есть много типов сообщений); Кроме того, я могу случайно включить слишком широкий шаблон. Также он не может обрабатывать сложные вещи, такие как взаимосвязь между сообщениями.

Я знаю, что это связано с ИИ. Может быть, есть уже разработанные инструменты?

3
Поправьте меня, если я ошибаюсь, но разве эти вопросы не должны быть размещены на SO ??? Avis 14 лет назад 0
@ Avis, я думаю, что вопросы типа «какую программу использовать…» - это SU. Конечно, такая программа также будет полезна для пользователей SO и SF. Vi. 14 лет назад 0
@Vi: Похоже, вы идете к программному решению, а не пытаетесь найти гипотетически подходящую программу. Запрашивать советы по дизайну на SO кажется уместным. Gilles 14 лет назад 0
@ Жиль, мои вопросы часто начинаются с того, «какую программу я должен использовать, чтобы сделать это и это» и заканчиваются каким-то сценарием, который я (или другой пользователь) написал. Я не знаю, следует ли переносить такие вещи в SO. / * Собираюсь спросить у Меты * / Vi. 14 лет назад 0

3 ответа на вопрос

0
b0fh

diff(и его различные варианты) покажет вам различия в обоих направлениях и сохранит порядок сообщений. Тем не менее, он не удалит дубликаты различий (для этого вы можете подать заявку uniqпозже) или работать с изменяющимся порядком. Это достаточно хорошо?

Нет. Файлы не очень похожи. Есть много вещей, таких как отметки времени, разный порядок и количество похожих сообщений. Vi. 14 лет назад 0
0
Gilles

Используйте diff(в обычном режиме вывода, т. Е. Нет -cили -u). Новые строки будут иметь префикс >.

diff A B | sed -ne 's/> //p' 

Если журналы содержат метки времени, сначала их нужно удалить.

Иногда лучше видеть новые / измененные биты в контексте с выделением различий и навигацией между разными фрагментами. В Emacs есть хороший интерфейс для этого (меню Tools | Compare, M-x ediff-files). Есть также много автономных инструментов (часто с «diff» или «сравнить» в их названии).

Кстати, если вас не интересует порядок строк, то сортировка обоих файлов с последующим commбудет проще и приятнее, чем процесс, который вы задаете в своем вопросе.

Будет ли `diff` действительно работать, если файлы не имеют больших общих частей, только _s Similar_, например, содержат те же типы сообщений (кроме некоторых дополнительных сообщений в` B`)? Файлы действительно большие, и существует много разных типов сообщений; Само приложение имеет таймеры и измеряет его производительность и зависит от сервера (который также имеет таймер). PS Это gstreamer подробный отладочный журнал. Vi. 14 лет назад 0
@Vi: Нет, для diff необходимо, чтобы общая часть была идентичной, за исключением пробелов. Общая проблема сравнения таких следов приложения может быть очень сложной. Учитывая пример выходных данных, который вы сейчас разместили, игнорирование временных меток выглядит нормально, но, похоже, номера буферов передают информацию, которую вы не хотели бы потерять. Содержат ли A и B одинаковые последовательности отправки и получения буфера (с разными номерами и успехом / неудачей), или соответствие быстро разрушается? Gilles 14 лет назад 0
Мне нужно знать, какие сообщения являются принципиально новыми в `B`. / * уже выполнил конкретную задачу вручную, создав очень длинный `cat A | egrep -b 'msg1 | msg2 | msg3 | ... | msgN'` и выдать ее в `b` * /. Я думаю, что это должно быть что-то вроде искусственного интеллекта, например, автокатегоризация или извлечение ключевых слов. Vi. 14 лет назад 0
s / egrep -b / egrep -v / Vi. 14 лет назад 0
0
Gilles

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

Я бы сформулировал вашу программу как попытку сравнить следы сетевой программы. Я подозреваю, что люди, которые сравнивают следы сетевых или параллельных программ, столкнулись с этой проблемой и написали свои собственные инструменты, но я не имею в виду конкретный пример.

Похожие вопросы