总结
将 Apache 错误日志传送到自定义脚本无法按预期工作。Apache 将核心消息发送到脚本。但来自 PHP 或 authz_core_module 的日志仍然会出现在 Apache 的默认日志文件中。
我想要的是
我使用 Apache 和 PHP(通过 PHP Apache 模块)作为网络空间。目前 Apache 的所有错误消息和PHP 已登录/var/log/apache2/error.log
。这是 Debian 下 Apache 的默认日志记录位置。此外,PHP 的error_log
指令未设置。因此 PHP应该将其日志发送到 Apache Logger。到目前为止,一切正常。
现在我想要利用 Apache 的一个功能。管道日志可用于将访问或错误日志传输到自定义脚本。此自定义脚本现在可以匿名化 IP 地址、在调试程序中显示错误、过滤消息、将过滤后的消息写入原始日志等。
我尝试过
为了实现这一点,我将以下内容附加到我的 apache2.conf:
ErrorLog "|$php /path/to/script/log.php"
CustomLog "|$php /path/to/script/log.php" common
自定义日志并非绝对必要。但出于测试目的,我想确保所有内容都已捕获。内容log.php
如下:
ob_implicit_flush(true);
while($f = fgets(STDIN))
{
file_put_contents("/path/to/script/log.txt", $f, FILE_APPEND);
}
发生了什么
现在发生了一些奇怪的事情。访问日志被写入log.txt
(如预期的那样),Appache 的核心错误如下¹:
[...] [so:warn] [pid 23307] AH01574: module ssl_module is already loaded, skipping
[...] [mpm_prefork:notice] [pid 23307] AH00163: Apache/2.4.25 (Debian) OpenSSL/1.0.2l configured -- resuming normal operations
被写入log.txt
(如预期)。但是,大多数模块的日志消息仍然写入/var/log/apache2/error.log
,包括¹:
[...] [authz_core:error] [pid 40549] [...] AH01630: client denied by server configuration: /var/www/html/webpage/secret
[...] [:error] [pid 58611] [...] PHP Parse error: syntax error, unexpected 'foo' (T_STRING) in /var/www/html/webpage/index.php on line 3
- PHP
error_log()
函数记录的所有内容
是否也可以将这些消息包含在管道中?如果可以,该怎么做?为什么 Apache 只通过我的脚本传输一些核心消息,而不传输来自模块的消息?
我知道我可以用脚本读取日志。但这使得过滤、匿名² 和/或将它们用于实时调试控制台变得更加困难。我只是想知道管道日志(或 Apache 或 PHP 中内置的类似内容)是否完全可用于此目的。
¹ IP 地址和时间戳缩短至 [...]
² 据我所知,在某些国家/地区,即使暂时保存 IP 地址也可能不合法。因此,管道化和匿名化或完全从日志格式中去除地址是唯一的选择。
一些版本信息(以防万一......)
阿帕奇
# apachectl -v
Server version: Apache/2.4.25 (Debian)
Server built: 2017-10-24T14:45:24
PHP
# php -v
PHP 7.0.33-0+deb9u7 (cli) (built: Feb 16 2020 15:11:40) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies
with Zend OPcache v7.0.33-0+deb9u7, Copyright (c) 1999-2017, by Zend Technologies
Linux/Debian
# uname -a
Linux <servername> 4.9.0-8-amd64 #1 SMP Debian 4.9.144-3 (2019-02-02) x86_64 GNU/Linux
# lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 9.12 (stretch)
Release: 9.12
Codename: stretch
答案1
后来发现错误完全在我这边。我不知为何无法正确读取配置文件。
中有两个配置文件/etc/apache2/sites-enabled/
。其中一个是由 certbot 自动创建的(我认为),并由我进行了大量编辑。它包含管理 *:443 的 SSL 证书的虚拟主机。我知道这一点,并在发布之前搜索了它们以查找与我的问题相关的任何内容。但似乎我当时这样做是盲目的。半小时前,当我出于不相关的原因查看它时,我在几个虚拟主机中看到了这一点:
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
:捂脸:
是的。ErrorLog 和 CustomLog 在那里被覆盖了。注释掉它们解决了我的问题。现在所有消息都通过我的脚本传输。