HEX
Server: LiteSpeed
System: Linux cluster02.load-balancer.x2.network 4.18.0-553.51.1.lve.1.el8.x86_64 #1 SMP Wed May 14 14:34:57 UTC 2025 x86_64
User: kbdhpghp (1098)
PHP: 8.2.29
Disabled: NONE
Upload Files
File: /home/kbdhpghp/logs/logs-de-acesso/logs.sh
#!/bin/bash

# Script de colorização automática do log do dia atual
# Monitora automaticamente: /home/*/logs/logs-de-acesso/YY-MM-DD.log

LOG_BASE_DIR="/home"
DATA_HOJE=$(date '+%y-%m-%d')  # Formato: 25-09-29

# Função para encontrar arquivo de log mais recente
find_todays_log() {
    # Procura por arquivos de log de hoje em qualquer usuário
    find "$LOG_BASE_DIR" -name "$DATA_HOJE.log" -path "*/logs/logs-de-acesso/*" 2>/dev/null | head -1
}

# Função para verificar se arquivo existe e é legível
check_log_file() {
    local log_file="$1"
    if [[ ! -f "$log_file" ]]; then
        echo "❌ Arquivo de log não encontrado: $log_file" >&2
        return 1
    fi
    
    if [[ ! -r "$log_file" ]]; then
        echo "❌ Sem permissão de leitura: $log_file" >&2
        return 1
    fi
    
    echo "✅ Monitorando: $log_file" >&2
    return 0
}

