Обертання журналу stdout?


53

У мене є програма Linux, яка може записувати інформацію в stdout та stderr.

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

Чи є спосіб змусити цей файл журналу обертатись? (Максимальний розмір, потім переключиться на інший файл, зберегти лише обмежену кількість файлів)

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


1
Чому ви не можете просто змінити скрипт, який перенаправляє вихід, щоб містити логіку для обертання?
MaQleod

Я міг би, якби хтось міг сказати мені, як визначити розмір журналу файлів і повернути його з-під stdout процесу, не порушуючи цей процес. Мені не доводиться використовувати, logrotateякщо є кращий варіант, який просто здався зручним відправною точкою для обговорення.
Міраль

2
Вам не доведеться використовувати логротат, але використання логротату просто економить час ... Зазвичай колесо у винаході колеса мало.
bubu

Точно моя думка. То чи існує спосіб змусити логротату працювати з перенаправленою вершиною поточного процесу?
Міраль

Відповіді:


44

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

  • Дана Бернштейна multilogз демонтів
  • Брюса Гюнтера multilogз демомонтолів-біс
  • Лорана Берко s6-logз s6
  • Ґерріт Папе svlogdз бігу
  • Уейн Маршалл tinylogз перп
  • Моя cyclogз ноша

Інструменти для обробки даних multilog-форматів наборів файлів журналу включають, серед іншого,:

Подальше читання


1
Дякую, multilogсхоже на те, що мені було потрібно.
Міраль

видається, що multilog є єдиним підключенням до debian у програмі debian (daemontools має офіційний пакет). Але в моєму конкретному випадку, коли я хотів зберігати журнали на розділі fat32, обертовий не працює, оскільки мультилог хоче використовувати симпосилання. Не підключайтесь і грайте для мене :)
Арнут

Це не може бути правдою, оскільки multilogніде не створюється і не вимагає символічних посилань. Це абсолютно нейтрально щодо них.
JdeBP

URL «Не використовувати LogRotate або Newsyslog в цьому столітті» має додаткову точку
duyue

15

rotatelogsінструмент поставляється з Apache (в binдиректорії) (див документації ) приймає вхідні дані зі стандартного вводу і повертає колоду після деякого певної кількості часу


14

Якщо у вас є можливість перейти до одного із стандартних потоків журналу (syslog, daemon, cron, користувач, безпека, пошта тощо), ви можете скористатися loggerкомандою та передавати на нього замість цього.

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

В іншому випадку вам може бути краще передавати вміст, який ви зареєстрували, до власної програми або сценарію для обробки, або подивитися на налаштування logrotateконфігурації.

EDIT: Відповідь JdeBP, здається, відповідає тому, що ви можете шукати.


2
+1 для простоти. До речі, ви також можете налаштувати спеціальний об'єкт (local0) замість стандартних (демон у вашому прикладі)
Roger Keays

14

У мене була подібна проблема, і спочатку я відкинув логротат, але виявилося, що логротат може насправді зробити це добре, ключова директива - " copytruncate ". Чомусь цей термін не з'явився ні в одному з гуглінгу, тому я додаю цю відповідь, щоб уточнити, як саме її використовувати для цього випадку.

Хитрість полягає в тому, що це працює лише в тому випадку, якщо переспрямування виконується з " >> " (додавати) замість " > " (створити).

Налаштування файлу (truncate.cfg):

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

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

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

Запуск обертання журналу:

logrotate truncate.cfg

Це приємна теорія, але вона насправді не працює в будь-якій системі, на якій я її спробував. Файл фактично не врізається, і програма продовжує додавати його, як і раніше. (І так, це навіть із перенаправленням, зробленим через >>.) ((До речі, ця відповідь вже була дана раніше.))
Міраль

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

То чи існує спосіб змусити логротату працювати з перенаправленим виступом поточного процесу?

Так! Ознайомтеся з директивою "copytruncate", запропонованою logrotate. Вказавши, що вказує logrotate впоратися з цією самою ситуацією: проста програма, яка зберігає свій файл журналу нескінченно відкритим.

Одне застереження може бути або не бути проблемою у вашій ситуації:

Зауважте, що між копіюванням файла та обрізанням файлу існує дуже маленький відрізок часу, тому деякі дані журналу можуть бути втрачені.

Анекдотично я бачив деякі джерела журналів "реального світу", які заохочують користувачів застосовувати цю директиву. Там яке - то обговорення цього варіанту тут .


3

Використовуйте спліт, це частина основних елементів. Він може прийняти stdin і розділити його на шматки (залежно від розміру, чи кількості рядків тощо).

Приклад:

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

Примітка, тире (-) вказує "розділити" використовувати stdin замість файлу.


Чи можете ви розширити свою відповідь, щоб описати, як це зробити? Дякую.
fixer1234

щойно оновив мою відповідь прикладом.
Назар

1G - довільний розмір, після чого він запускає новий файл?
fixer1234

1
Це не особливо гарне рішення проблеми, оскільки це означає, що ви можете отримати половину повідомлення в одному файлі і половину в іншому. Існує також ризик втрати даних, якщо машина вийде з ладу, в той час як splitє дані в тому, що може бути великим буфером. Зважаючи на те, що існує декілька інструментів, які правильно вирішують цю проблему, я не думаю, що таке рішення самостійно можна взагалі не рекомендувати.
Девід Річербі

1
@David Richerby - як щодо додавання -u для неблокованого?
Нік

3

Мені подобається multilogмій варіант використання, але мій випадок використання настільки тривіальний / простий, що він не викладений дуже просто у знайдених нами документах / прикладах. Ось простий мультилогічний приклад повороту:

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

Деякі примітки:

  • цей дамп входить у каталог / tmp / myapp /
  • s10000 представляє 10000 байт *
  • 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назвою "будь-що", в моєму випадку "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.


1

Я написав логроте в ці вихідні. Я, мабуть, не хотів би, якби прочитав чудову відповідь @ JdeBP і multilog.

Я зосередив увагу на тому, що він легкий і здатний bzip2 своїми вихідними фрагментами:

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

Хоча ще багато що потрібно зробити і протестувати.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.