我正在使用supervisord来管理需要在后台运行的php程序。该程序将事件记录到文件worker_log
。在supervisord.conf
我正在使用:
stderr_logfile=/var/log/supervisord/worker_log;
但是,我希望写入日志的事件能够自己加时间戳。我无法控制php程序,所以装饰它的日志不是一个选项。我想我要做的就是注释掉上面的日志记录配置,并通过管理员命令配置中的命令行管道来装饰程序:
command=php /www/myapp/worker.php 2>&1 | sed "s/^/`date` /" > /var/log/supervisord/worker_log;
手动运行此命令时似乎工作正常。然而,supervisord似乎以某种方式阻止它正常运作,我无法告诉如何。 worker.php
执行正常,但在此配置中,它的报告已被抑制。而且,正因为如此,它当然不会添加时间戳。
有没有人对此有足够的了解,为如何实现工人输出时间戳的目标提供指导?
答案 0 :(得分:7)
您可以编写一个专用的包装器脚本,在调用您的工作器代码之前将过滤器附加到stderr:
// filter to prepend date/time on all stderr output
class eventdata_filter extends php_user_filter
{
function filter($in, $out, &$consumed, $closing)
{
while (($bucket = stream_bucket_make_writeable($in))) {
$bucket->data = date('c') . ' ' . $bucket->data;
$consumed += $bucket->datalen;
stream_bucket_append($out, $bucket);
}
return PSFS_PASS_ON;
}
}
// register our custom filter
stream_filter_register('eventdata', 'eventdata_filter');
// keep a reference to the attached filter
$filter = stream_filter_append(STDERR, 'eventdata', STREAM_FILTER_WRITE);
// isolate the worker from any variables in this scope, such as $filter
function run()
{
include 'worker.php';
}
// run the worker
run();
// remove the filter
stream_filter_remove($filter);
顺便说一句,如果你不删除过滤器会导致分段错误(至少在5.4上测试过)。
答案 1 :(得分:4)
之前的答案(来自Jack)是正确的,因为您需要另一层代码来为每一行添加时间戳。 perl中的这个单行程将达到相同的结果:
perl -ne '@timeparts=localtime(); printf("%04d/%02d/%02d %02d:%02d:%02d %s",$timeparts[5]+1900,$timeparts[4]+1,@timeparts[3,2,1,0], $_);'
使用它代替sed脚本。
您尝试的方法无法解决的一个问题是日期是在调用sed命令时由shell计算并替换为shell,因此所有行都具有相同的日志时间戳
答案 2 :(得分:0)
编辑:猜猜我将留在这里。正是由于sed命令永久使用其启动date
输出,因此这种方法不起作用,因此时间戳是不正确的。
另一种实现此目标的方法(非常接近您的最初尝试)是将原始命令放在bash -c "command here"
的引号内,例如
command=bash -c 'php /www/myapp/worker.php 2>&1 | sed "s/^/`date` /" >> /var/log/supervisord/worker_log';
请注意,由于我倾向于保留这些日志并通过>
规则管理日志文件,因此我从>>
切换到logrotate
。
对于更一般的情况,您可能还需要设置您的环境,这看起来似乎有点不合理,但至少要在一个地方进行检查。玩具示例:bash -c "source ~/setup.bash && php /www/myapp/worker.php 2>&1 | sed ... >> /your/logfile/path.log"
(免责声明:给我这个惊喜的答案还不存在,令我感到有些惊讶,因此得知这是一种不好的做事方式,我就不会感到惊讶)