1
resposta

Converter para Linux

Bom dia Mestre, estou gostando muito do curso, estou seguindo as aulas utilizando containers docker em uma VM Linux, e estou tendo dificuldades para converter esse script para ".bash" para rodar dentro do container, até utilizei da IA, porem ao executar o script, esta entra em looping infinito, pq o script executa consulta no DB, poderia me ajudar com isso?

Segue script testado om looping infinito `#!/bin/bash

Configurações

STATEMENT_KEYWORD="statement:"
DURATION_KEYWORD="duration:"
POSTGRES_VERSION="16"
TABLE_NAME="query_logs"

Variáveis de conexão

PGUSER="postgres"
PGPASSWORD="postgres"
PGDATABASE="FRUTALLY_VENDAS"
PGHOST="localhost"
PGPORT="5432"

Caminhos

LOG_DIR="/var/lib/postgresql/data/log/"
TEMP_SQL_FILE="/tmp/insert_queries.sql"

Criar arquivo temporário

mkdir -p /tmp
> "$TEMP_SQL_FILE"

echo "Iniciando análise de logs..."

Função para processar um statement

process_statement() {
    local datetime="$1"
    local duration="$2"
    local query="$3"
    

Limpar e formatar valores

datetime=$(echo "$datetime" | sed 's/ LOG:.*//' | sed 's/ CEST.*//')
duration=$(echo "$duration" | sed "s/.*$DURATION_KEYWORD\s*//" | sed 's/ ms//')
query=$(echo "$query" | sed "s/^$STATEMENT_KEYWORD\s*//" | xargs)

Verificar se é uma linha válida

if [ -z "$datetime" ] || [ -z "$duration" ] || [ -z "$query" ]; then
    echo "Erro: Valores inválidos detectados"
    return 1
fi

Ignorar queries que referenciam a própria tabela de logs

if [[ "$query" == *"$TABLE_NAME"* ]]; then
    echo "Consulta descartada por referenciar a tabela."
    return 0
fi

Escapar aspas simples para SQL

query_escaped=$(echo "$query" | sed "s/'/''/g")

Verificar se a consulta já existe

check_sql="SELECT COUNT(*) FROM $TABLE_NAME WHERE log_time = '$datetime' AND duration_s = $duration AND query = '$query_escaped';"
check_result=$(PGPASSWORD="$PGPASSWORD" psql -U "$PGUSER" -d "$PGDATABASE" -h "$PGHOST" -p "$PGPORT" -c "$check_sql" -t)

if [ "$check_result" -eq 0 ]; then
    echo "INSERT INTO $TABLE_NAME (log_time, duration_s, query, checkquery) VALUES ('$datetime', $duration, '$query_escaped', 'NOTCHECK');" >> "$TEMP_SQL_FILE"
else
    echo "Query já incluída na tabela"
fi

}

Processar arquivos de log

for logfile in "$LOG_DIR"/*.log; do
    echo "Processando arquivo de log: $logfile"

Variáveis de estado

accumulating_query=false
statement_line=""
query=""
duration_line=""
datetime=""

while IFS= read -r line; do

Verificar se é uma linha de statement

    if [[ "$line" == *"$STATEMENT_KEYWORD"* ]]; then

Processar statement anterior se existir

        if [ "$accumulating_query" = true ] && [ -n "$statement_line" ]; then
            process_statement "$datetime" "$(echo "$duration_line" | grep -oP "$DURATION_KEYWORD \K[0-9.]+")" "$query"
        fi
        
        accumulating_query=true
        statement_line="$line"
        query=$(echo "$line" | sed "s/.*$STATEMENT_KEYWORD\s*//")
        

Extrair datetime da linha

        datetime=$(echo "$line" | grep -oP '^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}')
        
    elif [ "$accumulating_query" = true ]; then

Verificar se é uma linha de duration

    if [[ "$line" == *"$DURATION_KEYWORD"* ]]; then
        duration_line="$line"
        process_statement "$datetime" "$(echo "$duration_line" | grep -oP "$DURATION_KEYWORD \K[0-9.]+")" "$query"
        accumulating_query=false
        statement_line=""
        query=""
        duration_line=""
    else
        # Acumular linhas da query
        query="$query $line"
    fi
fi
done < "$logfile"
done

echo "Filtragem de logs concluída"

Executar comandos SQL gerados

if [ -s "$TEMP_SQL_FILE" ]; then
    echo "Executando comandos SQL..."
    psql -U "$PGUSER" -d "$PGDATABASE" -h "$PGHOST" -p "$PGPORT" -f "$TEMP_SQL_FILE"
else
    echo "Nenhum comando SQL para executar."
fi

echo "Processamento concluído"`
1 resposta

Ei, Aulino! Tudo bom?

Agradeço por aguardar o nosso retorno.

Fico feliz que esteja gostando do curso!

O problema pode estar ligado ao acúmulo incorreto de queries ou à falta de redefinição das variáveis de estado. Recomendo que revise alguns pontos:

  • Após processar um statement, defina accumulating_query=false para evitar acumulação indevida.
  • Reinicie statement_line, query, duration_line e datetime após cada iteração.
  • Confirme se o loop while IFS= read -r line para certo ao fim das linhas.
  • Use echo para exibir valores das variáveis durante o processamento e identificar falhas.

Um exemplo de redefinição de código com os pontos mencionados:

if [ "$accumulating_query" = true ] && [ -n "$statement_line" ]; then
    process_statement "$datetime" "$(echo "$duration_line" | grep -oP "$DURATION_KEYWORD \K[0-9.]+")" "$query"
    accumulating_query=false
    statement_line=""
    query=""
    duration_line=""
    datetime=""
fi

Espero que isso ajude a resolver o problema. Conte sempre com a gente por aqui.

Até mais, Aulino!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado!