DataLife Engine > Система > Ротация логов - newsyslog

Ротация логов - newsyslog


03-11-2010. Разместил: synergix Ротация логов - newsyslog Разбивая жесткий диск по умолчанию или попросту мало выделив на /var при разбивке рано или поздно сталкиваешься с тем что в разделе /var заканчивается свободное место и ничем хорошим это не грозит. В большинстве случаев причиной тому становятся самые обыкновенные логи. Я столкнулся с этим буквально сегодня, увидев забитый на 75% раздел /var, что естественно мне очень не понравилось.
Проанализировав занимаемое место на этом разделе с помощью ncdu, определил основных виновников - это были логи proftpd, nginx и нескольких других системных сервисов, некоторые из которых разжирели до 150 мегабайт. Было решено настроить их в ротацию со сжатием в bz2.

За логами в FreeBSD следит newsyslog. И логи, создаваемые системой уже настроены на ротацию. Настройки эти хранятся в /etc/newsyslog.conf и сразу после установки системы там можно заметить нечто похожее на:
# logfilename          [owner:group]    mode count size when  flags [/pid_file] [sig_num]
/var/log/all.log                        600  7     *    @T00  J
/var/log/amd.log                        644  7     100  *     J
/var/log/auth.log                       600  7     100  *     JC
/var/log/console.log                    600  5     100  *     J
/var/log/cron                           600  3     100  *     JC
/var/log/daily.log                      640  7     *    @T00  JN
/var/log/debug.log                      600  7     100  *     JC
/var/log/kerberos.log                   600  7     100  *     J
/var/log/lpd-errs                       644  7     100  *     JC
/var/log/maillog                        640  7     *    @T00  JC
/var/log/messages                       644  5     100  *     JC
/var/log/monthly.log                    640  12    *    $M1D0 JN
/var/log/pflog                          600  3     100  *     JB    /var/run/pflogd.pid
/var/log/ppp.log        root:network    640  3     100  *     JC
/var/log/security                       600  10    100  *     JC
/var/log/sendmail.st                    640  10    *    168   B
/var/log/weekly.log                     640  5     1    $W6D0 JN
/var/log/wtmp                           644  3     *    @01T05 B
/var/log/xferlog                        600  7     100  *     JC
/var/log/cvsup.log                      664  7    *    24    -
/var/log/cvsupd.log                     664  7    *    24    Z
/var/log/nginx-access.log               664  7    *    @T00  JC
/var/log/nginx-error.log                664  7    *    @T00  JC
/var/log/proftpd-error.log              664  7    *    @T00  JC
/var/log/proftpd-transfer.log           664  7    *    @T00  JC

Этот пример конфига с уже добавленными записями.
Прежде чем настроить это под себя или добавить сюда ротацию установленных программ следует разобраться что же именно все это обозначает и как это работает.

Описание файла newsyslog.conf

поля, разделенные пробелами или табуляцией
logfilename (лог-файл) -абсолютный путь к файлу, с которым будем работать, например /var/log/httpsd/httpsd-error.log.
[owner:group]([владелец:группа]) – который указывает newsyslog’у кто должен являться владельцем данного лог файла, необязательный параметр. По умолчанию владельцем устаревших журналов является пользователь root, группы wheel. Также можно указывать только один из параметров, например www: – сменить пользователя на www, а :www» сменит группу на www соответственно.
mode(права) – права, которые должны быть на файле (Unix формат, три цифры, например 644, 640, 600)
count (кол-во) – максимальное количество заархивированных лог файлов. Отсчет начинается с 0.
size (размер) – размер в килобайтах, при достижении которого будет произведена архивация лога.
when (когда) – время, через которое архивировать лог-файл. Поле времени может содержать данные четырех типов: «звездочку», число или два различных формата даты.

