Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ The image ships with `archive-cron-logs`, a log archiving script designed for th
- Additional archives for adjacent periods are created so archived ranges do not intersect the active period.
- **Recent logs preservation**: The script skips the newest `target_count` log files to keep the latest logs easy to read.
- **Naming**: When all files in a group belong to the same task, the task name is appended to the archive name as shown above.
- **Directory layout**: Archives are grouped by year in subdirectories (e.g. `2025-01-01_taskname.tar.gz` is stored as `2025/01-01_taskname.tar.gz`). The script also discovers existing archives in both the flat directory and year subdirs.

You can schedule archiving via container labels, for example in `docker-compose`:

Expand Down
39 changes: 36 additions & 3 deletions archive-cron-logs-functions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,47 @@ find_newest_archive() {
return 1
fi

# Build timestamp:file pairs and sort newest->oldest, then take the first entry (newest)
# Build timestamp:file pairs and sort newest->oldest, then take the first entry (newest).
# Look in both flat dir ($folder/*.tar.gz) and year subdirs ($folder/*/*.tar.gz).
local newest_archive=""
shopt -s nullglob
while IFS= read -r pair; do
# Take the first entry (newest after reverse sort)
newest_archive=$(echo "$pair" | cut -d: -f2-)
break
done < <(
for archive_file in "$folder"/*/*.tar.gz; do
[ -f "$archive_file" ] || continue
local year_subdir
year_subdir=$(basename "$(dirname "$archive_file")")
local basename_archive
basename_archive=$(basename "$archive_file")
local name_without_ext="${basename_archive%.tar.gz}"
local period_key="${year_subdir}-${name_without_ext}"
local timestamp=""
if [[ "$period_key" =~ ^([0-9]{4})(_.*)?$ ]]; then
local year="${BASH_REMATCH[1]}"
timestamp="${year}0101000000"
elif [[ "$period_key" =~ ^([0-9]{4})-([0-9]{2})(_.*)?$ ]]; then
local year="${BASH_REMATCH[1]}"; local month="${BASH_REMATCH[2]}"
timestamp="${year}${month}01000000"
elif [[ "$period_key" =~ ^([0-9]{4})-([0-9]{2})-([0-9]{2})(_.*)?$ ]]; then
local year="${BASH_REMATCH[1]}"; local month="${BASH_REMATCH[2]}"; local day="${BASH_REMATCH[3]}"
timestamp="${year}${month}${day}000000"
elif [[ "$period_key" =~ ^([0-9]{4})-([0-9]{2})-([0-9]{2})_([0-9]{2})(_.*)?$ ]]; then
local year="${BASH_REMATCH[1]}"; local month="${BASH_REMATCH[2]}"; local day="${BASH_REMATCH[3]}"; local hour="${BASH_REMATCH[4]}"
timestamp="${year}${month}${day}${hour}0000"
elif [[ "$period_key" =~ ^([0-9]{4})-([0-9]{2})-([0-9]{2})_([0-9]{2})-([0-9]{2})(_.*)?$ ]]; then
local year="${BASH_REMATCH[1]}"; local month="${BASH_REMATCH[2]}"; local day="${BASH_REMATCH[3]}"; local hour="${BASH_REMATCH[4]}"; local minute="${BASH_REMATCH[5]}"
timestamp="${year}${month}${day}${hour}${minute}00"
elif [[ "$period_key" =~ ^([0-9]{4})-([0-9]{2})-([0-9]{2})_([0-9]{2})-([0-9]{2})-([0-9]{2})_UTC(_.*)?$ ]]; then
local year="${BASH_REMATCH[1]}"; local month="${BASH_REMATCH[2]}"; local day="${BASH_REMATCH[3]}"; local hour="${BASH_REMATCH[4]}"; local minute="${BASH_REMATCH[5]}"; local second="${BASH_REMATCH[6]}"
timestamp="${year}${month}${day}${hour}${minute}${second}"
fi
if [ -n "$timestamp" ]; then
printf '%s:%s\n' "$timestamp" "$archive_file"
fi
done
for archive_file in "$folder"/*.tar.gz; do
[ -f "$archive_file" ] || continue
local basename_archive
Expand Down Expand Up @@ -55,8 +88,8 @@ find_newest_archive() {
if [ -n "$timestamp" ]; then
printf '%s:%s\n' "$timestamp" "$archive_file"
fi
done | LC_ALL=C sort -r
)
done
) | LC_ALL=C sort -r
shopt -u nullglob

if [ -n "$newest_archive" ]; then
Expand Down
20 changes: 18 additions & 2 deletions archive-cron-logs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,14 @@ fi
previous_period=""
newest_archive=$(find_newest_archive "$CRON_LOG_DIR")
if [ -n "$newest_archive" ]; then
archive_basename=$(basename "$newest_archive" .tar.gz)
archive_parent=$(dirname "$newest_archive")
archive_base=$(basename "$newest_archive" .tar.gz)
if [ "$archive_parent" != "$CRON_LOG_DIR" ]; then
year_subdir=$(basename "$archive_parent")
archive_basename="${year_subdir}-${archive_base}"
else
archive_basename="$archive_base"
fi
previous_period=$(parse_previous_period_from_archive_name "$archive_basename")
fi

Expand Down Expand Up @@ -110,7 +117,16 @@ while :; do
if [ -n "$common_task" ]; then
archive_name="${archive_name}_${common_task}"
fi
archive_path="$CRON_LOG_DIR/${archive_name}.tar.gz"
# Group archives by year subdirectory: 2025-01-01_task -> 2025/01-01_task.tar.gz
archive_year="${archive_name:0:4}"
if [ "${#archive_name}" -gt 4 ]; then
archive_rest="${archive_name:5}"
else
archive_rest="$archive_name"
fi
archive_year_dir="$CRON_LOG_DIR/$archive_year"
mkdir -p "$archive_year_dir"
archive_path="$archive_year_dir/${archive_rest}.tar.gz"

rel_files=()
while IFS= read -r f; do
Expand Down
Loading