Добавление метки метки времени вместе с строками файла журнала

У меня есть файл журнала, и мне нужно добавить временные метки к каждой строке по мере добавления. Поэтому я ищу сценарий, который добавляет временные метки к каждой записи в строках журнала и может работать как задание cron.

Может кто-нибудь, пожалуйста, помогите мне с идеей создания этого скрипта?

  • Проверьте, удален ли вход в систему
  • Можно ли найти время прошлых сеансов пользователя?
  • Как отреагировать журналистам на демонстрации проверки?
  • Как изменить задержку, возникшую после ввода неправильного пароля?
  • есть ли способ сохранить сеанс жизни даже при выходе из системы?
  • Как узнать, когда и какой пользователь зашел в систему под Mac OS X? Последнего недостаточно!
  • Как проверить, какой клиент обращается к Unix?
  • log file: только записи процесса старше «MMM DD HH: MM: SS»
  • 4 Solutions collect form web for “Добавление метки метки времени вместе с строками файла журнала”

    Общий путь

    $ cat input.log | sed -e "s/^/$(date -R) /" >> output.log 

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

    1. cat читает файл с именем input.log и просто печатает его в своем стандартном потоке вывода.

      Обычно стандартный вывод подключается к терминалу, но этот маленький скрипт содержит | поэтому shell перенаправляет стандартный вывод cat на стандартный ввод sed .

    2. sed считывает данные (как производит cat ), обрабатывает его (согласно сценарию с опцией -e ), а затем выводит его на стандартный вывод. Сценарий "s/^/$(date -R) /" означает замену каждого начала строки на текст, сгенерированный командой date -R (общая конструкция для команды replace: s/pattern/replace/ ).

    3. Затем согласно >> bash перенаправляет вывод sed в файл с именем output.log ( > означает замену содержимого файла и >> означает добавление в конец).

    Проблема заключается в том, что $(date -R) оценивается один раз при запуске скрипта, чтобы он вставлял текущую временную метку в начало каждой строки. Текущая временная метка может быть далека от момента, когда было создано сообщение. Чтобы избежать этого, вы должны обрабатывать сообщения, поскольку они записываются в файл, а не с заданием cron.

    ФИФО

    Стандартное перенаправление потока, описанное выше, называется трубой . Вы можете перенаправить его не только с | между командами в скрипте, но через файл FIFO (так называемый канал ). Одна программа будет записывать в файл, а другая будет считывать данные и получать их в качестве первых отправок.

    Выберите пример:

     $ mkfifo foo.log.fifo $ while true; do cat foo.log.fifo | sed -e "s/^/$(date -R) /" >> foo.log; done; # have to open a second terminal at this point $ echo "foo" > foo.log.fifo $ echo "bar" > foo.log.fifo $ echo "baz" > foo.log.fifo $ cat foo.log Tue, 20 Nov 2012 15:32:56 +0400 foo Tue, 20 Nov 2012 15:33:27 +0400 bar Tue, 20 Nov 2012 15:33:30 +0400 baz 

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

    1. mkfifo создает именованный канал

    2. while true; do sed ... ; done while true; do sed ... ; done запускает бесконечный цикл, и на каждой итерации он запускает sed с перенаправлением foo.log.fifo на его стандартный ввод; sed блокирует ожидание входных данных, а затем обрабатывает полученное сообщение и печатает его на стандартный вывод, перенаправленный в foo.log .

      На этом этапе вам нужно открыть новое окно терминала, потому что цикл занимает текущий терминал.

    3. echo ... > foo.log.fifo выводит сообщение на стандартный вывод, перенаправленный на файл fifo, и sed получает его, обрабатывает и записывает в обычный файл.

    Важное замечание – fifo так же, как любая другая труба не имеет смысла, если одна из ее сторон не связана с каким-либо процессом. Если вы попытаетесь записать в трубу, текущий процесс будет блокироваться, пока кто-то не будет читать данные с другой стороны трубы. Если вы хотите читать из канала, процесс блокируется, пока кто-то не напишет данные в трубу. sed петля в приведенном выше примере ничего не делает (спит), пока вы не выполните echo .

    Для вашей конкретной ситуации вы просто настраиваете приложение для записи сообщений журнала в файл fifo. Если вы не можете его настроить – просто удалите исходный файл журнала и создайте файл fifo. Но обратите внимание, что если цикл sed будет умирать по какой-то причине – ваша программа будет заблокирована при попытке write файл, пока кто-то не read из fifo.

    Преимущество – это текущая временная метка, которая оценивается и прикрепляется к сообщению, когда программа записывает его в файл.

    Асинхронная обработка с tailf

    Чтобы сделать запись в журнал и обработка более независимой, вы можете использовать два обычных файла с tailf . Приложение будет записывать сообщение в необработанный файл, а другой процесс – читать новые строки (следовать за записью асинхронно) и обрабатывать данные с записью во второй файл.

    Приведем пример:

     # will occupy current shell $ tailf -n0 bar.raw.log | while read line; do echo "$(date -R) $line" >> bar.log; done; $ echo "foo" >> bar.raw.log $ echo "bar" >> bar.raw.log $ echo "baz" >> bar.raw.log $ cat bar.log Wed, 21 Nov 2012 16:15:33 +0400 foo Wed, 21 Nov 2012 16:15:36 +0400 bar Wed, 21 Nov 2012 16:15:39 +0400 baz 

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

    1. Запустите процесс tailf который будет следовать за bar.raw.log в bar.raw.log и распечатать их до стандартного вывода, перенаправленного на бесконечный, в while read ... echo loop. Этот цикл выполняет два действия: считывает данные со стандартного ввода в буферную переменную, называемую line а затем записывает созданную bar.log метку со следующими буферизованными данными в bar.log .

    2. Напишите некоторые сообщения в bar.raw.log . Вы должны сделать это в отдельном окне терминала, потому что первый будет занят tailf который будет следовать за tailf и выполнять свою работу. Довольно просто.

    tailf вашего приложения не будут блокироваться, если вы убьете tailf . Концы – менее точные временные метки и дублирующие файлы журналов.

    Вы можете использовать скрипт ts perl из moreutils :

     $ echo test | ts %F-%H:%M:%.S 2012-11-20-13:34:10.731562 test 

    Изменен ответ Дмитрия Васильянова.

    В сценарии bash вы можете перенаправлять и переносить вывод с меткой времени по очереди на лету.

    Когда использовать:

    • Для заданий сценария bash вставьте строку перед основным скриптом
    • Для заданий без сценария создайте сценарий для вызова программы.
    • Для управления сервисами по системе лучше использовать tailf для файла журнала, как сказал Дмитрий Васильянов.

    Пример с именем foo.sh :

     #!/bin/bash exec &> >(while read line; do echo "$(date +'%h %d %H:%M:%S') $line" >> foo.log; done;) echo "foo" sleep 1 echo "bar" >&2 sleep 1 echo "foobar" 

    И результат:

     $ bash foo.sh $ cat foo.log May 12 20:04:11 foo May 12 20:04:12 bar May 12 20:04:13 foobar 

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

    1. exec &> Перенаправить stdout и stderr в одно и то же место
    2. >( ... ) выхода асинхронной внутренней команды
    3. Остальная часть работает по мере расширения Дмитрия Васильянова.

    Например:

    • метка времени и запись в файл

       #!/bin/bash exec &> >(while read line; do echo "$(date +'%h %d %H:%M:%S') $line" >> foo.log; done;) echo "some script commands" /path-to/some-thrid-party-programs 
    • Или печатать временную метку и записывать в stdout

       #!/bin/bash exec &> >(while read line; do echo "$(date +'%h %d %H:%M:%S') $line"; done;) echo "some script commands" /path-to/some-thrid-party-programs 

      затем сохраните их в настройках /etc/crontab

       * * * * * root /path-to-script/foo.sh >> /path-to-log-file/foo.log 

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

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

    Pushmonstats.sh – это сценарий, который собирает статистику температуры системы на моем ПК и отправляет ее в малину Pi, на которой работает Cacti. Некоторое время назад сеть застряла. Я только получил тайм-ауты SSH в журнале ошибок. К сожалению, в этом журнале нет записей времени. Я не знал, как добавить отметку времени к записи журнала. Итак, после некоторых поисков в Интернете я наткнулся на этот пост, и это то, что я сделал с помощью ts .

    Чтобы проверить его, я использовал неизвестный вариант rand . Это дало ошибку stderr. Чтобы захватить его, я перенаправляю его во временный файл. Затем я использую cat, чтобы показать содержимое файла и передать его в ts , добавить формат времени, который я нашел в этом сообщении, и, наконец, зарегистрировать его в файле ошибки. Затем я очищаю содержимое временного файла, иначе я получаю двойные записи для одной и той же ошибки.

    Crontab:

     * * * * * /home/monusr/bin/pushmonstats.sh 1>> /home/monusr/pushmonstats.log 2> /home/monusr/.err;/bin/cat /home/monusr/.err|/usr/bin/ts %F-%H:%M:%.S 1>> /home/monusr/pushmonstats.err;> /home/monusr/.err 

    Это дает следующее в моем журнале ошибок:

     2014-03-22-19:17:53.823720 rand: unknown option -- '-l' 

    Возможно, это не очень элегантный способ сделать это, но он работает. Интересно, есть ли более элегантный подход к нему.

    Linux и Unix - лучшая ОС в мире.