2013-12-12 3 views
3

Я ищу хороший способ загнать в живой файл журнала и отобразить количество строк с одинаковой датой/временем.bash tail в реальном файле журнала, считая строки uniq с той же датой/временем

В настоящее время это работает:

tail -F /var/logs/request.log | [cut the date-time] | uniq -c 

НО производительность не достаточно хорошо. Задержка длится более одной минуты, и каждый раз она выводится на несколько строк.

Любая идея?

+0

Вы бы писать свой собственный цикл (Баш скрипт), который обрабатывает вывод 'tail' и не обновляет счетчик до дата- изменения времени, затем распечатывает счетчик и сбрасывает счетчик? – Floris

+0

@Floris, и это поможет? – yaccz

+0

Собственно, какой формат даты, который входит в uniq? – yaccz

ответ

6

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

Вот мой тестовый сценарий. Во-первых, я пишу короткий скрипт, который записывает время в файл каждые 100 мс (приблизительно) - это мой «лог-файл», который генерирует достаточное количество данных, которые uniq -c должны дать мне интересный выход каждую секунду:

#!/bin/ksh 
while : 
do 
    echo The time is `date` >> a.txt 
    sleep 0.1 
done 

(Примечание - я должен был использовать ksh, который имеет возможность сделать суб-второй sleep)

в другом окне, я типа достаточно

tail -f a.txt | uniq -c 

Конечно, вы получите следующий результат, появляющийся каждый второй:

9 The time is Thu Dec 12 21:01:05 EST 2013 
    10 The time is Thu Dec 12 21:01:06 EST 2013 
    10 The time is Thu Dec 12 21:01:07 EST 2013 
    9 The time is Thu Dec 12 21:01:08 EST 2013 
    10 The time is Thu Dec 12 21:01:09 EST 2013 
    9 The time is Thu Dec 12 21:01:10 EST 2013 
    10 The time is Thu Dec 12 21:01:11 EST 2013 
    10 The time is Thu Dec 12 21:01:12 EST 2013 

и т.д. Никаких задержек. Важно отметить - Я не пытался вырезать время. Затем я сделал

tail -f a.txt | cut -f7 -d' ' | uniq -c 

И ваша проблема воспроизводится - это будет «висеть» на некоторое время (пока не было 4k символов в буфере, а затем он будет рвать все это сразу).

Немного поиска в Интернете (https://stackoverflow.com/a/16823549/1967396) рассказал мне об утилите под названием stdbuf.В этой ссылке, в нем конкретно упоминается почти точно ваш сценарий, и они обеспечивают следующее временное решение (перефразируя, чтобы соответствовать моему сценарию выше):

tail -f a.txt | stdbuf -oL cut -f7 -d' ' | uniq -c 

И это было бы здорово ... за исключением того, что эта утилита не существует на мой machine (Mac OS) - он специфичен для GNU coreutils. Это оставило меня неспособным проверить - хотя это может быть хорошим решением для вас.

Никогда не бойтесь - я нашел следующее обходное решение, основанное на команде socat (о которой я, честно говоря, почти не понимаю, но я адаптировался из ответа, приведенного в https://unix.stackexchange.com/a/25377).

Сделайте небольшой файл с именем tailcut.sh (это "long_running_command" из приведенной выше ссылке):

#!/bin/ksh 
tail -f a.txt | cut -f7 -d' ' 

Дайте ему разрешение на выполнение с chmod 755 tailcut.sh. Затем введите следующую команду:

socat EXEC:./tailcut.sh,pty,ctty STDIO | uniq -c 

И эй престо - ваш кусковой выход больше комковатый. socat посылает выходные данные из сценария прямо на следующий канал, и uniq может сделать свое дело.

+1

stdbuf сделал это. супер ответ. – zapp

+0

@zapp - Счастлив услышать! С новым годом. – Floris

1

Рассмотрите, как работает uniq -c.

Чтобы распечатать счетчик, ему необходимо прочитать все уникальные строки и только после строки, отличной от предыдущей, она может печатать строку и количество вхождений.

Именно так алгоритм в принципе работает, и вокруг него нет никакого способа.

Вы можете проверить это, запустив

touch a 
tail -F a | uniq -c 

а затем один за другим

echo 1 >> a 
echo 1 >> a 
echo 1 >> a 

ничего не происходит. Только после того, как вы запустите

echo 2 >> a 

uniq может печатать были 3 "1 \ П" вхождений.

+1

Конечно. Тем не менее, я ожидаю, что строки журнала будут распечатаны при изменении поля даты и времени, которое происходит каждую секунду! Но он выдается в задержке более одной минуты и в объемах, а не вживую. – zapp

1

Вы можете попробовать logtop (apt-get install logtop):

Использование:

tail -F /var/logs/request.log | [cut the date-time] | logtop 

Пример:

$ tail -f /var/log/varnish/varnishncsa.log | awk '{print $4}' | logtop 
5585 elements in 10 seconds (558.50 elements/s) 
    1 690 69.00/s [28/Mar/2015:23:13:48 
    2 676 67.60/s [28/Mar/2015:23:13:47 
    3 620 62.00/s [28/Mar/2015:23:13:49 
    4 576 57.60/s [28/Mar/2015:23:13:53 
    5 541 54.10/s [28/Mar/2015:23:13:54 
    6 540 54.00/s [28/Mar/2015:23:13:55 
    7 511 51.10/s [28/Mar/2015:23:13:51 
    8 484 48.40/s [28/Mar/2015:23:13:52 
    9 468 46.80/s [28/Mar/2015:23:13:50 

Колонны, слева направо:

  • Просто строка n умбра
  • QTE видел
  • хитов в секунду
  • фактическая линия
+0

Кажется, это отвечает на другой вопрос? – Floris

+0

@Floris: Почему? –

+0

Кажется, что это не живой канал - вывод показывает строки не в хронологическом порядке. Я думал, что OP хочет узнать, сколько раз повторялось какое-то конкретное сообщение, как это бывает. – Floris