# Understanding logrotate utility

Logs are useful when you want to track usage or troubleshoot an application. As more information gets logged, however, log files use more disk space. Over time a log file can grow to unwieldy size. Running out of disk space because of a large log file is a problem, but a large log file can also slow down the process of resizing or backing up your virtual server. Additionally, it’s hard to look for a particular event if you have a million log entries to skim through. So it’s a good idea to keep log files down to a manageable size, and to prune them when they get too old to be of much use.

Fortunately, the logrotate utility makes log rotation easy. “Log rotation” refers to the practice of archiving an application’s current log, starting a fresh log, and deleting older logs. The system usually runs logrotate once a day, and when it runs it checks rules that can be customized on a per-directory or per-log basis.

## How logrotate works

The system runs logrotate on a schedule, usually daily. On most distributions, the script that runs logrotate daily is located at /etc/cron.daily/logrotate.

Some distributions use a variation. For example, on Gentoo the logrotate script is located at /etc/cron.daily/logrotate.cron.

If you want logrotate to run more often (for hourly log rotation, for example) you need to use cron to run logrotate through a script in /etc/cron.hourly.

When logrotate runs, it reads its configuration files to determine where to find the log files that it needs to rotate, how often the files should be rotated, and how many archived logs to keep.

## logrotate.conf

The main logrotate configuration file is located at /etc/logrotate.conf.

The file contains the default parameters that logrotate uses when it rotates logs. The file is commented, so you can skim it to see how the configuration is set up. Several of the specific commands in that file are described later in this article.

Note that one line in the file reads:

include /etc/logrotate.d

That directory contains most of the application-specific configuration files.

## logrotate.d

Use the following command to list contents of the directory that stores application-specific log settings:

ls /etc/logrotate.d

Depending on how much is installed on your server, this directory might contain no files or several. In general, applications that are installed through your package manager will also create a config file in /etc/logrotate.d.

Example:

/var/log/mail.log {
weekly
rotate 5
compress
create 0644 postfix postfix
}

The size and rotation of /var/log/mail.log is managed according to the directives instantiated between the braces. The above configuration rotates logs every week, saves the last five rotated logs, compresses all of the old log files with gzip, and recreates the log files with permissions of 0644 and postfix as the user and group owner. These specific configuration options override global configuration options which are described below.

Remember, the configuration files for applications in /etc/logrotate.d inherit their defaults from the main /etc/logrotate.conf file.

### Log files

A log file and its rotation behavior are defined by listing the log file (or files) followed by a set of commands enclosed in curly brackets. Most application configuration files will contain just one of these blocks, but it’s possible to put more than one in a file, or to add log file blocks to the main logrotate.conf file.

You can list more than one log file for a block by using a wildcard in the name or by separating log files in the list with spaces. For example, to specify all files in the directory /var/foo that end in .log, and the file /var/bar/log.txt, you would set up the block as follows:

