Files
log_analysis/scripts/scan-anomalies.sh
rpert e96a8b03fc Initial cross-server log inventory + anomaly scan
- 10 hosts (mo1, ams, ams2, ro1, ca1, ca2, ca3, fr1, sony, termux)
- discover-logs.sh: portable inventory (Linux/FreeBSD/Termux)
- scan-anomalies.sh: ERROR/WARN/CRITICAL counts + journalctl + kubectl
- run-all.sh: parallel SSH fan-out
- build-summary.py: aggregates into reports/SUMMARY.md
- 5 HIGH-severity findings identified on ro1 (apache scanner traffic, mount_monitor warnings)
2026-04-10 21:49:17 +00:00

73 lines
2.6 KiB
Bash
Executable File

#!/bin/sh
# scan-anomalies.sh — inspect recent log files for error/warning/critical patterns.
# Output is human-readable; one block per file with issues.
set -u
HOST=$(hostname 2>/dev/null || uname -n)
echo "=== Anomaly scan: $HOST ($(date -u +%FT%TZ)) ==="
echo
# 1. systemd journal (Linux only) — last 24h, error priority and above.
if command -v journalctl >/dev/null 2>&1; then
echo "--- journalctl -p err --since '24 hours ago' ---"
journalctl -p err --since '24 hours ago' --no-pager 2>/dev/null | tail -100
echo
fi
# 2. kubectl events (mo1 only).
if command -v kubectl >/dev/null 2>&1; then
echo "--- kubectl get events --all-namespaces (warnings) ---"
kubectl get events --all-namespaces --field-selector type!=Normal 2>/dev/null | tail -50
echo
fi
# 3. Recent (mtime < 7d) log files: count error tokens.
PATTERN='ERROR|FATAL|CRITICAL|FAIL(ED|URE)?|panic|segfault|OOM|Out of memory|denied'
WPAT='WARN(ING)?'
scan_file() {
f="$1"
case "$f" in
*.gz) cmd="zcat -- \"$f\"" ;;
*.xz) cmd="xzcat -- \"$f\"" ;;
*.zst) cmd="zstdcat -- \"$f\"" ;;
*.zip) return ;;
*) cmd="cat -- \"$f\"" ;;
esac
errs=$(eval "$cmd" 2>/dev/null | grep -c -E "$PATTERN")
warns=$(eval "$cmd" 2>/dev/null | grep -c -E "$WPAT")
if [ "${errs:-0}" -gt 0 ] || [ "${warns:-0}" -gt 50 ]; then
sz=$(stat -c '%s' "$f" 2>/dev/null || stat -f '%z' "$f" 2>/dev/null)
printf '%s\terrors=%s\twarns=%s\tsize=%s\n' "$f" "$errs" "$warns" "$sz"
# Show up to 5 sample error lines.
eval "$cmd" 2>/dev/null | grep -E "$PATTERN" | head -5 | sed 's/^/ > /'
fi
}
echo "--- recent log files (mtime < 7d) ---"
# Use locate when possible; otherwise restrict to /var/log walk.
{
if command -v plocate >/dev/null 2>&1; then plocate /var/log 2>/dev/null
elif command -v locate >/dev/null 2>&1; then locate /var/log 2>/dev/null
fi
[ -d /var/log ] && du -a /var/log 2>/dev/null | awk '{ $1=""; sub(/^ /,""); print }'
} | sort -u | while IFS= read -r f; do
[ -f "$f" ] || continue
case "$f" in *.log|*.log.*|*/messages|*/syslog|*/auth*|*/kern*|*/daemon*) ;; *) continue ;; esac
# mtime within 7 days
if [ "$(find "$f" -prune -mtime -7 2>/dev/null)" = "$f" ]; then
scan_file "$f"
fi
done
# 4. Disk usage of /var/log overall.
echo
echo "--- /var/log disk usage ---"
du -sh /var/log 2>/dev/null
du -sh /var/log/* 2>/dev/null | sort -h | tail -15
# 5. Largest log files
echo
echo "--- top 15 largest files under /var/log ---"
du -ab /var/log 2>/dev/null | sort -nr | head -15 | awk '{ printf "%10d %s\n", $1, $2 }'