Apache-Zugriffsprotokolldateien bereinigen?

Apache-Zugriffsprotokolldateien bereinigen?

Wir haben diesen Code in einem Shell-Skript, das die Ausgabe für das Protokollieren durch Apache weiterleitet.

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

Es ist jedoch äußerst ineffizient. Innerhalb von Sekunden access.logvervierfachte sich die Anzahl der Einträge exponentiell, bis der Root-Slice des Servers voll war. Wir suchen nach einer besseren Möglichkeit, vertrauliche Daten wie Passwörter zu verschleiern, während Apache in schreibt access.log.

Antwort1

Das Problem dabei ist, dass Sie gleichzeitig aus dem Apache-Protokoll lesen und darin schreiben. Was auch immer Sie dem Protokoll hinzugefügt haben, gelangt durch den catAufruf auch zurück in die Pipeline (kein Wortspiel beabsichtigt :)). Dadurch entsteht eine unangenehme positive Rückkopplungsschleife, die so lange weiterläuft, bis Ihr Dateisystem voll ist. Die Antwort aufdiese FrageVielleicht interessiert es Sie, warum das passiert.

Wie sollten Sie dann vorgehen? Eine naive Lösung wäre, die Datei an Ort und Stelle wie folgt zu ändern:

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

und leiten Sie die Ausgabe nicht weiter: das Skript selbst ändert die Dateivor Ort. Lesen Sie auch die Antwort von Terdon, um zu erfahren, wie Sie den sedAufruf zur Verbesserung der Effizienz nur einmal (ohne Schleife) tätigen können.

Das Problem bei diesem Ansatz ist jedoch, dass ein aktiver Apache-Server wahrscheinlich Dinge in die Datei protokolliert, während Sie daran arbeiten, und dass dann seltsame Dinge passieren können. Eine bessere Lösung wäre, in der Apache-Dokumentation nach Möglichkeiten zu suchen, vertrauliche Informationen aus den Protokollen herauszuhalten.

Übrigens bereinigen Sie mit Ihrem Vorgehen nicht einmal die Protokolle: Die bereinigten Zeilen werden wieder an die (immer noch fehlerhafte) Protokolldatei angehängt.

Antwort2

So wie es aussieht, gibt es verschiedene Verbesserungen, die Sie vornehmen können. Erstens und am wenigsten wichtig: Sie haben einesinnloser Einsatz der Katze. Viel wichtiger ist, dass Sie es sedmehrere Male ausführen und jedes Mal die gesamte Datei ausdrucken. Ich bin mir nicht ganz sicher, was Sie mit machen. grepVersuchen Sie, nur die Zeilen auszudrucken, die die bestimmte Variable enthalten?

Eine Möglichkeit, die Dinge besser zu machen, wäre, es sedeinmal auszuführen und alle Ersetzungen durchführen zu lassen. Etwas wie:

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

verwandte Informationen