Ein von logrotate ausgeführtes Skript führt zu einem anderen Ergebnis als bei manueller Ausführung

Ein von logrotate ausgeführtes Skript führt zu einem anderen Ergebnis als bei manueller Ausführung

Ich möchte unsere Anwendungsprotokolle mit rotieren logrotate. Nach jeder Rotation wird ein Skript ausgeführt, das alle rotierten Protokolle in ein anderes Verzeichnis verschiebt. In habe ich beispielsweise /home/dev/logs/frontenddiese Protokolldateien:

webapp1-access.log
webapp2-access.log
anotherapp3-access.log
codename-access.log
...

Und meine Logrotate-Konfigurationsdatei:

$ cat app.daily
/home/dev/logs/frontend/*access.log {
   rotate 1
   daily
   copytruncate
   compress
   notifempty
   missingok
   lastaction
      bash /path/to/script.sh
   endscript
}

Und was script.sh macht, istErstellen Sie ein Verzeichnis basierend auf dem ProtokolldateinamenVerschieben Sie dann die rotierte Protokolldatei dorthin. Die webapp1-access.logwürde nach rotiert, webapp1-access.log.1.gzdann verschiebt das Skript sie nach /x/y/webbapp1/renamed.log.gz. Und so weiter für andere rotierte Protokolle.

Als ich Logrotate mit getestet habe logrotate -fv /path/to/config, funktionierte es perfekt wie erwartet. Dann habe ich die Logrotate-Konfigurationsdatei /etc/logrotate.d(als symbolischen Link) eingefügt.

Als ich am nächsten Tag in /x/ydeinem Verzeichnis nachgesehen habe, fand ich:

webbapp1/                       <---- created from initial logrotate -fv
webbapp1-access.log/            <---- Unexpected
anotherapp3/                    <---- created from initial logrotate -fv
anotherapp3-access.log/         <---- Unexpected
codename/                       <---- created from initial logrotate -fv
codename-access.log/            <---- Unexpected

Die *-access.log/Verzeichnisse werden von logrotate erstellt. Aber das logrotate -vf configmehrmalige Ausführen führt nicht zu diesem unerwarteten Ergebnis. Das passiert, wenn ich logrotate seine tägliche Rotation durchführen lasse.

Warum passiert das? Wie kann ich das beheben?


script.sh

#! /usr/bin/bash

exec 3>> /var/log/archived-log.log
[ "${1:-}" = "-d" ] && debug=1

environment="frontend"

rotateddir="/home/dev/logs/$environment"
destdir="/x/y"
[ "${debug:-}" ] && echo "DEST DIR: $destdir"

log() {
    timestamp=$(date +"%Y-%m-%d %H:%M:%S")
    echo "$timestamp: $1" >&3
}

for archive in $rotateddir/*.gz; do
    [ "${debug:-}" ] && echo "ARCHIVE: $archive"
    [ "${archive##*/}" = "*.gz"  ] && continue
    base_name=$(basename "$archive")
    [ "${debug:-}" ] && echo "BASENAME: $base_name"
    extension="${base_name##*.}"
    [ "${debug:-}" ] && echo "EXT: $extension"
    newdir_name="${base_name%-*}"
    [ "${debug:-}" ] && echo "NEWDIR_NAME: $newdir_name"
    tanggal=$(stat -c %y "$archive" | cut -d" " -f1 | { read dat; date -d $dat +%Y%m%d; })
    #jam=$(stat -c %y "$archive" | cut -d" " -f2 | { read dat; date -d $dat +%H%M; })
    newdir_path="$destdir/$newdir_name"
    [ "${debug:-}" ] && echo "NEWDIR_PATH: $newdir_path"
    #dest_archive="$newdir_path/$tanggal-$jam.log.$extension"
    dest_archive="$newdir_path/$tanggal.log.$extension"
    [ "${debug:-}" ] && echo "DEST_ARCHIVE: $dest_archive"

    [ ! -d "$newdir_path" ] && {
        if [ "${debug:-}" ]; then
            echo "Would create $newdir_path"
        else
            mkdir -p "$newdir_path"
            log "Created directory: $newdir_path"
        fi
    }

    [ ! -f "$dest_archive" ] && {
        if [ "${debug:-}" ]; then
            echo "Would move $archive to $dest_archive"
        else
            rsync -a --no-owner --no-group --remove-source-files "$archive" "$dest_archive"
            #cp -u --no-preserve=mode,ownership "$archive" "$dest_archive" && rm -f "$archive"
            log "Relocated $archive to $dest_archive"
        fi
    }

    rotates=$(ls -1 "$newdir_path" | wc -l )
    [ "$rotates" -ge 7 ] && {
        oldest=$(ls -t "$newdir_path" | tail -1)
        if [ "${debug:-}" ]; then
            echo "Would delete the oldest archive: $oldest"
        else
            rm -f "$newdir_path/$oldest"
            log "Deleted oldest archive of $base_name : $oldest"
        fi
    }   
done

exit 0



Aktualisieren

Ich weiß immer noch nicht, warum das passiert, aber schließlich habe ich beschlossen, das Skript einige Minuten nach der Rotation per Cron auszuführen.

Ich vermute, dass dieser Teil meines "script.sh" newdir_name="${base_name%-*}"nicht gut ausgewertet wird logrotate. Aber es funktionierte wie erwartet, wenn ich es zwangsweise ausführte mitlogrotate -fv config

Antwort1

Es stellte sich heraus, dass logrotate das Skript ausführt shund mein Skript Bashishms enthält.

Aus der Manpage:

letzte Aktion/Endskript

Die Linien zwischenletzte AktionUndEndskript(beide müssen in eigenen Zeilen stehen) werden ausgeführt (mit/bin/sh) ...

Am Ende führe ich mein Skript crontabeinige Minuten nach dem Logrotate aus.

verwandte Informationen