Tuesday, May 26, 2015

Logfile Rotation, and Counting Cars

Recently, fads changed in logfile rotation -- what a hot topic!

In RHEL5, it seems, logfiles were rotated very simply:  1, 2, 3.  Maybe gzipped too:  1.gz, 2.gz, 3.gz . This is a very simple arrangement:

  1. It's simpler to predict for humans:  3 follows 2 as often as 2.gz follows 1.gz .  
  2. It's simpler to use as a rotational algorithm
  3. This means it's simpler to use in scripting and automation.
But the new fad is worrisome:  Logs are rotated with date suffixes, as if we can't 'head -1' or 'tail -1', and maybe need the filename to reflect one of the dates on the logfiles;  the last day it was around, because 'tail -1' is so hard, perhaps?

Now logs end up like:

/var/log/messages-20150501
/var/log/messages-20150508
/var/log/messages-20150522

Hey, now -- what happened to the logfile from 20150515?  Well, it wasn't required, as logrotate will skip rotating a logfile which wasn't full enough and thus worthy of rotation. 

If we believe it takes slightly more effort to calculate a timestamp than to simply increment a counter, we have a process evolved to where it's harder, dumber, and useless.

I'll bet this started with someone who enjoys and uses systemd.

So here's a fix.  I used it only today, so it's been tested a whopping once, (aka twice as long as systemd), but it may actually work (hey, systemd works as an eyesore of a monolithic failbot very well, thanks, so you lay off; it's the kind of drooling, three-legged marmoset that any loving mother would be proud to hang on the fridge, albeit the back).

So you've fixed the config in logrotate so it'll name things like we have a clue:
echo nodateext > /etc/logrotate.d/aa-nodateext
(Please don't ask me why we're not hacking up /etc/logrotate.conf like someone too clueless about enterprise linux to know better. I may hurt you.)

Once you've corrected the behaviour, it's time to clean up the mess.  This script seeks out badly-named logfiles - most of them - and renames them properly.  That's it.

Yeah, it looks like crap.  It's quick, and I did it when I had some spare time today.  And now I intend to run it on a bajillion machines tomorrow.  I may even hook it into the %post script in my bish-logrotate-no_dateExt_you_Idiots RPM.  It could be the perfect quick-fix.

::::::::::::::
remediate-logfile-names.sh
::::::::::::::
#!/bin/sh
# -*- compile-command: "sh remediate-logfile-names.sh" -*-
# $Id: remediate-logfile-names.sh,v 1.2 2015/05/26 17:16:07 root Exp $

# locate the logrotate files we care about
find /etc/logrotate.d \
    -name \*~ -prune -o \
    -name \*.rpm\* -prune -o \
    -name syslo\* -prune -o \
    -type f \
    | sort \
    | \
    xargs -n1 sed -ne '
# prune the open-bracket on many logfile spec lines
/^\//{s/[{]//;p
} ' \
    | \
    while read fn trash; do
        case $fn in
            (/*)
                find $fn-201[0-9][0-9][0-9][0-9][0-9] -type f 2>/dev/null | \
                    grep -n "$fn" \
                    | awk -F: -v gz=${gz:0} '
{
  f=gensub(/-201.*$/,"",1,$2)"."$1
  print "mv "$2" "f
}
'
                ;;
            (compress)
                gz=1
                ;;
        esac
    done \
        | tee /dev/stderr \
        | sh

And that's about it.   Enjoy.  And if you want to know why you don't just hand-hack logrotate.conf, then toss me a comment.  

 - bish

Labels: , , ,