Разные временные метки в файле журнала с использованием команд Unix - PullRequest
0 голосов
/ 19 сентября 2011

У меня есть файл журнала с такими строками:

...timestamp...(id=1234)..GO...
...timestamp...(id=1234)..DONE...

Факты:

  • метки времени имеют вид ЧЧ: ММ: СС.сссс (с за неполные секунды)
  • каждый номер 'id' имеет две связанные строки: "GO" и "DONE"
  • две связанные строки не обязательно находятся рядом друг с другом; файл хронологический

Что я хочу:

  • сопоставить связанные линии GO / DONE
  • Разница во времени
  • (в идеале) создать новый файл вида:

    diffTime <GO line> <DONE line>
    

Моя главная точка отсчета - это разметка временных меток. Это было бы очень полезно, и мне не хватает навыков sort / sed / awk, чтобы написать это. Существуют ли инструменты файла журнала, чтобы помочь с таким взломом?

Ответы [ 2 ]

3 голосов
/ 19 сентября 2011

Я не знаю таких инструментов, но их можно написать в оболочке.Например, этот журнал:

11:18:51 (id=123) GO
11:18:52 (id=124) GO
11:18:53 (id=123) DONE
11:18:54 (id=125) GO
11:18:55 (id=125) DONE
11:18:55 (id=124) DONE

Может быть преобразован в

2 123
3 124
1 125

Где первый столбец - время в секундах, а второй столбец - идентификатор транзакции.

Командабыло:

cat example.log
| sed 's|\([^ ]\+\) (id=\([^)]\+\)) \(.\+\)|\1 \2 \3|;s|GO|1|;s|DONE|2|'
| sort -k2,3
| paste - -
| tr ':' ' '
| awk '{printf("%d %d\n", ((($6-$1)*60*60)+(($7-$2)*60)+($8-$3)), $4)}'

Этот однострочный, вероятно, может быть упрощен еще больше.

Как это работает:

  • изменить формат строки на "11:18:51 123 GO "
  • заменяет GO на 1 и DONE на 2 (потому что в дальнейшем это позволит нам правильно отсортировать его)
  • сортирует строки результатов по идентификатору транзакции и состоянию
  • соедините каждые 2 строки (теперь каждая строка результата описывает начало и конец транзакции)
  • заменяет все двоеточия на пробелы (чтобы упростить awk выражения позже)
  • вычисляет разницу во времени путем деления вручную
  • результат печати
2 голосов
/ 19 сентября 2011

Вот скрипт, который приведет вас на полпути:

#!/bin/bash

# Script must be called with one parameter, the name of the file to process
if [ $# -ne 1 ]; then
  echo "Usage: $0 filename"
  exit
fi

filename=$1


# Use sed to put the timestamp after the id
#    10:46:01:0000 (id=20) GO
#    10:46:02:0000 (id=10) GO
#    10:46:03:0000 (id=10) DONE
#    10:46:04:0000 (id=20) DONE
#
#  becomes
#
#    (id=20) 10:46:01:0000 GO
#    (id=10) 10:46:02:0000 GO
#    (id=10) 10:46:03:0000 DONE
#    (id=20) 10:46:04:0000 DONE
#
# \1 timestamp
# \2 id
# \3 status (GO or DONE)
#         \1          \2              \3
sed -e "s/\([0-9:]*\) \((id=[0-9]*)\) \(.*\)/\2 \1 \3/" $filename > temp1


# Now sort the file. This will cause timestamps to be sorted, grouped by id
#    (id=20) 10:46:01:0000 GO
#    (id=10) 10:46:02:0000 GO
#    (id=10) 10:46:03:0000 DONE
#    (id=20) 10:46:04:0000 DONE
#
#  becomes
#
#    (id=10) 10:46:02:0000 GO
#    (id=10) 10:46:03:0000 DONE
#    (id=20) 10:46:01:0000 GO
#    (id=20) 10:46:04:0000 DONE
sort temp1 > temp2


# Use sed to put the id after the timestamp
#    (id=10) 10:46:02:0000 GO
#    (id=10) 10:46:03:0000 DONE
#    (id=20) 10:46:01:0000 GO
#    (id=20) 10:46:04:0000 DONE
#
#  becomes
#
#    10:46:02:0000 (id=10) GO
#    10:46:03:0000 (id=10) DONE
#    10:46:01:0000 (id=20) GO
#    10:46:04:0000 (id=20) DONE
# \1 id
# \2 timestamp
# \3 status (GO or DONE)
sed -e "s/\((id=[0-9]*)\) \([0-9:]*\) \(.*\)/\2 \1 \3/" temp2 > temp3

А для остальных ... после запуска этого скрипта за каждой строкой GO будет следовать строка DONE с тем же идентификатором, при условии, чточто такая линия DONE существует.

Далее вы можете прочитать каждую пару строк, извлечь временные метки и отразить их (посмотрите функции временных меток, предложенные Johnsyweb).Затем объедините две строки в одну.Ваши результаты теперь будут выглядеть примерно так:

#    1s 10:46:02:0000 (id=10) GO 10:46:03:0000 (id=10) DONE
#    3s 10:46:01:0000 (id=20) GO 10:46:04:0000 (id=20) DONE

Обратите внимание, что записи не соответствуют порядку начальной отметки времени.Это произошло потому, что мы отсортировали по идентификатору ранее.Я оставлю это в качестве упражнения для вас, чтобы выяснить, как получить записи в правильном порядке.Мы хотим, чтобы запись для id = 20 предшествовала id = 10, потому что id = 20 была запущена до id = 10.

#    3s 10:46:01:0000 (id=20) GO 10:46:04:0000 (id=20) DONE
#    1s 10:46:02:0000 (id=10) GO 10:46:03:0000 (id=10) DONE

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

...