从 apache 错误日志中排除 ping(从 PHP exec 运行)

从 apache 错误日志中排除 ping(从 PHP exec 运行)

现在,由于多种原因,我需要定期 ping 多个主机以显示仪表板。

我使用这个 PHP 函数来做到这一点:

function PingHost($strIpAddr) {
        exec(escapeshellcmd('ping -q -W 1 -c 1 '.$strIpAddr), $dataresult, $returnvar);
        if (substr($dataresult[4],0,3) == "rtt") {
                //We got a ping result, lets parse it.
                        $arr = explode("/",$dataresult[4]);
                        return ereg_replace(" ms","",$arr[4]);
        } elseif (substr($dataresult[3],35,16) == "100% packet loss") {
                //Host is down!
                        return "Down";
        } elseif ($returnvar == "2") {
                return "No DNS";
        }
}

问题是,只要有未知主机,我的 apache 错误日志 (/var/log/apache/error.log) 中就会记录错误。我该如何禁用此特定功能的日志?

禁用 vhost 中的日志不是一个选项,因为该 vhost 的日志是相关的,只是与 ping 无关。

谢谢,

答案1

您需要对函数进行一些更改 - 基本上 exec 不会捕获写入日志文件的标准错误 - 您需要按如下方式更改函数

function PingHost($strIpAddr) {
    exec(escapeshellcmd('ping -q -W 1 -c 1 '.$strIpAddr.' 2>&1'), $dataresult, $returnvar);
    if (substr($dataresult[4],0,3) == "rtt") {
            //We got a ping result, lets parse it.
                    $arr = explode("/",$dataresult[4]);
                    return ereg_replace(" ms","",$arr[4]);
    } elseif (substr($dataresult[3],35,16) == "100% packet loss") {
            //Host is down!
                    return "Down";
    } elseif ($returnvar == "2") {
            return "No DNS";
    }
    if($returnvar == 68)
            return "Unknown host";

}

答案2

这是一个相当老的帖子,但当我深入研究我所面临的类似问题时发现它时,我想它可能会帮助其他人分享。

我编写了以下函数来处理应用程序中对命令行函数的所有调用。它的行为方式与 exec 类似,但有一些有用的补充:

  • 接受一个关联参数数组,这些参数将被转义escapeshellarg并随后替换到命令中strtr
  • 使用以下方式转义 shell 命令本身escapeshellcmd
  • 2>&1使用上面提到的方法将 stderr 重定向到 stdout西尔维乌德

函数如下:

/**
 * @param string   $command Use ':param_key' to escape arguments.
 * @param string[] $output
 * @param int|null $return
 * @param string[] $args    Use format [ 'param_key' => 'param_value' ].
 *
 * @return string
 */
function safe_exec( $command, &$output = null, &$return = null, $args = array() ) {
    // Escape all args
    foreach( $args as $arg_key => $arg_value ) {
        $args[ ':' . $arg_key ] = escapeshellarg( $arg_value );
        unset( $args[ $arg_key ] );
    }

    // Escape command and replace params
    $command = strtr( escapeshellcmd( $command ), $args ) . ' 2>&1';

    // Exec and return
    return exec( $command, $output, $return );
} // safe_exec

举一个简单的使用示例,我是这样使用它来检索我们的理光打印机的托盘状态的:

/**
 * These values are entered by the user (which is why we escape them), 
 * but for example:
 * 
 * $address = '10.243.224.42'
 * $tray = 1
 */

$oid = '1.3.6.1.4.1.367.3.2.1.2.20.2.2.1.11.2.' . $tray;

$command = "snmpwalk -v 2c -c public :address :oid";
safe_exec( $command, $output, $return, array(
    'address' => $address,
    'oid' => $oid,
) );

相关内容