Logrotate - это системная утилита, которая управляет автоматической ротацией и сжатием лог-файлов. Если в процессе длительной работы сервера файлы не были ротированы, сжаты и периодически не удалялись, то рано или поздно они могут занять весь доступный объем памяти.

Logrotate устанавливается по умолчанию на сервере и настроена для обработки ротации журналов для всех установленных пакетов и приложений.

Проверка версии Logrotate:

logrotate --version  

Вывод команды будет следующий:

[root@kvmde54-19861 ~]# logrotate --version
logrotate 3.8.6  

Стандартная конфигурация Logrotate хранится по двум путям:

  • Основной файл конфигурации — /etc/logrotate.conf.
  • Для создания настроек отдельных логов — используем директорию /etc/logrotate.d

Рассмотрим конфигурационный файл Logrotate /etc/logrotate.d:

nano /etc/logrotate.conf  

Вывод команды будет таким:

# see "man logrotate" for details
# rotate log files weekly
weekly  

# keep 4 weeks worth of backlogs
rotate 4  

# create new (empty) log files after rotating old ones
create  

# use date as a suffix of the rotated file
dateext  

# uncomment this if you want your log files compressed
#compress

# RPM packages drop log rotation information into this directory
include /etc/logrotate.d  

# no packages own wtmp and btmp -- we'll rotate them here
/var/log/wtmp {
    monthly
    create 0664 root utmp
        minsize 1M
    rotate 1
}

/var/log/btmp {
    missingok
    monthly
    create 0600 root utmp
    rotate 1
}

# system-specific logs may be also be configured here.
include /etc/logrotate.d/web  

Этот файл содержит конфигурационные блоки для двух разных файлов журнала в каталоге. Оба блока имеют одинаковые опции. Любые параметры, не заданные в этих конфигурационных блоках, наследуют значения по умолчанию или значения, установленные в файле /etc/logrotate.conf.

Основные директивы управления и обработки логов:

  • monthly - ротация раз в месяц. Возможные варианты daily, weekly, monthly, size;
  • notifempty - не ротировать пустой лог-файл.
  • rotate - указывает сколько старых логов нужно хранить, в параметрах передается количество;
  • create - указывает, что необходимо создать пустой лог файл после перемещения старого;
  • dateext - добавляет дату ротации перед заголовком старого лога;
  • compress - указывает, что лог необходимо сжимать;
  • delaycompress - не сжимать последний и предпоследний журнал;
  • extension - сохранять оригинальный лог файл после ротации, если у него указанное расширение;
  • mail - отправлять Email после завершения ротации;
  • maxage - выполнять ротацию журналов, если они старше, чем указано;
  • missingok - не выдавать ошибки, если лог файла не существует;
  • olddir - перемещать старые логи в отдельную папку;
  • postrotate/endscript - выполнить произвольные команды после ротации;
  • start - номер, с которого будет начата нумерация старых логов;
  • size - размер лога, когда он будет перемещен;

Для управления файлами журналов для приложений можно использовать два варианта:

  • Создать новый файл конфигурации Logrotate и поместить его в каталог /etc/logrotate.d/. Он будет работать ежедневно, как пользователь root вместе со всеми другими стандартными заданиями LogRotate.
  • Создать новый конфигурационный файл и запустить его с настройками LogRotate по умолчанию в Ubuntu.

Создание конфигурации в /etc/logrotate.d/

В качестве примера настроим обновления для сервера, который пишет логи в файлы access.log и error.log, расположенные в каталоге /var/log/example-app/.

Чтобы добавить конфигурацию каталог /etc/logrotate.d/, откройте новый файл:

