【问题标题】:Piping Apache log through script - not working for error log通过脚本管道 Apache 日志 - 不适用于错误日志
【发布时间】:2013-09-10 12:58:58
【问题描述】:

我正在为多个用户构建一个 LAMP 服务器以使用 mod_userdir 练习 Web 开发,并编写了脚本来分解访问和错误日​​志以记录用户主目录中的目录。

access_log.sh 脚本工作正常(日志行同时写入主服务器日志文件和用户日志文件),但 error_log.sh 仅更新主日志文件。这是error_log.sh:

#!/bin/bash

IFS='
'

userlogfile=error.log
syslogfile=/var/log/apache2/cs-web_error.log

homedirs=`ls -d /home/*`

while read logline; do
    echo -e ${logline} >> ${syslogfile}
    #echo -e "writing ${logline} to ${syslogfile}" #TESTING

    for homedir in $homedirs; do
        userlogpath="${homedir}/logs/${userlogfile}"
        if echo $logline | grep ${homedir} > /dev/null; then
            echo -e ${logline} >> ${userlogpath}
            #echo -e "writing ${logline} to ${userlogpath}" #TESTING
        fi
    done
done

Apache 的日志配置是:

CustomLog "| ${APACHE_LOG_DIR}/access_log.sh" common
ErrorLog "| ${APACHE_LOG_DIR}/error_log.sh"

如果我取消注释 #TESTING 语句,我会在通过脚本传送错误日志时得到如下输出:

writing [Fri Sep 06 12:15:11 2013] [error] [client 193.61.230.178] PHP Parse error:
syntax error, unexpected 'select' (T_STRING) in /home/ginny/htdocs/test.php on line 12 
to /var/log/apache2/cs-web_error.log
writing [Fri Sep 06 12:15:11 2013] [error] [client 193.61.230.178] PHP Parse error:  
syntax error, unexpected 'select' (T_STRING) in /home/ginny/htdocs/test.php on line 12 
to /home/ginny/logs/error.log

... 这表明 grep 语句正在工作。此外,像这样手动运行,文件被创建并写入:

root@cs-web:~# ls -l /home/ginny/logs/
total 16
-rw-r--r-- 1 root root 2213 Sep  6 12:53 access.log
-rw-r--r-- 1 root root 9984 Sep  6 12:49 error.log

我很难理解的是为什么这适用于访问日志,而不适用于错误日志 - 唯一的区别是:

root@cs-web:/var/log/apache2# diff access_log.sh error_log.sh
6,7c6,7
< userlogfile=access.log
< syslogfile=/var/log/apache2/cs-web_access.log
---
> userlogfile=error.log
> syslogfile=/var/log/apache2/cs-web_error.log
12a13
>     #echo -e "writing ${logline} to ${syslogfile}"
15,17c16,17
<         homedir=${homedir#/home/}
<         userlogpath="/home/${homedir}/logs/${userlogfile}"
<         if echo $logline | egrep "/(~|users/)${homedir}/" > /dev/null; then
---
>         userlogpath="${homedir}/logs/${userlogfile}"
>         if echo $logline | grep ${homedir} > /dev/null; then
18a19
>             #echo -e "writing ${logline} to ${userlogpath}"

非常感谢您的建议。

【问题讨论】:

    标签: shell logging apache2 lamp


    【解决方案1】:

    正确引用您的变量并改用数组。 readarray 也比依赖分词和可能通过路径名扩展生成更好。

    #!/bin/bash
    
    #IFS=$'\n'  ## No longer needed.
    
    userlogfile=error.log
    syslogfile=/var/log/apache2/cs-web_error.log
    
    readarray -t homedirs < <(ls -d /home/*)
    
    while read logline; do
        echo -e "${logline}" >> "${syslogfile}"
        #echo -e "writing ${logline} to ${syslogfile}" #TESTING
    
        for homedir in "${homedirs[@]}"; do
            userlogpath="${homedir}/logs/${userlogfile}"
            if echo "$logline" | grep "${homedir}" > /dev/null; then
                echo -e "${logline}" >> "${userlogpath}"
                #echo -e "writing ${logline} to ${userlogpath}" #TESTING
            fi
        done
    done
    

    但是如果你的版本早于4.0,那就用其他方法吧:

    IFS=$'\n'
    homedirs=($(ls -d /home/*))
    

    为了安全起见,我建议您也对其他脚本使用相同的概念。

    更新

    在您的第二个脚本中,您不再尝试用/home/ 修剪$homedir,这意味着如果"$homedir" 不以/home/ 开头,$userlogpath 可能是&lt;user&gt;/logs/${userlogfile}",而在您的第一个脚本仍然是/home/&lt;user&gt;/logs/${userlogfile}。尝试在您的 error_log.sh 中也使用这些行。

         homedir=${homedir#/home/}
         userlogpath="/home/${homedir}/logs/${userlogfile}"
    

    【讨论】:

    • 哦,我不太相信 - 抱歉之前的疑问,konsolebox - 我尝试了你的更改,它正在工作。不得不说我真的不明白为什么这可以解决问题,但确实可以。比你。
    • @robhogg 不用担心。欢迎:)
    猜你喜欢
    • 1970-01-01
    • 2023-04-04
    • 2012-08-05
    • 1970-01-01
    • 2012-12-06
    • 1970-01-01
    • 2013-01-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多