Как мне создать дружественный для logrotate файл-писатель на Java или другой платформе? - PullRequest
10 голосов
/ 29 июня 2011

Каковы лучшие практики для реализации средства записи / записи файлов в Java, совместимого с logrotate ? Целью было бы позволить использовать logrotate для всего управления журналом вместо использования встроенного ротации / управления API ведения журнала (Log4J и т. Д.).

Мне было бы интересно услышать комментарии / ответы для других платформ разработки, кроме Java.

Ответы [ 2 ]

9 голосов
/ 29 июня 2011

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

Если вы этого не сделаете, журналы будут записаны в старый файл, даже если он переименован в logrotate (!) (Дескриптор файла остается прежним), а затем записи журнала исчезнут, когда журнал будет сжат и удален (в таком случае java молча удалит такие журналы).

Закрытие и повторное открытие журнала (с использованием имени файла) обеспечит создание нового файла, если он был переименован.Закрытие и повторное открытие файла каждый раз, когда записывается журнал, является излишним, поскольку открытие файла является дорогостоящей операцией.

0 голосов
/ 31 января 2017

Я посмотрел на некоторые другие приложения, и, очевидно, есть опция postrotate и опция copytruncate .Опция copytruncate проще, но я думаю, что она менее надежна, поскольку буферы не могут быть сброшены (т. Е. Следуйте ответу @Jarek Potuik), и даже если они таковые, вы можете получить дублирующиеся записи или пропущенные записи.хотите параметр postrotate:

Параметр postrotate позволяет запустить команду, чтобы приложение сообщило, что нужно открыть файл (закрыть, а затем открыть).Открывая и закрывая файл в Java, вы делаете это с помощью синхронизированного блока или какой-либо блокировки и, конечно, очищаете все буферы.

Предположим, что ваше приложение называется myapp:

В /etc/logrotate.d/myapp у вас будет файл, похожий на:

/var/log/myapp/*.log {
        weekly
        missingok
        rotate 20
        compress
        delaycompress
        notifempty
        sharedscripts
        postrotate
            /etc/init.d/myapp rotate-logs > /dev/null
        endscript
}

Команда /etc/init.d/myapp rotate-logs должна будет подать сигнал приложению о закрытии и повторном открытии файлов журнала.

Часть сигнализации довольно сложна и зависит от того, какое у вас приложение, потому что Java не очень хорошо поддерживает IPC (например, сигналы Unix), поэтому вам, возможно, придется открыть порт или использовать существующий порт, такой как8080 (т. Е. Команда HTTP REST в случае контейнера сервлета), чтобы сообщить приложению закрыть и снова открыть файлы журнала.

...