# Função principal
monitor_todays_log() {
    local log_file
    
    # Tenta encontrar o arquivo de log
    log_file=$(find_todays_log)
    
    if [[ -z "$log_file" ]]; then
        echo "❌ Nenhum arquivo de log encontrado para hoje ($DATA_HOJE)" >&2
        echo "📁 Procurando em: $LOG_BASE_DIR/*/logs/logs-de-acesso/$DATA_HOJE.log" >&2
        return 1
    fi
    
    # Verifica se o arquivo é válido
    if ! check_log_file "$log_file"; then
        return 1
    fi
    
    echo "🎨 Colorizando log em tempo real: $log_file" >&2
    echo "⏰ Data: $DATA_HOJE | Use Ctrl+C para sair" >&2
    echo "----------------------------------------" >&2
    
    # Monitora o arquivo com tail -f e aplica colorização
    tail -f "$log_file" | awk '
function colorizar_campo(texto, cor) {
    # Códigos de cores ANSI
    colors["vermelho"] = "\033[1;31m"
    colors["verde"] = "\033[1;32m"
    colors["amarelo"] = "\033[1;33m"
    colors["azul"] = "\033[1;34m"
    colors["magenta"] = "\033[1;35m"
    colors["ciano"] = "\033[1;36m"
    colors["branco"] = "\033[1;37m"
    colors["reset"] = "\033[0m"
    
    return colors[cor] texto colors["reset"]
}

function colorizar_linha_completa(linha) {
    # Se a linha já contém códigos de cores, não processa novamente
    if (linha ~ /\033\[/) {
        return linha
    }
    
    # Buffer para reconstruir a linha colorida
    linha_colorida = ""
    linha_original = linha
    
    # 1. Timestamps - em ciano
    if (match(linha, /\[[^\]]+\]/)) {
        timestamp = substr(linha, RSTART, RLENGTH)
        linha_colorida = linha_colorida colorizar_campo(timestamp, "ciano") " "
        linha = substr(linha, RSTART + RLENGTH)
    }
    
    # 2. ERR - status code (vermelho para erro, verde para sucesso)
    if (match(linha, /\(ERR: [0-9]+\)/)) {
        status = substr(linha, RSTART, RLENGTH)
        codigo = status
        gsub(/[^0-9]/, "", codigo)
        if (codigo >= 400) {
            linha_colorida = linha_colorida colorizar_campo(status, "vermelho") " "
        } else {
            linha_colorida = linha_colorida colorizar_campo(status, "verde") " "
        }
        linha = substr(linha, RSTART + RLENGTH)
    }
    
    # 3. IP - azul
    if (match(linha, /\(IP: [^)]+\)/)) {
        ip = substr(linha, RSTART, RLENGTH)
        linha_colorida = linha_colorida colorizar_campo(ip, "azul") " "
        linha = substr(linha, RSTART + RLENGTH)
    }
    
    # 4. X-Forwarded-For - magenta
    if (match(linha, /\(X-Forwarded-For: [^)]+\)/)) {
        xff = substr(linha, RSTART, RLENGTH)
        linha_colorida = linha_colorida colorizar_campo(xff, "magenta") " "
        linha = substr(linha, RSTART + RLENGTH)
    }
    
    # 5. Cache - amarelo (hit/miss)
    if (match(linha, /\(Cache: [^)]+\)/)) {
        cache = substr(linha, RSTART, RLENGTH)
        if (cache ~ /hit/) {
            linha_colorida = linha_colorida colorizar_campo(cache, "verde") " "
        } else {
            linha_colorida = linha_colorida colorizar_campo(cache, "amarelo") " "
        }
        linha = substr(linha, RSTART + RLENGTH)
    }
    
    # 6. Size - verde
    if (match(linha, /\(Size: [^)]+\)/)) {
        size = substr(linha, RSTART, RLENGTH)
        linha_colorida = linha_colorida colorizar_campo(size, "verde") " "
        linha = substr(linha, RSTART + RLENGTH)
    }
    
    # 7. Time - ciano
    if (match(linha, /\(Time: [^)]+\)/)) {
        time = substr(linha, RSTART, RLENGTH)
        linha_colorida = linha_colorida colorizar_campo(time, "ciano") " "
        linha = substr(linha, RSTART + RLENGTH)
    }
    
    # 8. HTTPv - branco
    if (match(linha, /\(HTTPv: [^)]+\)/)) {
        httpv = substr(linha, RSTART, RLENGTH)
        linha_colorida = linha_colorida colorizar_campo(httpv, "branco") " "
        linha = substr(linha, RSTART + RLENGTH)
    }
    
    # 9. Method - amarelo (GET, POST, etc)
    if (match(linha, /\(Method: [^)]+\)/)) {
        method = substr(linha, RSTART, RLENGTH)
        linha_colorida = linha_colorida colorizar_campo(method, "amarelo") " "
        linha = substr(linha, RSTART + RLENGTH)
    }
    
    # 10. User-Agent - magenta (se existir)
    if (match(linha, /\(User-Agent: [^)]+\)/)) {
        ua = substr(linha, RSTART, RLENGTH)
        linha_colorida = linha_colorida colorizar_campo(ua, "magenta") " "
        linha = substr(linha, RSTART + RLENGTH)
    }
    
    # 11. URL e método HTTP - branco
    if (match(linha, /- (GET|POST|PUT|DELETE|HEAD|OPTIONS) http[^ ]+ HTTP\/[0-9.]+/)) {
        requisicao = substr(linha, RSTART, RLENGTH)
        # Remove o "- " inicial se existir
        gsub(/^- /, "", requisicao)
        linha_colorida = linha_colorida colorizar_campo(requisicao, "branco") " "
        linha = substr(linha, RSTART + RLENGTH)
    }
    
    # 12. Cluster information - ciano
    if (match(linha, /\(CL: [^)]+\)/)) {
        cluster = substr(linha, RSTART, RLENGTH)
        linha_colorida = linha_colorida colorizar_campo(cluster, "ciano")
        linha = substr(linha, RSTART + RLENGTH)
    }
    
    # Adiciona qualquer parte restante da linha
    if (linha != "" && linha != " " && linha != "- ") {
        # Remove hífen solto se existir
        gsub(/^- $/, "", linha)
        if (linha != "") {
            linha_colorida = linha_colorida colorizar_campo(linha, "branco")
        }
    }
    
    return linha_colorida
}

{
    # Processa cada linha recebida
    if (NF > 0) {
        print colorizar_linha_completa($0)
        fflush()  # Garante saída imediata para tail -f
    }
}'
}

# Opções do script
case "${1:-}" in
    "-h"|"--help")
        echo "Uso: $0 [opção]"
        echo ""
        echo "Opções:"
        echo "  -h, --help    Mostra esta ajuda"
        echo "  -l, --list    Lista arquivos de log disponíveis"
        echo "  -f, --file    Especifica um arquivo de log manualmente"
        echo "  sem opção     Monitora automaticamente o log de hoje"
        ;;
    "-l"|"--list")
        echo "📁 Arquivos de log disponíveis:"
        find "$LOG_BASE_DIR" -name "*.log" -path "*/logs/logs-de-acesso/*" 2>/dev/null | sort
        ;;
    "-f"|"--file")
        if [[ -n "$2" ]]; then
            if [[ -f "$2" ]]; then
                tail -f "$2" | awk -f <(echo "$AWK_SCRIPT")
            else
                echo "❌ Arquivo não encontrado: $2"
                exit 1
            fi
        else
            echo "❌ Especifique um arquivo: $0 -f /caminho/arquivo.log"
            exit 1
        fi
        ;;
    *)
        # Modo padrão: monitora automaticamente o log de hoje
        monitor_todays_log
        ;;
esac