commit c99d796cd9ab9ab6073228d7d7486e1198508ebf Author: allan Date: Wed Jan 28 10:31:58 2026 +0100 latest commit diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3eaaa81 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Allan Christensen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..03768c0 --- /dev/null +++ b/README.md @@ -0,0 +1,260 @@ +# Clear Logfiles for Ubuntu 24.04 Server +[![OS](https://img.shields.io/badge/ubuntu-24.04-E95420)](#) +[![Shell](https://img.shields.io/badge/shell-bash-121011)](#) +[![Feature](https://img.shields.io/badge/feature-log_cleanup-0078D7)](#) +[![License](https://img.shields.io/badge/License-MIT-green)](./LICENSE) + +Install log cleanup and logfile reporting on Ubuntu 24.04 server. + +Not a demo, not a quick hack. +This script is built for production systems and safe unattended execution. + +--- + +## Why this installer exists + +Ubuntu systems accumulate rotated logfiles over time. +While `logrotate` handles rotation, old rotated logs are not automatically removed, and custom or installer-generated logs can grow unnoticed. + +Disk space is rarely the real problem. +Operator clarity is. + +An unmanaged `/var/log` directory becomes noisy over time and increases the risk of misreading timestamps or confusing old incidents with new ones during troubleshooting — especially under pressure. + +In environments without centralized log storage, keeping `/var/log` clean ensures it remains a usable, live operational workspace. + +--- + +## What this script does + +✔ Scans `/var/log` recursively +✔ Deletes classic rotated logfiles created by logrotate +✔ Detects and reports large unrotated logfiles +✔ Detects non-logrotate numeric logfiles (installer and debug logs) +✔ Writes a full execution report to a logfile +✔ Designed for unattended cron execution + +--- + +## What this script does NOT do + +It won’t stop you from running the script without reading the documentation like there’s no tomorrow. +Skip the README, and whatever happens next is your headache, not a bug report. + +--- + +## 1. Download + +``` +git clone https://git.x-files.dk/system/clear-log-ubuntu.git +``` + +--- + +``` +cd clear-log-ubuntu +``` + +--- + +## 2. Install + +``` +sudo cp clear-log-files /usr/local/sbin/ +``` + +--- + +## Recommended first run + +The script is published in dry-run mode by default so nothing gets deleted. + +Run the script manually the first time. + +``` +sudo /usr/local/sbin/clear-log-files +``` + +Review the generated report in: + +``` +/var/log/clear-log-files.log +``` + +Once you are satisfied with the behavior, edit the script and set: + +``` +dryrun=false +``` + +Only then should the script be deployed via cron. + +--- + +## Cron usage + +Once verified, add a weekly cron job. This can quickly be done from the command line like this: + +``` +sudo tee /etc/cron.d/clear-log-files >/dev/null </dev/null 2>&1 + +EOF +``` + +## Configuration + +The two most important variables are defined at the top of the script. + +``` +dryrun=true +extended_cleanup=false +``` + +### dryrun + +- `true` + Default. No files are removed. All actions are simulated and reported. + +- `false` + Enables real cleanup. Intended for cron usage after verification. + +### extended_cleanup + +- `false` + Non-logrotate numeric logs are reported only (default and recommended). + +- `true` + Non-logrotate numeric logs are deleted during real runs. + +Deletion of extended logs requires both: +- `dryrun=false` +- `extended_cleanup=true` + +This is intentional. + +--- + +## Script output + +Each run writes a full report to: + +``` +/var/log/clear-log-files.log +``` + +The report includes: +- which files were removed +- which files were reported only +- warnings about large active logfiles +- execution timestamp and configuration state + +This makes audits and troubleshooting straightforward. + +--- + +## Logfile cleanup policy + +The script separates logfiles into three distinct classes. + +### Classic rotated logs (auto-removed) + +Examples: + +``` +auth.log.1 +auth.log.2.gz +kern.log.4.gz +dpkg.log.1 +``` + +--- + +### Extended rotated logs (reported only by default). + +Examples: + +``` +subiquity-client-debug.log.1946 +installer-info.log.1990 +customapp.log.999 +``` + +These files are not created by `logrotate`. + +By default, they are detected and reported but not deleted. Setting extended_cleanup to true changes this. + +--- + +### Large unrotated logs (warnings only) + +Any active `.log` file exceeding the configured size threshold is reported as a warning no action is taken. + +--- + +### What this script will "NEVER" delete are: + +Kernel logs and audit logs. These are allways kept for forensic needs. This is intentionally by design. + +--- + +## Configuration + +The two most important variables are defined at the top of the script. + +``` +dryrun=true +extended_cleanup=false +``` + +### dryrun + +- `true` + Default. No files are removed. All actions are simulated and reported. + +- `false` + Enables real cleanup. Intended for cron usage after verification. + +### extended_cleanup + +- `false` + Non-logrotate numeric logs are reported only (default and recommended). + +- `true` + Non-logrotate numeric logs are deleted during real runs. + +Deletion of extended logs requires both: +- `dryrun=false` +- `extended_cleanup=true` + +This is intentional. + +--- + +## Script output + +Each run writes a full report to: + +``` +/var/log/clear-log-files.log +``` + +The report includes: +- which files were removed +- which files were reported only +- warnings about large active logfiles +- execution timestamp and configuration state + +This makes audits and troubleshooting straightforward. + +--- + +### More Information + +More guides and documentation can be found on [wiki.x-files.dk](https://wiki.x-files.dk) + +--- + +### License + +Licensed under the [MIT License](./LICENSE). diff --git a/clear-log-files b/clear-log-files new file mode 100755 index 0000000..07f7b84 --- /dev/null +++ b/clear-log-files @@ -0,0 +1,157 @@ +#!/usr/bin/env bash + +# Author : Allan Christensen +# First Created : 12-03-2001 (DD-MM-YYYY) +# Description : Clears rotated logfiles and reports large unrotated logs in /var/log +# License : MIT License + +# +# Are we root +# +if [[ $(id -u) -ne 0 ]]; then echo "" && echo "Must be root or use sudo" && echo "" ; exit ; fi + +# +# Safety controls +# + +# +# Dry run mode +# +# true = simulate deletions, nothing is removed +# false = real run (cron) +# +dryrun=true + +# +# Extended rotated log cleanup +# +# Controls deletion of non-logrotate files like: +# app.log.1234 +# installer-debug.log.9876 +# +# false = report only (safe default) +# true = delete during real runs (dryrun must also be false) +# +extended_cleanup=false + +# +# Define variables +# +logdir="/var/log" + +# +# Warning threshold for unrotated logs (megabytes) +# +warning=200 + +resultlog="/var/log/clear-log-files.log" + +# +# Initialize log file +# +: > "$resultlog" +chmod 644 "$resultlog" + +{ + echo "Clear logfiles run : $(date)" + echo "Log Directory : $logdir" + echo "Warning threshold : ${warning} MB" + echo "Dry run : $dryrun" + echo "Extended cleanup : $extended_cleanup" + echo "" +} >> "$resultlog" + +# +# Safety check +# +if [[ ! "$logdir" =~ ^/var/log(/|$) ]]; then + echo "ERROR: Refusing to operate outside /var/log: $logdir" >> "$resultlog" + exit 1 +fi + +# +# Pass 1 — classic rotated logs (logrotate style) +# +echo "Classic rotated log files:" >> "$resultlog" +found=false + +while IFS= read -r file; do + found=true + if [[ "$dryrun" == true ]]; then + echo " $file (dry-run)" >> "$resultlog" + else + echo " $file" >> "$resultlog" + rm -f "$file" + fi +done < <( + find "$logdir" -type f \ + \( \ + -name "*.log.[1-9]" -o -name "*.log.[1-9][0-9]" \ + -o -name "*.log.[1-9].gz" -o -name "*.log.[1-9][0-9].gz" \ + -o -name "*.log.[1-9].xz" -o -name "*.log.[1-9][0-9].xz" \ + -o -name "*.log.[1-9].bz2" -o -name "*.log.[1-9][0-9].bz2" \ + -o -name "*.log.[1-9].zst" -o -name "*.log.[1-9][0-9].zst" \ + \ + -o -name "syslog.[1-9]" -o -name "syslog.[1-9][0-9]" \ + -o -name "syslog.[1-9].gz" -o -name "syslog.[1-9][0-9].gz" \ + -o -name "syslog.[1-9].xz" -o -name "syslog.[1-9][0-9].xz" \ + -o -name "syslog.[1-9].bz2" -o -name "syslog.[1-9][0-9].bz2" \ + -o -name "syslog.[1-9].zst" -o -name "syslog.[1-9][0-9].zst" \ + \) \ + ! -name "clear-log-files.log*" \ + 2>/dev/null +) + +[[ "$found" == false ]] && echo " None" >> "$resultlog" +echo "" >> "$resultlog" + +# +# Pass 2 — extended rotated logs (non-standard) +# +echo "Extended rotated log files:" >> "$resultlog" +found=false + +while IFS= read -r file; do + found=true + if [[ "$dryrun" == true || "$extended_cleanup" == false ]]; then + echo " $file (reported only)" >> "$resultlog" + else + echo " $file" >> "$resultlog" + rm -f "$file" + fi +done < <( + find "$logdir" -type f \ + -name "*.log.*" \ + ! -name "*.log.[1-9]*" \ + ! -name "clear-log-files.log*" \ + 2>/dev/null +) + +[[ "$found" == false ]] && echo " None" >> "$resultlog" +echo "" >> "$resultlog" + +# +# Detect large unrotated logs +# +echo "Large unrotated log files detected:" >> "$resultlog" +found=false + +while IFS= read -r file; do + size_mb=$(( $(stat -c %s "$file") / 1024 / 1024 )) + if (( size_mb >= warning )); then + echo " WARNING: $file (${size_mb} MB)" >> "$resultlog" + found=true + fi +done < <( + find "$logdir" -type f \ + -name "*.log" \ + ! -name "clear-log-files.log" \ + 2>/dev/null +) + +[[ "$found" == false ]] && echo " None" >> "$resultlog" +echo "" >> "$resultlog" + +# +# End of script +# diff --git a/last-tested b/last-tested new file mode 100644 index 0000000..46c28b6 --- /dev/null +++ b/last-tested @@ -0,0 +1,4 @@ +------------------------------------ +Last tested: 28-01-2026 (DD-MM-YYYY) +Environment: Ubuntu Server 24.04 LTS +------------------------------------