- Split monolithic exitrace.sh into focused lib/ modules - date_utils.sh: Date validation and generation functions - mx_lookup.sh: MX record lookup functionality - log_analyzer.awk: Core log analysis logic extracted from main script - Maintains full backward compatibility with existing interface - Improves maintainability, testability, and code organization 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
118 lines
3.4 KiB
Bash
118 lines
3.4 KiB
Bash
#!/usr/bin/env bash
|
|
# date_utils.sh - Date utility functions for exitrace
|
|
# Maintainer: ljp
|
|
|
|
# Constants
|
|
readonly DATE_FMT="%Y-%m-%d"
|
|
readonly MAX_DAYS_LIMIT=400
|
|
|
|
# Validation functions
|
|
validate_positive_integer() {
|
|
local value="$1"
|
|
local param="$2"
|
|
if [[ -z "$value" ]]; then
|
|
echo "Fehler: Parameter $param benötigt einen Wert" >&2
|
|
exit 1
|
|
fi
|
|
if ! [[ "$value" =~ ^[0-9]+$ ]]; then
|
|
echo "Fehler: $param muss eine positive Zahl sein (gegeben: '$value')" >&2
|
|
exit 1
|
|
fi
|
|
if [[ "$value" -eq 0 ]]; then
|
|
echo "Fehler: $param muss größer als 0 sein" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
validate_date() {
|
|
local date_val="$1"
|
|
local param="$2"
|
|
if [[ -z "$date_val" ]]; then
|
|
echo "Fehler: Parameter $param benötigt einen Wert" >&2
|
|
exit 1
|
|
fi
|
|
if ! date -d "$date_val" >/dev/null 2>&1; then
|
|
echo "Fehler: Ungültiges Datumsformat für $param: '$date_val'" >&2
|
|
echo "Erwartetes Format: YYYY-MM-DD" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
validate_date_range() {
|
|
local range="$1"
|
|
if [[ -z "$range" ]]; then
|
|
echo "Fehler: --range benötigt einen Wert" >&2
|
|
exit 1
|
|
fi
|
|
if [[ "$range" != *".."* ]]; then
|
|
echo "Fehler: Ungültiges Range-Format: '$range'" >&2
|
|
echo "Erwartetes Format: YYYY-MM-DD..YYYY-MM-DD" >&2
|
|
exit 1
|
|
fi
|
|
local start_date="${range%%..*}"
|
|
local end_date="${range##*..}"
|
|
validate_date "$start_date" "--range Startdatum"
|
|
validate_date "$end_date" "--range Enddatum"
|
|
}
|
|
|
|
# Date generation functions
|
|
gen_dates_hours_back() {
|
|
local hrs="$1" start_ts end_ts cur next_ts
|
|
end_ts="$(date +%s)" || { echo "Fehler: Kann aktuellen Timestamp nicht ermitteln" >&2; exit 1; }
|
|
start_ts="$(date -d "-${hrs} hours" +%s)" || { echo "Fehler: Kann Start-Timestamp nicht berechnen" >&2; exit 1; }
|
|
cur="$(date -d "@$start_ts" +${DATE_FMT})" || { echo "Fehler: Kann Startdatum nicht formatieren" >&2; exit 1; }
|
|
|
|
local iterations=0
|
|
while :; do
|
|
echo "$cur"
|
|
next_ts="$(date -d "$cur +1 day" +%s 2>/dev/null)" || { echo "Fehler: Datumsberechnung fehlgeschlagen für $cur" >&2; exit 1; }
|
|
[[ "$next_ts" -le "$end_ts" ]] || break
|
|
cur="$(date -d "$cur +1 day" +${DATE_FMT} 2>/dev/null)" || { echo "Fehler: Datum-Inkrement fehlgeschlagen für $cur" >&2; exit 1; }
|
|
|
|
# Sicherheit gegen Endlosschleifen
|
|
((iterations++))
|
|
if [[ $iterations -gt $MAX_DAYS_LIMIT ]]; then
|
|
echo "Fehler: Zu viele Tage im Zeitfenster (>$MAX_DAYS_LIMIT Tage)" >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
}
|
|
|
|
gen_dates_days_back() {
|
|
local days="$1" i
|
|
for ((i=0;i<=days;i++)); do
|
|
date -d "-$i day" +${DATE_FMT} || { echo "Fehler: Kann Datum für -$i day nicht berechnen" >&2; exit 1; }
|
|
done
|
|
}
|
|
|
|
gen_dates_range() {
|
|
local a="${1%%..*}" b="${1##*..}" cur="$a"
|
|
local iterations=0
|
|
|
|
while :; do
|
|
echo "$cur"
|
|
[[ "$cur" == "$b" ]] && break
|
|
cur="$(date -d "$cur +1 day" +${DATE_FMT} 2>/dev/null)" || { echo "Fehler: Datum-Inkrement fehlgeschlagen für $cur" >&2; exit 1; }
|
|
|
|
# Sicherheit gegen Endlosschleifen
|
|
((iterations++))
|
|
if [[ $iterations -gt $MAX_DAYS_LIMIT ]]; then
|
|
echo "Fehler: Zu großer Datumsbereich (>$MAX_DAYS_LIMIT Tage)" >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
}
|
|
|
|
files_for_date() {
|
|
local d="$1" y="${d:0:4}" m="${d:5:2}"
|
|
local logroot="${LOGROOT:-/var/log/easyname}"
|
|
local p="${logroot}/${y}/${m}/${d}.log"
|
|
if [[ -f "$p" ]]; then
|
|
printf "%s\n" "$p"
|
|
fi
|
|
if [[ -f "${p}.gz" ]]; then
|
|
printf "%s\n" "${p}.gz"
|
|
fi
|
|
}
|
|
|
|
# Built with the help of Claude Code |