3

Пример: приложение генерирует большой текстовый файл журнала 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]{6} , ... Он должен находить отдельные слова, простые шаблоны в числах, общие макеты (например, «некоторая дата, а не текст, а не текст, а не конец_линии»), а также обрабатывать комбинации выше. Поскольку это непростая задача, помощь пользователя (добавление регулярных выражений с явным "игнорировать это", "сделать основной фактор", "не разбивать на части", «считать датой / числом», «заботиться о заказе / количестве») таких сообщений "правила" должны быть поддержаны (но не обязательны) для него.
  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 ответа3

0

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

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

0

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

0

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

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

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

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

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .