Home / Alt manpages / savelog(8)

  • savelog(8)
  • Admin command
  • linux

Rotate a Log Safely with savelog

You will finish with a repeatable way to rotate one log file, keep a defined number of copies, and check that the new log is ready for the next writer. The examples use savelog from Debianutils 5.17build1, installed on this machine.

Allow about fifteen minutes. You need a shell and a log file that you are allowed to read, rename and recreate. Rotating a service log can briefly affect the process writing it, so test with a disposable file first and use a maintenance window for a production service. Ordinary rotation does not need sudo when you own the file; changing ownership or writing in a protected directory does.

1. Check the installed command

Read the local command help and record the package version before putting an option into a script. This is an ordinary, read-only check:

$ command -v savelog
/usr/bin/savelog
$ dpkg-query -W -f='${Package} ${Version}\n' debianutils
debianutils 5.17build1
$ savelog --help
Illegal option --
Usage: savelog [-m mode] [-u user] [-g group] [-t] [-c cycle] [-p]
             [-j] [-C] [-d] [-l] [-r rolldir] [-n] [-q] file ...

This version prints usage for --help as an error because --help is not one of its options. Do not use that output as a script test. The installed manual also documents -J, -D and compression levels -1 through -9; use the exact local manual when building a version-sensitive script.

Checkpoint

Confirm the package version and the path you will rotate. Stop if the path is a symlink or points at a file whose ownership and permissions you have not checked.

2. Make a disposable test log

Use a temporary directory to see the naming and timing of a rotation without touching a service. The command below creates a non-empty log and asks for three saved versions:

$ work_dir=$(mktemp -d /tmp/savelog-test.XXXXXX)
$ printf 'first line\n' > "$work_dir/app.log"
$ savelog -c 3 "$work_dir/app.log"
Rotated `/tmp/savelog-test.XXXXXX/app.log' at Sat Sep 26 21:30:28 BST 2026.

The timestamp and temporary directory name will differ. Inspect the directory:

$ find "$work_dir" -maxdepth 1 -type f -printf '%f\n' | sort
app.log.0
$ file "$work_dir"/app.log.0
/tmp/savelog-test.XXXXXX/app.log.0: ASCII text

On the first run, the original file becomes app.log.0. Version 0 is deliberately left uncompressed because a process may still have it open. A new main file is not necessarily created by a plain rotation, so a service that expects its pathname to exist needs the next step.

3. Create the writer's new log

Use -t when the new main file must be created. It is also implied by -m, -u and -g:

$ printf 'current entry\n' > "$work_dir/app.log"
$ savelog -l -t -c 3 "$work_dir/app.log"
Rotated `/tmp/savelog-test.XXXXXX/app.log' at Sat Sep 26 21:31:10 BST 2026.
$ find "$work_dir" -maxdepth 1 -type f -printf '%f %s bytes\n' | sort
app.log 0 bytes
app.log.0 15 bytes
app.log.1 11 bytes

-l means do not compress any saved logs. Without it, versions above 0 are compressed with gzip by default, so a saved file will normally have a suffix such as .1.gz. The cycle count must be at least 2. With -c 3, old versions beyond the retained cycle are removed during rotation.

Checkpoint

Verify both the new app.log and the newest saved copy. If the main file is missing, do not restart the service yet; create it with touch only after checking its owner and mode, or rerun with -t.

4. Rotate a real log with the right compression

For a log owned by your account, this is the normal form:

$ savelog -c 7 -t /path/to/application.log
Rotated `/path/to/application.log' at Sat Sep 26 21:32:00 BST 2026.

Seven versions are kept by default, so specifying -c 7 makes that choice visible in a script. The newest saved copy is application.log.0 and later copies are compressed unless you add -l. Use -j for bzip2 or -J for xz. The manual warns that xz can use a very large amount of memory at higher compression levels, so do not select it casually on a busy or small host.

To use a separate directory for rotated files, provide an existing directory with -r:

$ install -d -m 0750 /var/log/application/archive
$ savelog -r /var/log/application/archive -c 7 -t /var/log/application/application.log

The install command and this rotation need elevated privileges when the directory belongs to root. Check the destination before running it. The old files move there; the main log remains at its original pathname.

5. Preserve permissions and ownership deliberately

Use -p when the rotated and newly created files should inherit the original log's owner, group and permissions:

$ stat -c '%n %a %U:%G' /var/log/application/application.log
/var/log/application/application.log 640 appsvc:adm
$ savelog -p -t -c 7 /var/log/application/application.log
$ stat -c '%n %a %U:%G' /var/log/application/application.log /var/log/application/application.log.0
/var/log/application/application.log 640 appsvc:adm
/var/log/application/application.log.0 640 appsvc:adm

The exact account names and modes are host-specific. If the application requires a fixed policy, -m 0640, -u appsvc and -g adm set the mode, owner and group and create the new file. These options change access to log data, so review them before copying a command into automation. Run the command as an account that can perform the requested ownership change.

6. Handle empty logs and date-based names

By default, savelog can rotate an empty file. Add -n when an empty file should be left alone:

$ : > /tmp/empty.log
$ savelog -n -t -c 3 /tmp/empty.log
$ find /tmp -maxdepth 1 -name 'empty.log*' -printf '%f\n'
empty.log

Use -d when date-stamped names are more useful than numbered copies. On this installation, the result looked like date.log.20260926213037; the timestamp will reflect the time of your run. -D can override the date format using the syntax understood by date. Treat that format as part of your retention and monitoring design, because scripts looking only for .0 will not find date-rolled files.

7. Verify and recover before touching a service

Check the exit status and list the resulting files immediately:

$ savelog -q -t -p -c 7 /path/to/application.log
$ printf 'savelog exit status: %s\n' "$?"
savelog exit status: 0
$ find /path/to -maxdepth 1 -name 'application.log*' -printf '%f\n' | sort

A zero status tells you that this invocation completed. It does not prove that the service has reopened the new file. Confirm the service's documented reopen or reload procedure, then inspect the new file after the service writes another entry. Do not blindly send a reload signal: it may be service-specific and can interrupt production traffic.

The manpage carries a serious warning: if a process is still writing to file.0 while savelog moves and compresses it to file.1, data could be lost. If the writer cannot reopen logs safely, stop and use the service's supported rotation mechanism instead. Recovery for an accidental rotation is to stop the writer, copy the saved file back to the expected pathname only after preserving a backup, and follow the service's normal restart or reopen procedure. Do not delete old copies until the new path and recent entries are confirmed.

Done means

  • The installed Debianutils version and savelog option syntax were checked.
  • A disposable log was rotated first, with the resulting names inspected.
  • The cycle count, compression method and empty-file policy match the requirement.
  • The new main log has the intended owner, group and permissions.
  • The service can reopen the new file, or a safer service-specific rotation method has been chosen.
  • Saved copies remain available until recent writes have been verified.