sudo nano /etc/logrotate.d/example-app  
/var/log/example-app/*.log {
    daily
    missingok
    rotate 14
    compress
    notifempty
    create 0640 www-data www-data
    sharedscripts
    postrotate
        systemctl reload example-app
    endscript
}

Описание директив:

  • create 0640 www-data www-data - данная команда создаст новый пустой файл журнала после ротации с заданными разрешениями (0640), владелец ( www-data) и группы (www-data);
  • sharedscripts - эта опция означает, что любые скрипты, добавленные в конфигурацию, выполняются только один раз за запуск после сжатия файлов, а не для каждого отдельного обновленного файла. Поскольку наша конфигурация будет соответствовать двум лог-файлам (access.log и error.log), скрипт, указанный в postrotate, будет запускаться только 1 раз;
  • postrotate to endscript - скрипт в этом блоке будет запущен после того, как файл журнала обновится. В примере приложение перезагружается.

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

sudo logrotate /etc/logrotate.conf --debug  
[root@kvmde54-19861 ~]# sudo logrotate /etc/logrotate.conf --debug
reading config file /etc/logrotate.conf  
including /etc/logrotate.d  
Ignoring nginx.rpmnew, because of .rpmnew ending  
reading config file bootlog  
reading config file chrony  
reading config file example-app  
error: example-app:7 unknown user 'www-data'  
error: found error in /var/log/example-app/*.log , skipping  
removing last 1 log configs  
reading config file exim  
reading config file httpd  
reading config file mariadb  
reading config file nginx  
reading config file ppp  
reading config file proftpd  
reading config file roundcubemail  
reading config file syslog  
Ignoring web because it's not a regular file.  
reading config file wpa_supplicant  
reading config file yum  
including /etc/logrotate.d/web  
Allocating hash table for state file, size 15360 B  

Handling 13 logs  

rotating pattern: /var/log/boot.log  
 after 1 days (7 rotations)
empty log files are not rotated, old logs are removed  
considering log /var/log/boot.log  
  log does not need rotating (log has been rotated at 2020-5-19 15:23, that is not day ago yet)

rotating pattern: /var/log/chrony/*.log  weekly (4 rotations)  
empty log files are rotated, old logs are removed  
considering log /var/log/chrony/*.log  
  log /var/log/chrony/*.log does not exist -- skipping
not running postrotate script, since no logs were rotated  

rotating pattern: /var/log/exim/*log  weekly (4 rotations)  
empty log files are not rotated, old logs are removed  
considering log /var/log/exim/main.log  
  log does not need rotating (log has been rotated at 2020-5-19 15:23, that is not week ago yet)
considering log /var/log/exim/reject.log  
  log does not need rotating (log has been rotated at 2020-5-19 15:23, that is not week ago yet)

rotating pattern: /var/log/httpd/*log  after 1 days (3 rotations)  
empty log files are not rotated, old logs are removed  
considering log /var/log/httpd/access_log  
  log does not need rotating (log has been rotated at 2020-5-19 15:23, that is not day ago yet)
considering log /var/log/httpd/error_log  
  log does not need rotating (log has been rotated at 2020-5-19 15:23, that is not day ago yet)
not running postrotate script, since no logs were rotated  

rotating pattern: /var/log/nginx/*.log  after 1 days (3 rotations)  
empty log files are not rotated, old logs are removed  
considering log /var/log/nginx/access.log  
  log does not need rotating (log has been rotated at 2020-5-19 15:23, that is not day ago yet)
considering log /var/log/nginx/error.log  
  log does not need rotating (log has been rotated at 2020-5-19 15:23, that is not day ago yet)
not running postrotate script, since no logs were rotated  

rotating pattern: /var/log/ppp/connect-errors  after 1 days (5 rotations)  
empty log files are not rotated, old logs are removed  
considering log /var/log/ppp/connect-errors  
  log /var/log/ppp/connect-errors does not exist -- skipping

rotating pattern: /var/log/proftpd/*.log /var/log/xferlog  weekly (4 rotations)  
empty log files are not rotated, old logs are removed  
considering log /var/log/proftpd/controls.log  
  log does not need rotating (log has been rotated at 2020-5-19 15:23, that is not week ago yet)
considering log /var/log/xferlog  
  log /var/log/xferlog does not exist -- skipping
not running postrotate script, since no logs were rotated  

rotating pattern: /var/log/roundcubemail/*.log  30720 bytes (4 rotations)  
empty log files are not rotated, old logs are removed  
switching euid to 0 and egid to 48  
considering log /var/log/roundcubemail/*.log  
  log /var/log/roundcubemail/*.log does not exist -- skipping
switching euid to 0 and egid to 0  

rotating pattern: /var/log/cron  
/var/log/maillog
/var/log/messages
/var/log/secure
/var/log/spooler
 weekly (4 rotations)
empty log files are rotated, old logs are removed  
considering log /var/log/cron  
  log does not need rotating (log has been rotated at 2020-5-19 15:23, that is not week ago yet)
considering log /var/log/maillog  
  log does not need rotating (log has been rotated at 2020-5-19 15:23, that is not week ago yet)
considering log /var/log/messages  
  log does not need rotating (log has been rotated at 2020-5-19 15:23, that is not week ago yet)
considering log /var/log/secure  
  log does not need rotating (log has been rotated at 2020-5-19 15:23, that is not week ago yet)
considering log /var/log/spooler  
  log does not need rotating (log has been rotated at 2020-5-19 15:23, that is not week ago yet)
not running postrotate script, since no logs were rotated  

rotating pattern: /var/log/wpa_supplicant.log  30720 bytes (4 rotations)  
empty log files are not rotated, old logs are removed  
considering log /var/log/wpa_supplicant.log  
  log does not need rotating (log size is below the 'size' threshold)

rotating pattern: /var/log/yum.log  yearly (4 rotations)  
empty log files are not rotated, log files >= 30720 are rotated earlier, old logs are removed  
considering log /var/log/yum.log  
  log does not need rotating (log has been rotated at 2020-5-19 15:23, that is not year ago yet)

rotating pattern: /var/log/wtmp  monthly (1 rotations)  
empty log files are rotated, only log files >= 1048576 bytes are rotated, old logs are removed  
considering log /var/log/wtmp  
  log does not need rotating (log has been rotated at 2020-5-19 15:23, that is not month ago yet)
  log does not need rotating ('misinze' directive is used and the log size is smaller than the minsize value
rotating pattern: /var/log/btmp  monthly (1 rotations)  
empty log files are rotated, old logs are removed  
considering log /var/log/btmp  
  log does not need rotating (log has been rotated at 2020-5-19 15:23, that is not month ago yet)

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

После чего, можно выполнить проверку того, что создали:

[root@kvmde54-19861 ~]# logrotate -d /etc/logrotate.d/example-app
reading config file /etc/logrotate.d/example-app  
removing last 1 log configs  
Allocating hash table for state file, size 15360 B  

Handling 0 logs  

Создание конфигурации LogRotate

В этом примере мы имеем приложение, которое работает под пользователем testing, генерация журналов, которые хранятся в каталоге /home/testing/logs/. Нам нужно сделать ротацию этих журналов ежечасно, поэтому мы должны установить его за пределами структуры /etc/logrotate.d, представленной в Ubuntu.

Создадим через текстовый редактор конфигурационный файл в нашем каталоге.

nano /home/testing/logrotate.conf  

Затем вставьте следующую конфигурацию:

/home/testing/logrotate.conf
/home/testing/logs/*.log {
    hourly
    missingok
    rotate 24
    compress
    create
}

file

Сохраните и закройте файл.

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

Необходимо настроить конфигурацию в соответствии с вашим приложением.

Сделаем файл журнала чтобы проверить, что он работает:

cd ~  
mkdir logs  
touch logs/access.log  

Поскольку журналы принадлежат testing нам не нужно использовать sudo. Однако нам нужно указать файл состояния. Этот файл записывает, что logrotate видел и сделал в прошлый раз, так что он знает, что делать при следующем запуске.

Мы попросим Logrotate поместить файл состояния прямо в наш домашний каталог для этого примера. Мы можем указать где угодно, что доступно и удобно:

logrotate /home/testing/logrotate.conf --state /home/testing/logrotate-state --verbose --force  

Вывод

[testing@kvmde54-19861 ~]$ logrotate /home/testing/logrotate.conf --state /home/testing/logrotate-state --verbose --force  
reading config file /home/testing/logrotate.conf  
Allocating hash table for state file, size 15360 B  

Handling 1 logs  

rotating pattern: /home/testing/logrotate.conf  
/home/testing/logs/*.log  forced from command line (24 rotations)
empty log files are rotated, old logs are removed  
considering log /home/testing/logrotate.conf  
  log needs rotating
considering log /home/testing/logs/access.log  
  log needs rotating
rotating log /home/testing/logrotate.conf, log->rotateCount is 24  
dateext suffix '-2020051916'  
glob pattern '-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'  
renaming /home/testing/logrotate.conf.24.gz to /home/testing/logrotate.conf.25.gz (rotatecount 24, logstart 1, i 24),  
old log /home/testing/logrotate.conf.24.gz does not exist  
renaming /home/testing/logrotate.conf.23.gz to /home/testing/logrotate.conf.24.gz (rotatecount 24, logstart 1, i 23), 

–verbose распечатает подробную информацию о том, что делает Logrotate. Это первый раз, когда LogRotate видит этот файл журнала, так, насколько это известно, файлу ноль часов, и к нему не должно быть применена ротация.

Если мы посмотрим на файл состояния, мы увидим, что Logrotate записал информацию о запуске:

cat /home/testing/logrotate-state  

Вывод

[testing@kvmde54-19861 ~]$ cat /home/testing/logrotate-state
logrotate state -- version 2  
"/home/testing/logs/access.log" 2020-5-19-16:39:6
"/home/testing/logrotate.conf" 2020-5-19-16:39:6

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

Если вы хотите заставить LogRotate производить ротацию файла журнала, тогда надо использовать флаг –force:

logrotate /home/testing/logrotate.conf --state /home/testing/logrotate-state --verbose --force  

Далее, нужно настроить задание cron для запуска Logrotate каждый час. Откройте crontab пользователя:

crontab -e  

Откроется текстовый файл. Возможно, в файле уже есть некоторые комментарии, объясняющие ожидаемый основной синтаксис.
Переместите курсор на новую пустую строку в конец файла и добавьте следующее:

14 * * * * /usr/sbin/logrotate /home/testing/logrotate.conf --state /home/testing/logrotate-state  

Эта задача будет выполняться на 14 – й минуте каждого часа, каждый день.

Обновлено 19 мая 2020 г.