#!/bin/bash # # A replacement of the logrotate's copytruncate method to use when: # * we haven't permission to change ownership, so the built-in copytruncate # method would fail (this is a bug in logrotate, I think); # * we haven't permission to reload the service, so the create new log method # doesn't work - the service would still write to the already rotated file. # # This script, when called as a prerotate script from logrotate configuration: # * copytruncates a file having $LOGEXT (see below) extesion and compresses it # (and returns with 1 exit code, thus, the logrotate will skip this file). # * does nothing with files having any other extensions - e.g .1, .2 and so on # (and returns with 0 exit code, thus, the logrotate can process this file); # # In other words, with default settings it simulates the effect of logrotate # configuration options below: # /*.log { # dateext # dateyesterday # dateformat %Y-%m-%d. # extension log # compress # copytruncate # [...] # } # but doesn't stop if failed to set the permissions during copytruncate. # # The script receives the file to process as it's first command line parameter. # Lack of the parameter it simply does nothing. # # Author: Kovács Zoltán # Kovács Zoltán # License: GNU/GPL v3+ (https://www.gnu.org/licenses/gpl-3.0.en.html) # 2023-06-18 v1.0 # new: forked from the "SMARTERP_skeleton" repository. # 2020-11-09 v0.1 Initial release # Configurable parameters - must be consistent with the logrotate configuration. # DATESTRING="$(date "+%Y-%m-%d" -d '1 day ago')" # Yesterday goes to the filename LOGEXT="log" # Processes only *.$LOGEXT files # Messages. MSG_MISSINGDEP="Fatal: missing dependency" # Checks the dependencies. TR=$(which tr 2>/dev/null) if [ -z "$TR" ]; then echo "$MSG_MISSINGDEP tr."; exit 1 ; fi for item in basename cp dirname gzip do if [ -n "$(which $item)" ] then export $(echo $item | "$TR" '[:lower:]' '[:upper:]')=$(which $item) else echo "$MSG_MISSINGDEP $item." >&2; exit 1; fi done # All dependencies are available via "$THECOMMAND" (upper case) call. # # An additional bugfix (use "$(which gzip)" instead of "$GZIP"): # https://www.gnu.org/software/gzip/manual/html_node/Environment.html GZIP="" # Lack of the parameter (unlikely) it simply does nothing. # The script returns an OK status, so the logrotate will continue. [[ -z "$1" ]] && exit 0 # Parses the parameter. LOGDIR="$("$DIRNAME" $1)" LOGFILE="$("$BASENAME" $1)" NEWFILE="${LOGFILE%.*}.$DATESTRING.${LOGFILE##*.}" # If the parameter doesn't point to a writeable file it simply does nothing. [[ ! -w "$LOGDIR/$LOGFILE" ]] && exit 0 # If the log's folder isn't writable it simply does nothing. [[ ! -w "$LOGDIR" ]] && exit 0 # If the extension doesn't match it simply does nothing. [[ "${LOGFILE##*.}" != "$LOGEXT" ]] && exit 0 # Cases above must handled by the logrotate itself. # The script returns an OK status, so the logrotate will continue. # Doesn't copy if it would overwrite something. # Returns an error status, so the logrotate won't process this file. [[ -e "$LOGDIR/$NEWFILE" ]] && exit 1 [[ -e "$LOGDIR/$NEWFILE.gz" ]] && exit 1 # Tries to copy the current logfile. "$CP" -p "$LOGDIR/$LOGFILE" "$LOGDIR/$NEWFILE" # >/dev/null 2>&1 # On error returns an error status so the logrotate won't process this file. [[ ! -r "$LOGDIR/$NEWFILE" ]] && exit 1 # Done with copy. Tries to empty the current logfile. Doesn't check the result. : >"$LOGDIR/$LOGFILE" # Compresses the rotated logfile. Doesn't check the result. "$(which gzip)" "$LOGDIR/$NEWFILE" #>/dev/null 2>&1 # Returns a fake error status to prevent the logrotate to process this file. exit 1 # That's all, Folks! :)