Tuesday, September 8, 2020

bash script to rotate logs without restarting process

 The problem with Linux logrotate is that it requires root access to modify its configuration files, and it sends a HUP signal to the process generating the log expecting it to restart and recreate the log file after it has been rotated. I didn't have root access on the server where I needed to rotate logs, and the HUP signal (kill -1) didn't necessarily cause the process to restart and recreate the log file rotated.

The following bash script (saved as rotateLog.sh) can be run as a non-root user and doesn't need the process to restart. It isn't as seamless as logrotate, but it gets the job done when your main priority is to prevent a log file from taking all the drive space.

In crontab, you would invoke it using:

<path to rotateLogs.sh>/rotateLog.sh <path to log file being rotated>

By default it saves up to 20 historical files and rotates if the size of the log file is greater than 20MB, but you can change those numbers as needed:



#!/bin/bash

LOGFILEPATH=$1

MAXLOGS=20
MAXSIZE=20480000c

if [ -z "$1" ]; then
   echo "Not executed. No log file path passed as first parameter."
elif [ ! -f "$LOGFILEPATH" ]; then
   echo "Not executed. Log file path doesn't exist."
else
   PREFIX="${LOGFILEPATH%.*}"
   EXTENSION="${LOGFILEPATH##*.}"
   if [[ $(find $LOGFILEPATH -type f -size +$MAXSIZE 2>/dev/null) ]]; then
      ls -1tdq $PREFIX*.$EXTENSION | tail -n +$MAXLOGS | xargs rm -f
      NOW=$(date +_%y.%m.%d_%H.%M.%S)
      cp $LOGFILEPATH $PREFIX$NOW.$EXTENSION
      cat /dev/null > $LOGFILEPATH
   fi
fi