/var/foo/*.log /var/bar/log.txt {
...
}

### Rotate count

The rotate command determines how many archived logs are returned before logrotate starts deleting the older ones. For example:

rotate 4

This command tells logrotate to keep four archived logs at a time. If four archived logs exist when the log is rotated again, the oldest one is deleted to make room for the new archive.

### Rotation interval

You can specify a command that tells logrotate how often to rotate a particular log. The possible commands include:

daily
weekly
monthly
yearly

If a rotation interval is not specified the log will be rotated whenever logrotate runs (unless another condition like size has been set).

If you want to use a time interval other than the defined ones, you need to use cron to create a separate configuration file. For example, if you want to rotate a particular log file hourly, you could create a file in /etc/cron.hourly (you might need to create that directory too) that would contain a line like the following:

/usr/sbin/logrotate /etc/logrotate.hourly.conf

Then you would put the configuration for that hourly run of logrotate (the log file location, whether or not to compress old files, and so on) into /etc/logrotate.hourly.conf.

### Size

You can use the size command to specify a file size for logrotate to check when determining whether to perform a rotation. The format of the command tells logrotate what units you’re using to specify the size:

size 100K
size 100M
size 100G

The first example would rotate the log if it gets larger than 100 kilobytes, and the second if it’s larger than 100 megabytes, and the third if it’s over 100 gigabytes. I don’t recommend using a limit of 100G, mind you, the example just got a little out of hand there.

The size command takes priority over and replaces a rotation interval if both are set.

### Compression

If you want archived log files to be compressed (in gzip format), you can include the following command, usually in /etc/logrotate.conf:

compress

Compression is normally a good idea, because log files are usually all text and text compresses well. If, however, you have some archived logs that you don’t want to compress, but you still want compression to be on by default, you can include the following command in an application-specific configuration:

nocompress

### delaycompress

Another command of note in regard to compression is as follows:

delaycompress

This command is useful if you want to compress the archived logs, but want to delay the compression. When delaycompress is active, an archived log is compressed the next time that the log is rotated. This can be important when you have a program that might still write to its old log file for a time after a fresh one is rotated in. Note that delaycompress works only if you have compress in your configuration.

### copytruncate

Truncate the original log file to zero size in place after creating a copy, instead of moving the old log file and optionally creating a new one. It can be used when some program cannot be told to close its logfile and thus might continue writing (appending) to the previous log file forever. Note that there is a very small time slice between copying the file and truncating it, so some logging data might be lost. When this option is used, the create option will have no effect, as the old log file stays in place.

### Postrotate

Logrotate runs the postrotate script after the log file is rotated. You usually want to use this script to restart an application after the log rotation so that the app can switch to a new log.

postrotate
/usr/sbin/apachectl restart > /dev/null
endscript

>/dev/null tells logrotate to pipe the command’s output to nowhere. In this case, you don’t need to view the output if the application restarted correctly.

The postrotate command tells logrotate that the script to run, starts on the next line, and the endscript command says that the script is done.

Normally, the absolute path to the log file is passed as first argument to the script. If sharedscripts is specified, whole pattern is passed to the script.

### Prerotate

To run a command before rotation begins, use a directive similar to the following:

prerotate
touch /srv/www/example.com/application/tmp/stop
endscript

The lines between prerotate and endscript (both of which must appear on lines by themselves) are executed (using /bin/sh) before the log file is rotated and only if the log will actually be rotated.

Remember that in postrotate and prerotate command all lines between prerotate and endscript will be executed.

### Sharedscripts

Normally logrotate runs the prerotate and postrotate scripts every time it rotates a log. This is also true for multiple logs that use the same configuration block. For example, a web server configuration block that refers to both the access.log and the error.log will, if it rotates both, run the postrotate script twice (once for each file rotated). If both files are rotated, the web server is restarted twice.

To keep logrotate from running that script for every log, you can include the following command:

sharedscripts

This command tells logrotate to check all the logs for that configuration block before running the postrotate script. If one or both of the logs is rotated, the postrotate script runs only once. If none of the logs is rotated, the postrotate script doesn’t run.

# Testing logrotate

## Debug

The debug flag, -d, tells logrotate to go through the motions of rotating logs but not actually rotate them. It can be handy if you want to test a new config file but don’t want any actual log rotation run when you do (if you’re working on a production server, for example).

The debug flag is good for checking that the config file is formatted properly and that logrotate can find the log files it would rotate. However, since it doesn’t actually run the rotations it doesn’t test some parts of the process like the postrotate scripts.

~]$logrotate -d /etc/logrotate.d/postgresql-common reading config file /etc/logrotate.d/postgresql-common Handling 1 logs rotating pattern: /var/log/postgresql/*.log after 1 days (10 rotations) empty log files are not rotated, old logs are removed switching euid to 0 and egid to 0 considering log /var/log/postgresql/postgresql-9.4-main.log log does not need rotating switching euid to 0 and egid to 1000 ## Verbose The verbose flag, -v, tells logrotate to say what it’s doing while it’s doing it. It’s very useful when trying to find out why logrotate doesn’t rotate a log when you want it to. ## Force The force flag, -f, forces logrotate to rotate all logs when it runs, whether or not they would normally need to be rotated at that time. If you want to thoroughly test logrotate’s configs this is the flag to use. Just remember that logrotate will be rotating logs and deleting old ones according to the configuration you’ve set up, so don’t accidentally rotate out a recent log you needed to keep. ## How logrotate remembers How does logrotate exactly handle “daily”? Judging by the timestamps on my systems, logrotate does its daily log rotation when logrotate is run by cron. However, if I run it earlier than that it doesn’t rotate the files. How does logrotate know if should rotate them or not, does it keep a history or perhaps use timestamps? How make logrotate decision if log rotate or no? Record of last time when logrotate make log rotate is in /var/lib/logrotate/status file for debian linux distros. That file is where logrotate stores information about when it last rotated each log file. If you look inside you’ll see something like: ~]$ cat /var/lib/logrotate/status
logrotate state -- version 2
"/var/log/syslog" 2019-6-5-6:25:6
"/var/log/postgresql/postgresql-9.4-main.log" 2019-6-5-6:25:6
"/var/log/auth.log" 2015-5-16-6:0:0
...

It’s a straightforward format - the log file location is on the left, and the date when it was last rotated is on the right.

If you want to check logrotate out with a particular log file but don’t want to force everything to rotate, you can delete the log’s entry from the logrotate status file. Then when you run logrotate normally it should create a new entry for the log with today’s date (even though it may not actually rotate the log - it uses that first run as a baseline if it’s just interval-based).

Logrotate doesn’t seem to care at what time of day it’s run; even if it usually runs at 23:55, if you were to run it at 01:30 instead, it would still rotate files marked daily and last done yesterday; but having done so it would put today’s date into the state file (against any rotated files), so a second run at 23:55 would do nothing.