85

Is it possible to get logrotate to consider logfiles in a directory and all its subdirectories? (i.e. without explicitly listing the subdirectories.)

4 Answers 4

125

How deep do your subdirectories go?

/var/log/basedir/*.log /var/log/basedir/*/*.log {
    daily
    rotate 5
}

Will rotate all .log files in basedir/ as well as all .log files in any direct child of basedir. If you also need to go 1 level deeper just add another /var/log/basedir/*/*/*.log until you have each level covered.

This can be tested by using a separate logrotate config file which contains a constraint that will not be met (a high minsize) and then running log rotate yourself in verbose mode

logrotate -d testconfig.conf

the -d flag will list each log file it is considering to rotate.

3
  • 9
    Thanks! Looks like -d puts logrotate in dry run mode (i.e. doesn't actually change anything) actually. Dec 3, 2010 at 15:36
  • 2
    Not really directly relevant but probably useful to someone. the -f option tells logrotate to "force run". a bare word at the end of the command is a config file to use instead of the default. so logrotate -f /some/config means run with that config file, and always run even if the config file says it's not time to run yet. To my untrained eyes, and to my predecessor who put in a cron job with that, it seemed like -f was just specifying the config file. Quite confusing.
    – Dan Pritts
    Oct 5, 2015 at 16:39
  • 2
    it's actually debug -d, --debug Turns on debug mode and implies -v. In debug mode, no changes will be made to the logs or to the logrotate state file.
    – yahol
    Jan 25, 2021 at 9:04
5

It's old thread, but you can do the following:

/var/log/basedir/**/*.log {
    daily
    rotate 5
}

These two stars will match zero or more directories. You must be careful, though, how you define log files to be rotated, because you can rotate files that have been already rotated. I'll cite the manual of logrotate here.

Please use wildcards with caution. If you specify *, logrotate will rotate all files, including previously rotated ones. A way around this is to use the olddir directive or a more exact wildcard (such as *.log).

7
  • 6
    this wildcard pattern did not work for me. Logrotate 3.8.6 on RHEL 7.3
    – northben
    May 30, 2017 at 14:40
  • Maybe you should enable globstar before running logrotate. This will enable it for bash shopt -s globstar.
    – bat_ventzi
    Jun 5, 2017 at 9:15
  • I have the same problem. Logrotate 3.8.7 on Ubuntu 16.04.3. ls /var/log/basedir/**/*.log works as described, but logrotate doesn't. Aug 10, 2017 at 23:12
  • doesn't work for me either, on logrotate 3.11.0. I don't think that bash expansion has anything to do with logrotate wildcards. (except for similar syntax)
    – Thayne
    Jan 23, 2019 at 22:39
  • 1
    Not working. Please remove this answer or add a version where it dóes work.
    – Quisse
    Jan 8, 2020 at 7:50
5

In my case, the depth of subdirectories can change without warning, so I set up a bash script to find all subdirectories and create a config entry for each directory.

It's also important for me to keep the structure of subdirectories after rotation, which wildcards (i.e. @DanR's answer) didn't seem to do. If you're doing daily log rotations, you could put this script in a daily cron-job.

basedir=/var/log/basedir/
#destdir=${basedir} # if you want rotated files in the same directories
destdir=/var/log/archivedir/ #if you want rotated files somewhere else
config_file=/wherever/you/keep/it
> ${config_file} #clear existing config_file contents

subfolders = $(find ${basedir} -type d)

for ii in ${subfolders}
do
    jj=${ii:${#basedir}} #strip off basedir, jj is the relative path

    #append new entry to config_file
    echo "${basedir}${jj}/* {
        olddir ${destdir}${jj}/
        daily
        rotate 5
    }" >> ${config_file}

    #add one line as spacing between entries
    echo "\n" >> ${config_file}

    #create destination folder, if it doesn't exist
    [ -d ${destdir}${jj} ] || mkdir ${destdir}${jj}
done

Like @DanR suggested, test with logrotate -d

0

Took some trial and error but finally got my wildcard pattern working as I have log files in one folder followed by IP and then hostname and then actual log folder.

I have a second hard drive as a VM so I pointed the logs to use this path:

/mnt/logs/var/log/remotes/10.4.11.12/pve2-test

I have several remote servers listed in the remotes folder followed by it's host name in it's own folder. I didn't want to change this structure so figured out how to use the wildcard that actually works.

/mnt/logs/var/log/remotes/1*/**/*.log

I've tried /mnt/logs/var/log/remotes /** /** /*.log which didn't work. I am guessing because I was trying to do full wildcard followed with another full wildcard which it didn't like. (Pardon the extra spaces in the wildcard as it truncated in editing??)

Hope this helps.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .