#!/usr/bin/env bash # events.sh - Filesystem-first event system for homelab EVENTS_BASE_DIR="${RUNTIME_PATH:-/opt/homelab}/events" # Emit a normalized JSON event # Usage: emit_event emit_event() { local type=$1 local severity=$2 local source=$3 local service=$4 local correlation_id=$5 local payload=${6:-"{}"} local node=$(hostname) local timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ") local date_dir=$(date +"%Y-%m-%d") local event_dir="${EVENTS_BASE_DIR}/${date_dir}/${node}" mkdir -p "$event_dir" # Generate a unique filename for the event to ensure append-only/no-overwrite local event_id=$(cat /proc/sys/kernel/random/uuid 2>/dev/null || date +%s%N) local event_file="${event_dir}/${timestamp}_${type}_${event_id}.json" # Construct JSON cat < "$event_file" { "timestamp": "$timestamp", "node": "$node", "type": "$type", "severity": "$severity", "source": "$source", "service": "$service", "correlation_id": "$correlation_id", "payload": $payload } EOF # Also log to standard logging if available if command -v log >/dev/null 2>&1; then log "EVENT" "[$type] service=$service severity=$severity cid=$correlation_id" fi } # Query recent events (last N events or by date) # Usage: list_events [date] [node] list_events() { local target_date=${1:-$(date +"%Y-%m-%d")} local target_node=$2 local search_path="${EVENTS_BASE_DIR}/${target_date}" if [[ -n "$target_node" ]]; then search_path="${search_path}/${target_node}" fi if [[ -d "$search_path" ]]; then find "$search_path" -name "*.json" | sort fi } # Simple filter helper # Usage: filter_events filter_events() { local field=$1 local value=$2 local files=$3 for f in $files; do if grep -q "\"$field\": \"$value\"" "$f"; then echo "$f" fi done } # export -f emit_event # export -f list_events # export -f filter_events