Если время ротации не важно (например ротация производится только в зависимости от размера) то звездочки * в этом поле будет достаточно.
Если указать число, то ротация будет производится по прошествии заданного числа часов, например 12 – будет производится раз в 12 часов, т.е. 2 раза в сутки (при этом мы явно не указываем точное время ротации).
Когда требуется точно указать дату и/или время ротации придется использовать более сложный вариант записи. Если поле начинается символом @, то считается что время представлено в формате ISO-8601. Этот стандарт используется newsyslog в большинстве Unix-подобных операционных систем в том числе FreeBSD. Этот формат использовался еще с первой версией newsyslog разработанной в MIT (Массачусетском Технологическом Институте). Сложным этот формат кажется пока не разберешься в нем и не начнешь его использовать. Полная запись даты в формате ISO-8601 состоит из 16 цифр с буквой T в середине. Первые четыре цифры означают год, следующие две – месяц, и еще две – день месяца. Буква «T» идет после даты, отделяя ее от времени, как десятичная точка в вещественных числах отделяет дробную часть от целой. После буквы T идут две цифры часа, затем две цифры минут и наконец две цифры секунд. Например дата 16 мая 2010 года, 23:17:09, в формате ISO-8601 будет выглядеть следующим образом: 20100516T231709. Вы обязательно должны ставить букву «T» в ISO-8601-дате. С полными дата все довольно просто, сложности начинаются когда требуется указать неполный формат даты. Указываем только то что нужно, все неуказанные поля не будут учитываться. Когда требуется указать неполный формат – указываем например только дату @17T00 – выполнять 17 числа ежемесячно в полночь. Или @T22 выполнять ежедневно в 22:00. Стоит обратить внимание что запить типа @8T будет запускать ротацию один раз в час, каждый час восьмого числа каждого месяца и так на протяжении целого дня. Такая запись может пригодиться для отладки, но вряд ли будет полезна в нормальном режиме работы. У этой системы имеется один серьезный недостаток – она не дает простого способа задавать ежедневно выполняемые задачи. Когда требуется запустить ротацию журнала, например, по пятницам, что не является чем-то необычным. Или запустить ротацию журнала в последний день месяца таким образов вообще не удастся. Но это можно сделать благодаря другому формату записи.
Если запись времени начинается со знака доллара $, то считается, что время задается в формате FreeBSD – «месяц-неделя-день». Такая запись напоминает возможности cron и позволяет вам установить конкретные дни недели для выполнения задачи. Этот формат использует три буквенных идентификатора: M (день месяца), W (день недели), H (час дня). После каждого из них идет число, указывающее точное время запуска. Часы находятся в интервале от 0 до 23, дни недели от 0 (воскресенье), до 6 (суббота). Дни месяца: от 1 и до количества дней в конкретном месяце. Так, например, для запуска ротации по пятницам за час до полуночи вам следует задать время как $W5H23. Для запуска ротации 15 числа каждого месяца в 3 часа ночи просто напишите $M15H03. Одна интересная функция этой системы позволяет вам автоматически задавать ротацию на последний день месяца используя специальный «день месяца» – «L» (last – последний). Без этого знака было бы очень трудно задать ротацию журнала в последний день месяца без написания специального скрипта, который бы вставлял количество дней в конкретном месяце. Если вы хотите запустить ротацию вашего журнала аккаунтов за два часа до начала нового месяца, вы должны использовать запись $MLH22.

flags (флаги) – некоторые параметры, для лог-файлов:

B – по умолчанию, newsyslog добавляет в новый лог-файл сообщение о том, что лог-файл был ротирован, но если лог-файл бинарный, то это сообщение испортит лог, с параметром B newsyslog не будет добавлять никаких сообщений в лог
C – если лог-файл не существует, то его необходимо создать
G – если указан данный флаг, то в названии лог-файла можно использовать стандартные шаблоны(например *)
J – сжимать лог-файл, используя bzip2
N– Не предупреждать никакой процесс, о ротации лог-файла
W – если используете флаги Z или J, то newsyslog должен подождать, пока завершиться процесс архивации.
Z– сжимать лог, использую gzip.

[/pid_file] – задает путь к pid-файлу процесса создающего и ведущего журнал. Использование pid-файлов является простым способом записи поля ID процесса в системе, так что бы другие программы могли его легко прочитать. pid-файлы большинства программ можно найти в каталоге /var/run. Если в этом поле вы укажете полный путь к pid-файлу, то newsyslog будет посылать сигнал этому процессу когда будет производиться ротация. Например веб-сервер Apache должен быть оповещен при ротации его журналов. Записав в этом поле полный путь к его pid-файлу вы заставите newsyslog посылать процессу Apache сигнал kill -1, что бы он запустил свою часть обработки ротации журналов.

[sig_num] – большинство программ поддерживают ротацию журналов сигналом kill -1 или SIGHUP. Некоторые программы требуют специального сигнала, когда их файлы ротируют. Если вы используйте программу такого типа, то укажите номер необходимого сигнала в последнем поле.

Давайте соберем все сказанное вместе, в самом худшем случае, в примере, в который трудно поверить. Итак у вас есть журнал базы данных, который вы хотите ротировать в 23 часа в последний день каждого месяца. В документации базы данных сказано, что вы должны послать процессу базы сигнал прерывания (SIGINT или сигнал номер 2) после ротации. Вы хотите, что бы архивные журналы принадлежали пользователю «dbmanager» и читать их мог только он. Более того, журналы – двоичные файлы и должны быть не тронуты newsyslog’ом. Ваш newsyslog.conf должен выглядеть следующим образом:

/var/log/database dbmanager: 600 30 * $MLH23 B /var/run/db.pid 2


Теперь пару слов как это работает

Newsyslog обычно запускается по cron’у раз в час, читает конфигурационный файл /etc/newsyslog.conf и определяет, когда лог-файлы нуждаются в архивировании и перегруппировке. logfile перемещается в logfile.0, logfile.0 перемещается в logfile.1, и так далее. Другое именование логи получают при архивации с помощью gzip: logfile.0.gz, logfile.1.gz, и т.д. Таким образом в зависимости от настроек ротация логов может производится когда они достигнут определённого размера или в определённую дату/время.
Вернуться назад