Журнал ротации стандартного выхода?

53

У меня есть программа для Linux, которая может записывать информацию в stdout и stderr.

У меня есть сценарий оболочки, который перенаправляет этот вывод в файл в /var/log. (Через >>и 2>&1.)

Есть ли способ заставить этот файл журнала вращаться? (максимальный размер, затем переключитесь на другой файл, оставьте только ограниченное количество файлов)

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

Miral
источник
1
Почему вы не можете просто изменить скрипт, который перенаправляет вывод, чтобы содержать логику вращения?
MaQleod
Я мог бы, если бы кто-нибудь мог сказать мне, как определить размер файла журнала и выворачивать его из-под стандартного потока процесса, не нарушая этот процесс. Мне не нужно использовать, logrotateесли есть лучший вариант, который звучит как удобная отправная точка для обсуждения.
Мирал
2
Вам не нужно использовать logrotate, но использование logrotate просто экономит время ... Обычно мало смысла изобретать велосипед.
бубу
Именно моя точка зрения. Так есть ли способ заставить logrotate работать с перенаправленным stdout текущего процесса?
Мирал

Ответы:

44

В качестве альтернативы вы могли бы направить вывод через инструменты, предназначенные для основной цели - поддерживать наборы журнальных файлов с ограниченным размером, автоматически вращаемыми, такие как:

  • Дана Бернштейна multilogиз daemontools
  • Брюса Гюнтера multilogиз daemontools-бис
  • Лорана Берко s6-logот s6
  • Геррит Папе svlogdиз Рунита
  • Уэйн Маршалл tinylogиз Перп
  • Мой cyclogиз ничего

Инструменты для последующей обработки multilogформатов файлов журналов включают, среди прочего:

дальнейшее чтение

JdeBP
источник
1
Спасибо, multilogпохоже, именно то, что мне было нужно.
Мирал
multilog, похоже, является единственным решением plug-and-play в Debian (у daemontools есть официальный пакет). Но в моем конкретном случае, когда я хотел сохранить журналы в разделе fat32, ротация не работает, так как multilog хочет использовать символическую ссылку. Нет подключи и играй для меня :)
Arnout
Это не может быть правдой, поскольку multilogнигде не создаются и не требуются символические ссылки. Это абсолютно нейтрально по отношению к ним.
JdeBP
URL «Не использовать LogRotate или Newsyslog в этом столетии» имеет дополнительную точку
duyue
15

rotatelogsинструмент поставляется с Apache (в binдиректории) (см документации ) принимает входные данные из стандартного ввода и поворачивает бревно после некоторого определенного количества времени

BertNase
источник
14

Если у вас есть возможность перейти к одному из стандартных потоков журналов (syslog, daemon, cron, user, security, mail и т. Д.), Вы можете использовать loggerкоманду и канал к нему.

echo "Hello." | logger -p daemon.info

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

РЕДАКТИРОВАТЬ: JdeBP ответ, кажется, есть то, что вы можете искать.

Лара Дуган
источник
2
+1 для простоты. Кстати, вы также можете настроить пользовательское средство (local0) вместо стандартных (демон в вашем примере)
Roger Keays
14

У меня была похожая проблема, и я изначально отказывался от logrotate, но оказалось, что logrotate действительно может это сделать, ключевая директива - copytruncate . По какой-то причине этот термин не встречается ни в одном из поисковиков, которые я использовал, поэтому я добавляю этот ответ, чтобы уточнить, как именно его использовать в данном случае.

Хитрость в том, что это работает, только если перенаправление выполняется с помощью « >> » (добавление) вместо « > » (создание).

Файл конфигурации (truncate.cfg):

/tmp/temp.log {
    size 10M
    copytruncate
    rotate 4
    maxage 100
}

Тестовая программа (никогда не сдается файл). Вы можете наблюдать за тем, как он заполняет диск, и хотя удаление файла журнала будет работать, на самом деле оно не освободит место на диске:

cat /dev/urandom >> /tmp/temp.log

Запуск журнала поворота:

logrotate truncate.cfg
Сэм Хендли
источник
Это хорошая теория, но на самом деле она не работает ни в одной системе, на которой я ее пробовал. Файл фактически не усекается, и программа продолжает добавляться к нему, как и раньше. (И да, это даже с перенаправлением, выполненным через >>.) ((Кстати, этот ответ уже был дан ранее.))
Miral
1
… Как обсуждено в logrotate, не будет усекать оригинальный файл (на нашем сайте Unix & Linux). Кроме того, echo /dev/urandom >> /tmp/temp.logмы запишем 13 детерминированных символов /tmp/temp.logи сразу же завершим работу. Вы имели в виду cat /dev/urandom?
G-Man говорит: «Восстанови Монику»
2
Только что протестировал здесь, и, похоже, работает. Содержимое файла копируется в новый файл журнала. Исходный файл остается открытым для процесса и усекается (теперь размер равен 0).
Филипп
1
Будьте осторожны с возможной потерей данных с помощью copytruncate.
wanghq
1
+1 хотя "Обратите внимание, что между копированием файла и его усечением существует очень маленький промежуток времени, поэтому некоторые данные журнала могут быть потеряны".
Тагар
3

