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