gistfile1.txt
· 9.3 KiB · Text
Brut
#!/usr/bin/env bash
FW_EVENTS_LOG="$(ctx::fw_events_log)"
WG_EVENTS_LOG="$(ctx::events_log)"
function cmd::logs::on_load() {
flag::register --name
flag::register --type
flag::register --since
flag::register --limit
flag::register --fw
flag::register --wg
flag::register --follow
flag::register --all
flag::register --before
flag::register --force
flag::register --days
}
function cmd::logs::help() {
cat <<EOF
Usage: wgctl logs [subcommand] [options]
Show or manage WireGuard and firewall activity logs.
Subcommands:
show (default) Show activity logs
remove, rm Remove log entries
rotate Remove entries older than N days
Options for show:
--name <name> Filter by client name
--type <type> Filter by device type
--limit <n> Max results per source (default: 50)
--fw Show only firewall drops
--wg Show only WireGuard events
--follow, -f Follow logs in real time
Options for remove:
--name <name> Remove entries for specific peer
--all Remove all log entries
--fw Remove only firewall events
--wg Remove only WireGuard events
--before <days> Remove entries older than N days
--force Skip confirmation
Options for rotate:
--days <n> Days to keep (default: 7)
--force Skip confirmation
Examples:
wgctl logs
wgctl logs --name phone-nuno
wgctl logs --fw --limit 100
wgctl logs --follow
wgctl logs remove --name phone-nuno
wgctl logs remove --all --force
wgctl logs remove --fw --before 1
wgctl logs rotate
wgctl logs rotate --days 30 --force
EOF
}
function cmd::logs::run() {
local subcmd="${1:-show}"
if [[ "$subcmd" == --* ]]; then
subcmd="show"
else
shift || true
fi
case "$subcmd" in
show) cmd::logs::show "$@" ;;
remove|rm|del) cmd::logs::remove "$@" ;;
rotate) cmd::logs::rotate "$@" ;;
help) cmd::logs::help ;;
*)
log::error "Unknown subcommand: '${subcmd}'"
cmd::logs::help
return 1
;;
esac
}
function cmd::logs::show() {
local name="" type="" limit=50
local fw_only=false wg_only=false follow=false
while [[ $# -gt 0 ]]; do
case "$1" in
--name) name="$2"; shift 2 ;;
--type) type="$2"; shift 2 ;;
--limit) limit="$2"; shift 2 ;;
--fw) fw_only=true; shift ;;
--wg) wg_only=true; shift ;;
--follow|-f) follow=true; shift ;;
--help) cmd::logs::help; return ;;
*)
log::error "Unknown flag: $1"
return 1
;;
esac
done
if [[ -n "$name" && -n "$type" ]]; then
name=$(peers::resolve_and_require "$name" "$type") || return 1
fi
local filter_ip=""
if [[ -n "$name" ]]; then
filter_ip=$(peers::get_ip "$name")
[[ -z "$filter_ip" ]] && log::error "Could not find IP for: $name" && return 1
fi
if $follow; then
cmd::logs::follow "$filter_ip" "$name" "$type" "$fw_only" "$wg_only"
return
fi
log::section "WireGuard Activity Log"
printf "\n"
$wg_only || cmd::logs::show_fw_events "$filter_ip" "$name" "$type" "$limit"
$fw_only || cmd::logs::show_wg_events "$filter_ip" "$name" "$type" "$limit"
}
function cmd::logs::follow() {
local filter_ip="${1:-}" filter_name="${2:-}" filter_type="${3:-}"
local fw_only="${4:-false}" wg_only="${5:-false}"
local filter_peers="${6:-}"
local clients_dir
clients_dir="$(ctx::clients)"
local wg_log="$WG_EVENTS_LOG"
local fw_log="$FW_EVENTS_LOG"
$fw_only && wg_log=""
$wg_only && fw_log=""
log::section "WireGuard Live Log (Ctrl+C to stop)"
printf "\n %-20s %-8s %-20s %-25s %s\n" \
"TIME" "SOURCE" "CLIENT" "DESTINATION/ENDPOINT" "EVENT"
printf " %s\n" "$(printf '─%.0s' {1..90})"
while IFS="|" read -r source ts client dst_or_endpoint event; do
if [[ "$source" == "fw" ]]; then
local colored_event
case "$event" in
tcp) colored_event="\033[1;33mtcp\033[0m" ;;
udp) colored_event="\033[0;36mudp\033[0m" ;;
icmp) colored_event="\033[0;37micmp\033[0m" ;;
*) colored_event="$event" ;;
esac
printf " %-20s %-8s %-20s %-25s %b\n" \
"$ts" "firewall" "$client" "$dst_or_endpoint" "$colored_event"
else
local colored_event
case "$event" in
attempt) colored_event="\033[1;31mattempt\033[0m" ;;
handshake) colored_event="\033[1;32mhandshake\033[0m" ;;
*) colored_event="$event" ;;
esac
printf " %-20s %-8s %-20s %-25s %b\n" \
"$ts" "wireguard" "$client" "$dst_or_endpoint" "$colored_event"
fi
done < <(json::follow_logs "$fw_log" "$wg_log" "$filter_ip" "$filter_type" \
"$clients_dir" "$filter_peers")
}
function cmd::logs::remove() {
local name="" type="" before="" force=false
local fw_only=false wg_only=false all=false
while [[ $# -gt 0 ]]; do
case "$1" in
--name) name="$2"; shift 2 ;;
--type) type="$2"; shift 2 ;;
--before) before="$2"; shift 2 ;;
--fw) fw_only=true; shift ;;
--wg) wg_only=true; shift ;;
--all) all=true; shift ;;
--force) force=true; shift ;;
--help) cmd::logs::help; return ;;
*)
log::error "Unknown flag: $1"
return 1
;;
esac
done
# Validate — need at least one filter
if ! $all && [[ -z "$name" && -z "$before" ]]; then
log::error "Specify --name, --before, or --all"
cmd::logs::help
return 1
fi
local filter_ip=""
if [[ -n "$name" ]]; then
name=$(peers::resolve_and_require "$name" "$type") || return 1
filter_ip=$(peers::get_ip "$name")
fi
# Build description for confirmation
local desc=""
$all && desc="all entries"
[[ -n "$name" ]] && desc="entries for '${name}'"
[[ -n "$before" ]] && desc="${desc:+$desc, }entries older than ${before} days"
$fw_only && desc="${desc} (fw only)"
$wg_only && desc="${desc} (wg only)"
if ! $force; then
read -r -p "Remove ${desc}? [y/N] " confirm
case "$confirm" in
[yY][eE][sS]|[yY]) ;;
*) log::info "Aborted"; return 0 ;;
esac
fi
local result
result=$(json::remove_events_filtered \
"$WG_EVENTS_LOG" "$FW_EVENTS_LOG" \
"${name:-}" "${filter_ip:-}" \
"$fw_only" "$wg_only" \
"${before:-}")
local removed_wg removed_fw
IFS="|" read -r removed_wg removed_fw <<< "$result"
local total=$(( removed_wg + removed_fw ))
if [[ "$total" -eq 0 ]]; then
log::wg_warning "No log entries found matching the criteria"
return 0
fi
log::wg_success "Removed ${total} log entries (wg: ${removed_wg}, fw: ${removed_fw})"
}
function cmd::logs::show_wg_events() {
local filter_ip="${1:-}" filter_name="${2:-}" filter_type="${3:-}" limit="${4:-50}"
[[ ! -f "$WG_EVENTS_LOG" ]] && return 0
printf " WireGuard Events:\n"
printf " %-20s %-20s %-18s %s\n" "TIME" "CLIENT" "ENDPOINT" "EVENT"
printf " %s\n" "$(printf '─%.0s' {1..75})"
local found=false
while IFS="|" read -r ts client endpoint event; do
[[ -z "$ts" ]] && continue
local colored_event
case "$event" in
attempt*) colored_event="\033[1;31m${event}\033[0m" ;;
handshake*) colored_event="\033[1;32m${event}\033[0m" ;;
*) colored_event="$event" ;;
esac
printf " %-20s %-20s %-18s %b\n" "$ts" "$client" "$endpoint" "$colored_event"
found=true
done < <(json::wg_events "$WG_EVENTS_LOG" "$filter_name" "$filter_type" "$limit")
$found || printf " —\n"
printf "\n"
}
function cmd::logs::show_fw_events() {
local filter_ip="${1:-}" filter_name="${2:-}" filter_type="${3:-}" limit="${4:-50}"
[[ ! -f "$FW_EVENTS_LOG" ]] && return 0
printf " Firewall Drops:\n"
printf " %-20s %-18s %-25s %s\n" "TIME" "CLIENT" "DESTINATION" "PROTOCOL"
printf " %s\n" "$(printf '─%.0s' {1..75})"
local found=false
while IFS="|" read -r ts client dst proto; do
[[ -z "$ts" ]] && continue
local colored_proto
case "$proto" in
tcp*) colored_proto="\033[1;33m${proto}\033[0m" ;;
udp*) colored_proto="\033[1;36m${proto}\033[0m" ;;
icmp*) colored_proto="\033[0;37m${proto}\033[0m" ;;
*) colored_proto="$proto" ;;
esac
printf " %-20s %-18s %-25s %b\n" "$ts" "$client" "$dst" "$colored_proto"
found=true
done < <(json::fw_events "$FW_EVENTS_LOG" "$filter_ip" "$filter_type" \
"$(ctx::clients)" "$limit")
$found || printf " —\n"
printf "\n"
}
function cmd::logs::rotate() {
local days=7 force=false
while [[ $# -gt 0 ]]; do
case "$1" in
--days) days="$2"; shift 2 ;;
--force) force=true; shift ;;
--help) cmd::logs::help; return ;;
*) log::error "Unknown flag: $1"; return 1 ;;
esac
done
$force || {
read -r -p "Remove log entries older than ${days} days? [y/N] " confirm
case "$confirm" in
[yY]*) ;;
*) log::info "Aborted"; return 0 ;;
esac
}
local result
result=$(json::remove_events_filtered \
"$WG_EVENTS_LOG" "$FW_EVENTS_LOG" \
"" "" "false" "false" "$days")
local removed_wg removed_fw
IFS="|" read -r removed_wg removed_fw <<< "$result"
local total=$(( removed_wg + removed_fw ))
if [[ "$total" -eq 0 ]]; then
log::wg_warning "No log entries older than ${days} days"
return 0
fi
log::wg_success "Rotated ${total} entries older than ${days} days (wg: ${removed_wg}, fw: ${removed_fw})"
}
| 1 | #!/usr/bin/env bash |
| 2 | |
| 3 | FW_EVENTS_LOG="$(ctx::fw_events_log)" |
| 4 | WG_EVENTS_LOG="$(ctx::events_log)" |
| 5 | |
| 6 | function cmd::logs::on_load() { |
| 7 | flag::register --name |
| 8 | flag::register --type |
| 9 | flag::register --since |
| 10 | flag::register --limit |
| 11 | flag::register --fw |
| 12 | flag::register --wg |
| 13 | flag::register --follow |
| 14 | flag::register --all |
| 15 | flag::register --before |
| 16 | flag::register --force |
| 17 | flag::register --days |
| 18 | } |
| 19 | |
| 20 | function cmd::logs::help() { |
| 21 | cat <<EOF |
| 22 | Usage: wgctl logs [subcommand] [options] |
| 23 | |
| 24 | Show or manage WireGuard and firewall activity logs. |
| 25 | |
| 26 | Subcommands: |
| 27 | show (default) Show activity logs |
| 28 | remove, rm Remove log entries |
| 29 | rotate Remove entries older than N days |
| 30 | |
| 31 | Options for show: |
| 32 | --name <name> Filter by client name |
| 33 | --type <type> Filter by device type |
| 34 | --limit <n> Max results per source (default: 50) |
| 35 | --fw Show only firewall drops |
| 36 | --wg Show only WireGuard events |
| 37 | --follow, -f Follow logs in real time |
| 38 | |
| 39 | Options for remove: |
| 40 | --name <name> Remove entries for specific peer |
| 41 | --all Remove all log entries |
| 42 | --fw Remove only firewall events |
| 43 | --wg Remove only WireGuard events |
| 44 | --before <days> Remove entries older than N days |
| 45 | --force Skip confirmation |
| 46 | |
| 47 | Options for rotate: |
| 48 | --days <n> Days to keep (default: 7) |
| 49 | --force Skip confirmation |
| 50 | |
| 51 | Examples: |
| 52 | wgctl logs |
| 53 | wgctl logs --name phone-nuno |
| 54 | wgctl logs --fw --limit 100 |
| 55 | wgctl logs --follow |
| 56 | wgctl logs remove --name phone-nuno |
| 57 | wgctl logs remove --all --force |
| 58 | wgctl logs remove --fw --before 1 |
| 59 | wgctl logs rotate |
| 60 | wgctl logs rotate --days 30 --force |
| 61 | EOF |
| 62 | } |
| 63 | |
| 64 | function cmd::logs::run() { |
| 65 | local subcmd="${1:-show}" |
| 66 | if [[ "$subcmd" == --* ]]; then |
| 67 | subcmd="show" |
| 68 | else |
| 69 | shift || true |
| 70 | fi |
| 71 | |
| 72 | case "$subcmd" in |
| 73 | show) cmd::logs::show "$@" ;; |
| 74 | remove|rm|del) cmd::logs::remove "$@" ;; |
| 75 | rotate) cmd::logs::rotate "$@" ;; |
| 76 | help) cmd::logs::help ;; |
| 77 | *) |
| 78 | log::error "Unknown subcommand: '${subcmd}'" |
| 79 | cmd::logs::help |
| 80 | return 1 |
| 81 | ;; |
| 82 | esac |
| 83 | } |
| 84 | |
| 85 | function cmd::logs::show() { |
| 86 | local name="" type="" limit=50 |
| 87 | local fw_only=false wg_only=false follow=false |
| 88 | |
| 89 | while [[ $# -gt 0 ]]; do |
| 90 | case "$1" in |
| 91 | --name) name="$2"; shift 2 ;; |
| 92 | --type) type="$2"; shift 2 ;; |
| 93 | --limit) limit="$2"; shift 2 ;; |
| 94 | --fw) fw_only=true; shift ;; |
| 95 | --wg) wg_only=true; shift ;; |
| 96 | --follow|-f) follow=true; shift ;; |
| 97 | --help) cmd::logs::help; return ;; |
| 98 | *) |
| 99 | log::error "Unknown flag: $1" |
| 100 | return 1 |
| 101 | ;; |
| 102 | esac |
| 103 | done |
| 104 | |
| 105 | if [[ -n "$name" && -n "$type" ]]; then |
| 106 | name=$(peers::resolve_and_require "$name" "$type") || return 1 |
| 107 | fi |
| 108 | |
| 109 | local filter_ip="" |
| 110 | if [[ -n "$name" ]]; then |
| 111 | filter_ip=$(peers::get_ip "$name") |
| 112 | [[ -z "$filter_ip" ]] && log::error "Could not find IP for: $name" && return 1 |
| 113 | fi |
| 114 | |
| 115 | if $follow; then |
| 116 | cmd::logs::follow "$filter_ip" "$name" "$type" "$fw_only" "$wg_only" |
| 117 | return |
| 118 | fi |
| 119 | |
| 120 | log::section "WireGuard Activity Log" |
| 121 | printf "\n" |
| 122 | $wg_only || cmd::logs::show_fw_events "$filter_ip" "$name" "$type" "$limit" |
| 123 | $fw_only || cmd::logs::show_wg_events "$filter_ip" "$name" "$type" "$limit" |
| 124 | } |
| 125 | |
| 126 | function cmd::logs::follow() { |
| 127 | local filter_ip="${1:-}" filter_name="${2:-}" filter_type="${3:-}" |
| 128 | local fw_only="${4:-false}" wg_only="${5:-false}" |
| 129 | local filter_peers="${6:-}" |
| 130 | local clients_dir |
| 131 | clients_dir="$(ctx::clients)" |
| 132 | local wg_log="$WG_EVENTS_LOG" |
| 133 | local fw_log="$FW_EVENTS_LOG" |
| 134 | $fw_only && wg_log="" |
| 135 | $wg_only && fw_log="" |
| 136 | |
| 137 | log::section "WireGuard Live Log (Ctrl+C to stop)" |
| 138 | printf "\n %-20s %-8s %-20s %-25s %s\n" \ |
| 139 | "TIME" "SOURCE" "CLIENT" "DESTINATION/ENDPOINT" "EVENT" |
| 140 | printf " %s\n" "$(printf '─%.0s' {1..90})" |
| 141 | |
| 142 | while IFS="|" read -r source ts client dst_or_endpoint event; do |
| 143 | if [[ "$source" == "fw" ]]; then |
| 144 | local colored_event |
| 145 | case "$event" in |
| 146 | tcp) colored_event="\033[1;33mtcp\033[0m" ;; |
| 147 | udp) colored_event="\033[0;36mudp\033[0m" ;; |
| 148 | icmp) colored_event="\033[0;37micmp\033[0m" ;; |
| 149 | *) colored_event="$event" ;; |
| 150 | esac |
| 151 | printf " %-20s %-8s %-20s %-25s %b\n" \ |
| 152 | "$ts" "firewall" "$client" "$dst_or_endpoint" "$colored_event" |
| 153 | else |
| 154 | local colored_event |
| 155 | case "$event" in |
| 156 | attempt) colored_event="\033[1;31mattempt\033[0m" ;; |
| 157 | handshake) colored_event="\033[1;32mhandshake\033[0m" ;; |
| 158 | *) colored_event="$event" ;; |
| 159 | esac |
| 160 | printf " %-20s %-8s %-20s %-25s %b\n" \ |
| 161 | "$ts" "wireguard" "$client" "$dst_or_endpoint" "$colored_event" |
| 162 | fi |
| 163 | done < <(json::follow_logs "$fw_log" "$wg_log" "$filter_ip" "$filter_type" \ |
| 164 | "$clients_dir" "$filter_peers") |
| 165 | } |
| 166 | |
| 167 | function cmd::logs::remove() { |
| 168 | local name="" type="" before="" force=false |
| 169 | local fw_only=false wg_only=false all=false |
| 170 | |
| 171 | while [[ $# -gt 0 ]]; do |
| 172 | case "$1" in |
| 173 | --name) name="$2"; shift 2 ;; |
| 174 | --type) type="$2"; shift 2 ;; |
| 175 | --before) before="$2"; shift 2 ;; |
| 176 | --fw) fw_only=true; shift ;; |
| 177 | --wg) wg_only=true; shift ;; |
| 178 | --all) all=true; shift ;; |
| 179 | --force) force=true; shift ;; |
| 180 | --help) cmd::logs::help; return ;; |
| 181 | *) |
| 182 | log::error "Unknown flag: $1" |
| 183 | return 1 |
| 184 | ;; |
| 185 | esac |
| 186 | done |
| 187 | |
| 188 | # Validate — need at least one filter |
| 189 | if ! $all && [[ -z "$name" && -z "$before" ]]; then |
| 190 | log::error "Specify --name, --before, or --all" |
| 191 | cmd::logs::help |
| 192 | return 1 |
| 193 | fi |
| 194 | |
| 195 | local filter_ip="" |
| 196 | if [[ -n "$name" ]]; then |
| 197 | name=$(peers::resolve_and_require "$name" "$type") || return 1 |
| 198 | filter_ip=$(peers::get_ip "$name") |
| 199 | fi |
| 200 | |
| 201 | # Build description for confirmation |
| 202 | local desc="" |
| 203 | $all && desc="all entries" |
| 204 | [[ -n "$name" ]] && desc="entries for '${name}'" |
| 205 | [[ -n "$before" ]] && desc="${desc:+$desc, }entries older than ${before} days" |
| 206 | $fw_only && desc="${desc} (fw only)" |
| 207 | $wg_only && desc="${desc} (wg only)" |
| 208 | |
| 209 | if ! $force; then |
| 210 | read -r -p "Remove ${desc}? [y/N] " confirm |
| 211 | case "$confirm" in |
| 212 | [yY][eE][sS]|[yY]) ;; |
| 213 | *) log::info "Aborted"; return 0 ;; |
| 214 | esac |
| 215 | fi |
| 216 | |
| 217 | local result |
| 218 | result=$(json::remove_events_filtered \ |
| 219 | "$WG_EVENTS_LOG" "$FW_EVENTS_LOG" \ |
| 220 | "${name:-}" "${filter_ip:-}" \ |
| 221 | "$fw_only" "$wg_only" \ |
| 222 | "${before:-}") |
| 223 | |
| 224 | local removed_wg removed_fw |
| 225 | IFS="|" read -r removed_wg removed_fw <<< "$result" |
| 226 | local total=$(( removed_wg + removed_fw )) |
| 227 | |
| 228 | if [[ "$total" -eq 0 ]]; then |
| 229 | log::wg_warning "No log entries found matching the criteria" |
| 230 | return 0 |
| 231 | fi |
| 232 | |
| 233 | log::wg_success "Removed ${total} log entries (wg: ${removed_wg}, fw: ${removed_fw})" |
| 234 | } |
| 235 | |
| 236 | function cmd::logs::show_wg_events() { |
| 237 | local filter_ip="${1:-}" filter_name="${2:-}" filter_type="${3:-}" limit="${4:-50}" |
| 238 | |
| 239 | [[ ! -f "$WG_EVENTS_LOG" ]] && return 0 |
| 240 | |
| 241 | printf " WireGuard Events:\n" |
| 242 | printf " %-20s %-20s %-18s %s\n" "TIME" "CLIENT" "ENDPOINT" "EVENT" |
| 243 | printf " %s\n" "$(printf '─%.0s' {1..75})" |
| 244 | |
| 245 | local found=false |
| 246 | while IFS="|" read -r ts client endpoint event; do |
| 247 | [[ -z "$ts" ]] && continue |
| 248 | local colored_event |
| 249 | case "$event" in |
| 250 | attempt*) colored_event="\033[1;31m${event}\033[0m" ;; |
| 251 | handshake*) colored_event="\033[1;32m${event}\033[0m" ;; |
| 252 | *) colored_event="$event" ;; |
| 253 | esac |
| 254 | printf " %-20s %-20s %-18s %b\n" "$ts" "$client" "$endpoint" "$colored_event" |
| 255 | found=true |
| 256 | done < <(json::wg_events "$WG_EVENTS_LOG" "$filter_name" "$filter_type" "$limit") |
| 257 | |
| 258 | $found || printf " —\n" |
| 259 | printf "\n" |
| 260 | } |
| 261 | |
| 262 | function cmd::logs::show_fw_events() { |
| 263 | local filter_ip="${1:-}" filter_name="${2:-}" filter_type="${3:-}" limit="${4:-50}" |
| 264 | |
| 265 | [[ ! -f "$FW_EVENTS_LOG" ]] && return 0 |
| 266 | |
| 267 | printf " Firewall Drops:\n" |
| 268 | printf " %-20s %-18s %-25s %s\n" "TIME" "CLIENT" "DESTINATION" "PROTOCOL" |
| 269 | printf " %s\n" "$(printf '─%.0s' {1..75})" |
| 270 | |
| 271 | local found=false |
| 272 | while IFS="|" read -r ts client dst proto; do |
| 273 | [[ -z "$ts" ]] && continue |
| 274 | local colored_proto |
| 275 | case "$proto" in |
| 276 | tcp*) colored_proto="\033[1;33m${proto}\033[0m" ;; |
| 277 | udp*) colored_proto="\033[1;36m${proto}\033[0m" ;; |
| 278 | icmp*) colored_proto="\033[0;37m${proto}\033[0m" ;; |
| 279 | *) colored_proto="$proto" ;; |
| 280 | esac |
| 281 | printf " %-20s %-18s %-25s %b\n" "$ts" "$client" "$dst" "$colored_proto" |
| 282 | found=true |
| 283 | done < <(json::fw_events "$FW_EVENTS_LOG" "$filter_ip" "$filter_type" \ |
| 284 | "$(ctx::clients)" "$limit") |
| 285 | |
| 286 | $found || printf " —\n" |
| 287 | printf "\n" |
| 288 | } |
| 289 | |
| 290 | |
| 291 | |
| 292 | function cmd::logs::rotate() { |
| 293 | local days=7 force=false |
| 294 | |
| 295 | while [[ $# -gt 0 ]]; do |
| 296 | case "$1" in |
| 297 | --days) days="$2"; shift 2 ;; |
| 298 | --force) force=true; shift ;; |
| 299 | --help) cmd::logs::help; return ;; |
| 300 | *) log::error "Unknown flag: $1"; return 1 ;; |
| 301 | esac |
| 302 | done |
| 303 | |
| 304 | $force || { |
| 305 | read -r -p "Remove log entries older than ${days} days? [y/N] " confirm |
| 306 | case "$confirm" in |
| 307 | [yY]*) ;; |
| 308 | *) log::info "Aborted"; return 0 ;; |
| 309 | esac |
| 310 | } |
| 311 | |
| 312 | local result |
| 313 | result=$(json::remove_events_filtered \ |
| 314 | "$WG_EVENTS_LOG" "$FW_EVENTS_LOG" \ |
| 315 | "" "" "false" "false" "$days") |
| 316 | |
| 317 | local removed_wg removed_fw |
| 318 | IFS="|" read -r removed_wg removed_fw <<< "$result" |
| 319 | local total=$(( removed_wg + removed_fw )) |
| 320 | |
| 321 | if [[ "$total" -eq 0 ]]; then |
| 322 | log::wg_warning "No log entries older than ${days} days" |
| 323 | return 0 |
| 324 | fi |
| 325 | |
| 326 | log::wg_success "Rotated ${total} entries older than ${days} days (wg: ${removed_wg}, fw: ${removed_fw})" |
| 327 | } |