清理 Apache 访问日志文件?

清理 Apache 访问日志文件?

我们在 shell 脚本中包含此代码,该脚本通过管道输出供 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

并且不要将输出传送到任何地方:脚本本身将修改文件就地。另请参阅terdon的答案,了解如何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

相关内容