feat(ingestion): implement log monitoring script with webhook integration
- Add logwhisperer.sh script for tailing and monitoring system logs - Implement pattern matching for critical errors (FATAL, ERROR, OOM, segfault) - Add JSON payload generation with severity levels - Implement rate limiting and offset tracking per log source - Add install.sh with interactive configuration and systemd support - Create comprehensive test suite with pytest - Add technical specification documentation - Update CHANGELOG.md following Common Changelog standard All 12 tests passing. Follows Metodo Sacchi (Safety first, little often, double check).
This commit is contained in:
333
scripts/install.sh
Executable file
333
scripts/install.sh
Executable file
@@ -0,0 +1,333 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# LogWhisperer Agent - Script di Installazione
|
||||
# Installa lo script di monitoraggio log e configura l'ambiente
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
INSTALL_DIR="/usr/local/bin"
|
||||
CONFIG_DIR="/etc/logwhisperer"
|
||||
DATA_DIR="/var/lib/logwhisperer"
|
||||
LOG_DIR="/var/log/logwhisperer"
|
||||
|
||||
# Colori per output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Genera UUID v4
|
||||
generate_uuid() {
|
||||
# Usa /proc/sys/kernel/random/uuid se disponibile (Linux)
|
||||
if [[ -r /proc/sys/kernel/random/uuid ]]; then
|
||||
cat /proc/sys/kernel/random/uuid
|
||||
else
|
||||
# Fallback con uuidgen o generazione manuale
|
||||
if command -v uuidgen &> /dev/null; then
|
||||
uuidgen
|
||||
else
|
||||
# Generazione manuale semplice
|
||||
local hex="0123456789abcdef"
|
||||
local uuid=""
|
||||
for i in {0..35}; do
|
||||
if [[ $i == 8 || $i == 13 || $i == 18 || $i == 23 ]]; then
|
||||
uuid+="-"
|
||||
elif [[ $i == 14 ]]; then
|
||||
uuid+="4"
|
||||
elif [[ $i == 19 ]]; then
|
||||
uuid+="${hex:$((RANDOM % 4 + 8)):1}"
|
||||
else
|
||||
uuid+="${hex:$((RANDOM % 16)):1}"
|
||||
fi
|
||||
done
|
||||
echo "$uuid"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Verifica prerequisiti
|
||||
check_prerequisites() {
|
||||
log_info "Verifica prerequisiti..."
|
||||
|
||||
# Verifica bash
|
||||
if [[ "${BASH_VERSION:-}" < "4.0" ]]; then
|
||||
log_error "Richiesto Bash 4.0 o superiore"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verifica curl
|
||||
if ! command -v curl &> /dev/null; then
|
||||
log_error "curl non trovato. Installa curl: apt-get install curl / yum install curl"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verifica permessi root per installazione system-wide
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
log_warn "Esecuzione senza root. Installazione in modalità utente..."
|
||||
INSTALL_DIR="$HOME/.local/bin"
|
||||
CONFIG_DIR="$HOME/.config/logwhisperer"
|
||||
DATA_DIR="$HOME/.local/share/logwhisperer"
|
||||
LOG_DIR="$HOME/.local/log/logwhisperer"
|
||||
fi
|
||||
|
||||
log_info "Prerequisiti OK"
|
||||
}
|
||||
|
||||
# Crea directory necessarie
|
||||
create_directories() {
|
||||
log_info "Creazione directory..."
|
||||
|
||||
mkdir -p "$CONFIG_DIR"
|
||||
mkdir -p "$DATA_DIR"
|
||||
mkdir -p "$LOG_DIR"
|
||||
mkdir -p "$INSTALL_DIR"
|
||||
|
||||
log_info "Directory create"
|
||||
}
|
||||
|
||||
# Configura il client
|
||||
configure_client() {
|
||||
log_info "Configurazione LogWhisperer..."
|
||||
|
||||
local config_file="$CONFIG_DIR/config.env"
|
||||
local client_id
|
||||
local webhook_url
|
||||
local log_sources
|
||||
|
||||
# Genera CLIENT_ID
|
||||
client_id=$(generate_uuid)
|
||||
log_info "Client ID generato: $client_id"
|
||||
|
||||
# Chiedi WEBHOOK_URL
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "Configurazione Webhook"
|
||||
echo "=========================================="
|
||||
read -p "Inserisci l'URL del webhook n8n: " webhook_url
|
||||
|
||||
if [[ -z "$webhook_url" ]]; then
|
||||
log_warn "Nessun webhook URL fornito. Lo script funzionerà in modalità offline."
|
||||
webhook_url=""
|
||||
elif [[ ! "$webhook_url" =~ ^https:// ]]; then
|
||||
log_warn "L'URL non usa HTTPS. Si consiglia di usare HTTPS per la sicurezza."
|
||||
fi
|
||||
|
||||
# Configura LOG_SOURCES
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "Configurazione Sorgenti Log"
|
||||
echo "=========================================="
|
||||
|
||||
# Rileva sistema e propone defaults
|
||||
local default_sources="/var/log/syslog"
|
||||
if [[ -f /etc/redhat-release ]]; then
|
||||
default_sources="/var/log/messages"
|
||||
fi
|
||||
|
||||
if [[ -f /var/log/nginx/error.log ]]; then
|
||||
default_sources="$default_sources,/var/log/nginx/error.log"
|
||||
fi
|
||||
|
||||
if [[ -d /var/log/postgresql ]]; then
|
||||
default_sources="$default_sources,/var/log/postgresql/*.log"
|
||||
fi
|
||||
|
||||
read -p "Sorgenti log da monitorare [$default_sources]: " log_sources
|
||||
log_sources="${log_sources:-$default_sources}"
|
||||
|
||||
# Chiedi POLL_INTERVAL
|
||||
echo ""
|
||||
read -p "Intervallo di polling in secondi [5]: " poll_interval
|
||||
poll_interval="${poll_interval:-5}"
|
||||
|
||||
# Scrivi configurazione
|
||||
cat > "$config_file" <<EOF
|
||||
# LogWhisperer Configuration
|
||||
# Generato automaticamente il $(date)
|
||||
|
||||
WEBHOOK_URL="$webhook_url"
|
||||
CLIENT_ID="$client_id"
|
||||
LOG_SOURCES="$log_sources"
|
||||
POLL_INTERVAL=$poll_interval
|
||||
MAX_LINE_LENGTH=2000
|
||||
EOF
|
||||
|
||||
chmod 600 "$config_file"
|
||||
log_info "Configurazione salvata in: $config_file"
|
||||
|
||||
# Mostra riepilogo
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "Riepilogo Configurazione"
|
||||
echo "=========================================="
|
||||
echo "Client ID: $client_id"
|
||||
echo "Webhook URL: ${webhook_url:-<non configurato>}"
|
||||
echo "Log Sources: $log_sources"
|
||||
echo "Poll Interval: ${poll_interval}s"
|
||||
echo "Config File: $config_file"
|
||||
echo "=========================================="
|
||||
}
|
||||
|
||||
# Installa lo script
|
||||
install_script() {
|
||||
log_info "Installazione script..."
|
||||
|
||||
local source_script="$SCRIPT_DIR/logwhisperer.sh"
|
||||
local target_script="$INSTALL_DIR/logwhisperer"
|
||||
|
||||
if [[ ! -f "$source_script" ]]; then
|
||||
log_error "Script sorgente non trovato: $source_script"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cp "$source_script" "$target_script"
|
||||
chmod +x "$target_script"
|
||||
|
||||
log_info "Script installato in: $target_script"
|
||||
}
|
||||
|
||||
# Crea systemd service (se root)
|
||||
create_systemd_service() {
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
log_info "Installazione utente: salto creazione servizio systemd"
|
||||
return 0
|
||||
fi
|
||||
|
||||
log_info "Creazione servizio systemd..."
|
||||
|
||||
local service_file="/etc/systemd/system/logwhisperer.service"
|
||||
|
||||
cat > "$service_file" <<EOF
|
||||
[Unit]
|
||||
Description=LogWhisperer Agent - Log Monitoring Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=$INSTALL_DIR/logwhisperer --config $CONFIG_DIR/config.env
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
User=root
|
||||
Group=adm
|
||||
StandardOutput=append:$LOG_DIR/agent.log
|
||||
StandardError=append:$LOG_DIR/agent.log
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
log_info "Servizio systemd creato"
|
||||
log_info "Per avviare: systemctl start logwhisperer"
|
||||
log_info "Per abilitare all'avvio: systemctl enable logwhisperer"
|
||||
}
|
||||
|
||||
# Testa l'installazione
|
||||
test_installation() {
|
||||
log_info "Test installazione..."
|
||||
|
||||
if ! command -v logwhisperer &> /dev/null; then
|
||||
# Aggiungi a PATH se necessario
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
log_warn "Aggiungi $INSTALL_DIR al tuo PATH:"
|
||||
echo " export PATH=\"\$PATH:$INSTALL_DIR\""
|
||||
echo " oppure riavvia la shell"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Testa la configurazione
|
||||
local config_file="$CONFIG_DIR/config.env"
|
||||
if [[ -f "$config_file" ]]; then
|
||||
# shellcheck source=/dev/null
|
||||
source "$config_file"
|
||||
|
||||
if [[ -n "${WEBHOOK_URL:-}" ]]; then
|
||||
log_info "Test di connettività al webhook..."
|
||||
if curl -s -o /dev/null -w "%{http_code}" "$WEBHOOK_URL" | grep -q "200\\|404"; then
|
||||
log_info "Webhook raggiungibile"
|
||||
else
|
||||
log_warn "Webhook non raggiungibile. Verifica l'URL."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
log_info "Test completato"
|
||||
}
|
||||
|
||||
# Mostra istruzioni finali
|
||||
show_instructions() {
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "Installazione Completata!"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "Comandi disponibili:"
|
||||
echo " logwhisperer --help Mostra help"
|
||||
echo " logwhisperer --validate Verifica configurazione"
|
||||
echo " logwhisperer --dry-run --test-line 'FATAL error' Test pattern"
|
||||
echo ""
|
||||
|
||||
if [[ $EUID -eq 0 ]]; then
|
||||
echo "Gestione servizio:"
|
||||
echo " systemctl start logwhisperer Avvia servizio"
|
||||
echo " systemctl stop logwhisperer Ferma servizio"
|
||||
echo " systemctl status logwhisperer Stato servizio"
|
||||
echo " journalctl -u logwhisperer -f Log servizio"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo "File importanti:"
|
||||
echo " Config: $CONFIG_DIR/config.env"
|
||||
echo " Logs: $LOG_DIR/"
|
||||
echo " Data: $DATA_DIR/"
|
||||
echo ""
|
||||
echo "Prossimi passi:"
|
||||
echo " 1. Verifica la configurazione: logwhisperer --validate"
|
||||
echo " 2. Testa il pattern matching: logwhisperer --dry-run --test-line 'ERROR test'"
|
||||
echo " 3. Avvia il monitoraggio"
|
||||
|
||||
if [[ $EUID -eq 0 ]]; then
|
||||
echo " systemctl start logwhisperer"
|
||||
else
|
||||
echo " logwhisperer --config $CONFIG_DIR/config.env"
|
||||
fi
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
}
|
||||
|
||||
# Main
|
||||
main() {
|
||||
echo ""
|
||||
echo "╔══════════════════════════════════════════╗"
|
||||
echo "║ LogWhisperer Agent Installer ║"
|
||||
echo "║ Versione 1.0.0 ║"
|
||||
echo "╚══════════════════════════════════════════╝"
|
||||
echo ""
|
||||
|
||||
check_prerequisites
|
||||
create_directories
|
||||
configure_client
|
||||
install_script
|
||||
create_systemd_service
|
||||
test_installation
|
||||
show_instructions
|
||||
}
|
||||
|
||||
# Se eseguito direttamente
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
main "$@"
|
||||
fi
|
||||
Reference in New Issue
Block a user