我有一个为每个请求编写日志的 API。还有另一个后台任务始终在运行并使用相同的记录器来记录错误等。由于该进程始终在运行并且具有对文件的引用,因此 API 实际上从未获得在那里写入的权限。
我正在使用独白作为带有“StreamHandler”处理程序的记录器。
我的目标是在两个进程中使用相同的日志文件。我怎样才能实现它?monolog 有没有什么简单的方法可以在写完东西后释放文件的访问锁并在写之前再次获得它?谢谢。
我有一个为每个请求编写日志的 API。还有另一个后台任务始终在运行并使用相同的记录器来记录错误等。由于该进程始终在运行并且具有对文件的引用,因此 API 实际上从未获得在那里写入的权限。
我正在使用独白作为带有“StreamHandler”处理程序的记录器。
我的目标是在两个进程中使用相同的日志文件。我怎样才能实现它?monolog 有没有什么简单的方法可以在写完东西后释放文件的访问锁并在写之前再次获得它?谢谢。
我自己一直在想这个;考虑到 php 在像 mod_php 这样的多进程环境中运行的频率,令人惊讶的是,那里没有多少明确的文档。
最明显的解决方案是不直接利用 StreamHandler,而是依赖 syslog 或排序。PHP 本身并不真正处理线程/多进程支持,但 syslog(及其多个变体)在套接字上侦听,具有相对先进的路由功能,并且是线程安全的。
既然你提到你有一个后台任务正在运行并使用相同的记录器,也许你可以扩展这个后台进程来监听一个套接字并负责记录来自你其他进程的消息(或者,更好的是,有一些其他后台任务)为此;SRP 的存在是有原因的)。
不是 100% 准确,但看看这个 SO answer。
我自己很好奇,所以我写了以下简单的脚本:
测试.php
require_once __DIR__ . '/vendor/autoload.php';
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
$log = new Logger( 'Test' . `tasklist | grep php | wc -l` );
$log->pushHandler(new StreamHandler(__DIR__ . '/file.log', Logger::DEBUG));
while ( true ) {
$log->debug( "This is a single log line" );
}
我在一台 Win 8.1 四核机器上并行运行了 8 个脚本。
在第一次运行时,我遇到了罕见的打嗝,换行符会被放错位置,这样你会在同一行得到两个日志转储,然后一个空行(换行符)。
在第二次运行时,我根本没有打嗝。
(*) 请注意,单个脚本在我的机器上写入了 10000 行,因此在平均每秒 80000 行(并且在第二次运行时没有)时获得罕见的打嗝......相当不错。
干杯。