supervisord管理的程序的时间戳日志



我正在使用supervisorord来管理一个需要在后台运行的php程序。该程序将事件注销到文件worker_log中。在我使用的supervisord.conf中配置这一点很简单:

stderr_logfile=/var/log/supervisord/worker_log;

但是,我希望写入日志的事件能够对它们自己进行时间戳。我不能控制php程序,所以装饰它的日志不是一个选项。我想我要做的是注释掉上面的日志记录配置,并通过supervisor的命令配置中的命令行管道装饰程序:

command=php /www/myapp/worker.php 2>&1 | sed "s/^/`date` /" > /var/log/supervisord/worker_log;

手动运行此命令时,它似乎工作正常。然而,supervisord似乎以某种方式阻止了它正常运行,我不知道是怎么回事。worker.php执行良好,但在该配置中,它的报告被抑制。因此,它当然不会添加时间戳。

有人对此有足够的了解来指导如何实现为工人的产出加时间戳的目标吗?

您可以编写一个专用的包装器脚本,在调用您的工作代码之前,将过滤器附加到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上测试过)。

前面的答案(来自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计算和替换的,因此所有行都具有相同的日志时间戳

编辑:我想我会把这个留在这里。确切地说,这种方法不起作用,因为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"

(免责声明:鉴于我对这个答案还不存在感到轻微的惊讶,得知这是一种糟糕的做事方式,我并不感到惊讶)

最新更新