Так есть ли способ заставить logrotate работать с перенаправленным stdout текущего процесса?

Да! Ознакомьтесь с директивой «copytruncate», предлагаемой logrotate. Указание, которое инструктирует logrotate справиться с этой самой ситуацией: простая программа, которая сохраняет свой файл журнала открытым на неопределенное время.

Одно предупреждение может или не может быть проблемой в вашей ситуации:

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

Как ни странно, я видел некоторые источники журналов "реального мира", которые поощряют пользователей применять эту директиву. Там какое - то обсуждение этого варианта здесь .

natevw
источник
3

Используйте split, это часть coreutils. Он может взять stdin и разбить его на куски (в зависимости от размера чанка, количества строк и т. Д.).

Пример:

app | split --bytes 1G - /var/logs/put-prefix-here

Примечание. Тире (-) указывает «split» использовать stdin вместо файла.

Назар
источник
Можете ли вы расширить свой ответ, чтобы описать, как это сделать? Благодарю.
fixer1234
только что обновил мой ответ с примером.
Назар
1G произвольного размера, после чего начинается новый файл?
fixer1234
1
Это не очень хорошее решение проблемы, потому что это означает, что вы можете получить половину сообщения в одном файле и половину в следующем. Существует также риск потери данных, если машина splitвыйдет из строя, когда у нее есть данные в том, что может быть большим буфером. Учитывая, что есть несколько инструментов, которые решают эту проблему должным образом, я не думаю, что такое решение может быть рекомендовано вообще.
Дэвид Ричерби
1
@ Дэвид Ричерби - как насчет добавления -u для небуферизованного?
Ник
3

Мне нравится multilogмой вариант использования, но мой вариант использования настолько тривиален / прост, что не очень просто изложен в документах / примерах, которые я нашел. Вот простой пример поворота мультилога:

mkdir /tmp/myapp
./myapp | multilog t s10000 n5 '!tai64nlocal' /tmp/myapp 2>&1

Некоторые заметки:

  • этот дамп записывается в этот каталог / tmp / myapp /
  • s10000 представляет 10 000 байтов *
  • n5 представляет 5 файлов. * «Текущий» журнал считается одним из файлов, поэтому он включает в себя 4 старых журнала + «текущий»
  • это основано на примерах, предоставленных Франсуа Босолеем по адресу: http://blog.teksol.info/pages/daemontools/best-practices
  • Я не понимаю многие варианты - я отсылаю вас к различной документации, чтобы расширить это ...
  • Документы предупреждают, что: "Note that running processor may block any program feeding input to multilog."где «процессор» - это '!tai64nlocal'часть команды

* Для многих приложений это плохой выбор для долгосрочного использования. Они позволяют наблюдать за процессом заполнения и вращения бревен быстрее, чем это делают большие бревна.

Наконец, не забудьте nohup, если требуется! С nohup вам не нужны 2>&1(s = 10e6 и n = 30 здесь):

mkdir -p /tmp/myapp
nohup ./myapp | multilog t s10000000 n30 '!tai64nlocal' /tmp/myapp &

Эта команда должна начать вас.

шалфей
источник
1

Я просто хотел добавить к комментарию Сэма Хендли выше:

Хитрость в том, что это работает, только если перенаправление выполняется с помощью >>(добавления) вместо >(создания).

Я столкнулся с той же проблемой, когда исходный файл просто продолжает расти, если вы используете >(создаете), но если вы используете >>(добавляете) Logrotate copytruncate работает красиво и как ожидалось. Исходный файл возвращается к нулю байтов, и программа продолжает запись.

Перенаправьте STDOUT и STDERR во вращающийся лог-файл:

  1. some-program.sh >> /tmp/output.txt 2>&1 &
  2. Создайте файл конфигурации logrotate под /etc/logrotate.dназванием any, output_roll в моем случае.

    Пример конфигурации для моего случая:

    /tmp/output.txt {
        notifempty
        missingok
        size 1G
        copytruncate
        start 0
        rotate 15
        compress
    }
    
  3. Настройте свою работу cron внутри /etc/crontabфайла

    *  *  *  *  * root /usr/sbin/logrotate /etc/logrotate.d/output_roll
    

    Это будет проверять файл каждую минуту. Вы можете настроить в соответствии с вашими потребностями.

  4. Начни это:

    $> service crond restart
    
  5. это оно

Примечание. У меня также была проблема с настройкой SELinux, SELINUX=enforcingпоэтому я установил его на SELINUX=disabled.

user578558
источник
1

Я написал logrotee в эти выходные. Я бы не стал, если бы прочитал отличный ответ @ JdeBP и multilog.

Я сосредоточился на том, чтобы он был легким и имел возможность bzip2 его выходных блоков, таких как:

verbosecommand | logrotee \
  --compress "bzip2 {}" --compress-suffix .bz2 \
  /var/log/verbosecommand.log

Однако многое еще предстоит сделать и проверить.

Виктор Сергиенко
источник