Logrotate is a system utility that controls the automatic rotation and compression of log files. If files have not been rotated, compressed and periodically deleted during long-term server operation, they may sooner or later take up all available memory space.

    Logrotate is installed by default on the server and is configured to handle log rotation for all installed packages and applications.

    Logrotate version check:

    logrotate --version  
    

    The output of the command will be

    [[email protected] ~]# logrotate --version
    logrotate 3.8.6  
    

    The default configuration of Logrotate is stored in two paths:

    • The main configuration file - /etc/logrotate.conf.
    • To create settings for individual logs - use directory /etc/logrotate.d

    Let's take a look at the Logrotate configuration file /etc/logrotate.d:

    nano /etc/logrotate.conf  
    

    The output of the command will be

    # 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 also be configured here.
    include /etc/logrotate.d/web  
    

    This file contains the configuration blocks for two different log files in the directory. Both blocks have the same options. Any options not specified in these configuration blocks inherit the default values or values set in /etc/logrotate.conf

    Basic log management and processing directives:

    • monthly - rotation once a month. Possible variants daily, weekly, monthly, size;
    • notifempty - do not rotate empty log file.
    • rotate - specifies how many old logs to keep, the number is passed in parameters;
    • create - specifies that you must create an empty log file after moving the old one;
    • dateext - adds rotation date before old log header;
    • compress - specifies that the log should be compressed;
    • delaycompress - does not compress the last and penultimate log;
    • extension - saves original log file after rotation, if it has the specified extension;
    • mail - Send Email after rotation;
    • maxage - to rotate logs if they are older than specified;
    • missingok - do not output errors if log file does not exist;
    • olddir - move old logs to a separate folder;
    • postrotate/endscript - execute random commands after rotation;
    • start - number from which you will start numbering the old logs;
    • size - the size of the log when it will be moved;

    Two options can be used to manage log files for applications:

    • Create a new Logrotate configuration file and place it in /etc/logrotate.d/. It will run daily as the root user along with all other standard LogRotate tasks.
    • Create a new configuration file and run it with the default LogRotate settings in Ubuntu

    Create configuration in /etc/logrotate.d/

    As an example, let's configure updates for a server that writes logs to the access.log and error.log files located in /var/log/example-app/

    To add the configuration directory /etc/logrotate.d/, open a new file:

    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
    }
    

    Description of the directives:

    • create 0640 www-data www-data - this command will create a new empty log file after rotation with specified permissions (0640), owner ( www-data) and groups (www-data);
    • sharedscripts - this option means that any scripts added to the configuration will only run once per run after the files have been compressed, not for each individual updated file. Because our configuration will match two log files (access.log and error.log), the script specified in postrotate will only run once;
    • postrotate to endscript - the script in this block will be run after the log file is updated. In the example, the application is reloaded

    After configuring it according to the requirements, you can run the test with the command:

    sudo logrotate /etc/logrotate.conf --debug  
    
    [[email protected] ~]# 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 a 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 a 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 day (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 a 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 a day ago yet)
    not running postrotate script, since no logs were rotated  
    
    rotating pattern: /var/log/nginx/*.log after 1 day (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 a 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 a day ago yet)
    not running postrotate script, since no logs were rotated  
    
    rotating pattern: /var/log/ppp/connect-errors after 1 day (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 a 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  
    
    the following 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 a 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 a 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 a 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 a 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 months 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 months ago yet)
    
    

    As a result, the logrotate utility will be called, pointing to the standard configuration file in debug mode.
    The console will display information about which files logrotate is processing at the moment. The standard Logrotate configuration will be performed once a day, including new configuration.

    After that, you can check what you have created:

    [[email protected] ~]# 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  
    

    Create LogRotate configuration

    In this example, we have an application that runs under the user testing, generating logs that are stored in the /home/testing/logs/ directory. We need to make these logs rotate hourly, so we need to set it outside the /etc/logrotate.d structure presented in Ubuntu.

    Let's create a configuration file in our directory using a text editor

    nano /home/testing/logrotate.conf  
    

    Then insert the following configuration:

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

    file

    Save and close the file

    This configuration will rotate files hourly, compressing and saving the twenty-four old logs and creating a new log file to replace the rotated one.

    It is necessary to customize the configuration to suit your application.

    Let's make a log file to check that it works:

    cd ~  
    
    mkdir logs  
    
    touch logs/access.log  
    

    Since the logs belong to testing we don't need to use sudo. However, we do need to specify a status file. This file records what logrotate saw and did last time, so it knows what to do the next time it runs

    We will ask Logrotate to put the status file directly in our home directory for this example. We can specify anywhere that is available and convenient:

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

    Output

    [[email protected] ~]$ 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  
    
    handling 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 will print detailed information about what Logrotate is doing. This is the first time LogRotate has seen this log file, so as far as we know, the file has zero hours, and no rotation should be applied to it.

    If we look at the status file, we can see that Logrotate has recorded startup information:

    cat /home/testing/logrotate-state  
    

    The output is

    [[email protected] ~]$ 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 noted that it had seen the logs, and when it last looked at their rotation. If you run the same command, one hour later, the log is rotated as expected.

    If you want to force LogRotate to rotate the log file, then you must use the -force flag:

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

    Next, you need to configure a cron job to run Logrotate every hour. Open a user's crontab:

    crontab -e  
    

    This opens a text file. The file probably already has some comments explaining the expected basic syntax
    Move the cursor to a new blank line at the end of the file and add the following:

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

    This task will run on the 14th minute of every hour, every day.