Limpar arquivos de log de acesso do Apache?

Limpar arquivos de log de acesso do Apache?

Temos esse código em um script de shell que canaliza a saída para o Apache registrar.

declare -a values=( $taintRequestVals )

for item in ${!values[@]}
do
    cat $apacheLog | sed "s/${values[$item]}=[^&\t\n]*/${values[$item]}=***/g" | /bin/grep ${values[$item]}=
done

No entanto, é extremamente ineficiente. Em segundos, access.logquadruplicou exponencialmente até o ponto em que a fatia raiz do servidor foi preenchida. Procurando uma maneira melhor de ofuscar dados confidenciais, como senhas, enquanto o Apache está gravando no access.log.

Responder1

O problema aqui é que você está lendo o log do Apache e gravando nele ao mesmo tempo. Tudo o que você adicionou ao log também retorna ao pipeline por meio da catchamada (sem intenção de jogo de palavras :)). Isso cria um ciclo de feedback positivo desagradável que continuará funcionando até que o sistema de arquivos fique cheio. A resposta paraessa questãopode ser interessante para você saber por que isso acontece.

Como você deve fazer isso então? Uma solução ingênua seria modificar o arquivo da seguinte forma:

for item in ${!values[@]};do
    sed -i "..." "$apacheLog"  #cat isn't needed here
done

e não canalize a saída para lugar nenhum: o próprio script modificará o arquivono local. Veja também a resposta de Terdon sobre como fazer a sedchamada apenas uma vez (sem loop) para melhorar a eficiência.

O problema com essa abordagem, entretanto, é que um servidor Apache ativo provavelmente registrará coisas no arquivo enquanto você trabalha nele e coisas estranhas podem começar a acontecer. Uma solução melhor seria procurar na documentação do Apache maneiras de manter informações confidenciais fora dos logs.

Aliás, o que você está fazendo nem mesmo higieniza os logs: ele anexa as linhas higienizadas de volta ao arquivo de log (ainda contaminado).

Responder2

Da forma como está, existem várias melhorias que você pode fazer. Primeiro, e menos importante, você tem umuso inútil de gato. O que é muito mais importante é que você execute sedvárias vezes, cada uma delas imprimindo o arquivo inteiro. Não tenho certeza do que você está fazendo grep. Você está tentando imprimir apenas as linhas que contêm a variável específica?

De qualquer forma, uma maneira de fazer melhor as coisas seria executar seduma vez e fazer todas as substituições. Algo como:

replace=""
for item in ${!values[@]}
do
    ## build the sed line
    replace="s/${values[$item]}=[^&\t\n]*/${values[$item]}=***/g;$replace"
done

### run the replacement using sed's -i option so it 
### changes the original file
eval sed -i \""$replace"\" $apacheLog

informação relacionada