Очистить файлы журнала доступа Apache?

Очистить файлы журнала доступа Apache?

У нас есть этот код в скрипте оболочки, который передает вывод Apache в журнал.

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

Однако это крайне неэффективно. За считанные секунды access.logувеличилось вчетверо экспоненциально до точки, где корневой срез сервера заполнился. Ищем лучший способ скрыть конфиденциальные данные, такие как пароли, пока Apache пишет в access.log.

решение1

Проблема в том, что вы одновременно читаете из журнала Apache и пишете в него. Все, что вы добавили в журнал, также возвращается в конвейер через вызов cat(без игры слов :) ). Это создает неприятный цикл положительной обратной связи, который будет работать до тех пор, пока ваша файловая система не заполнится. Ответ наэтот вопросВам может быть интересно узнать, почему это происходит.

Как же тогда поступить? Наивным решением было бы изменить файл на месте, например так:

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

и никуда не перенаправляйте вывод: скрипт сам изменит файлна месте. Также см. ответ Тердона о том, как сделать вызов sedтолько один раз (без цикла), чтобы повысить эффективность.

Проблема с этим подходом, однако, заключается в том, что работающий сервер Apache, скорее всего, будет регистрировать события в файле, пока вы работаете с ним, и могут начать происходить странные вещи. Лучшим решением было бы поискать в документации Apache способы сохранения конфиденциальной информации вне журналов.

Кстати, то, что вы делаете, даже не очищает журналы: вы добавляете очищенные строки обратно в (все еще испорченный) файл журнала.

решение2

На данный момент, есть различные улучшения, которые вы можете сделать. Первое, и наименее важное, у вас естьбесполезное использование кота. Гораздо важнее то, что вы запускаете sedнесколько раз, каждый из которых выведет весь файл. Я не совсем уверен, что вы делаете с grep, вы пытаетесь вывести только те строки, которые содержат определенную переменную?

В любом случае, один из способов сделать что-то лучше — запустить его sedодин раз и сделать все замены. Что-то вроде:

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

Связанный контент