首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >给supervisord管理的程序的日志加上时间戳

问给supervisord管理的程序的日志加上时间戳
EN

Stack Overflow用户
提问于 2013-07-23 09:32:04
回答 3查看 4K关注 0票数 12

我正在使用supervisord来管理一个需要在后台运行的php程序。该程序将事件记录到文件worker_log中。在我使用的supervisord.conf中配置它非常简单:

代码语言:javascript
复制
stderr_logfile=/var/log/supervisord/worker_log;

但是,我希望正在写入日志的事件能够为它们自己加时间戳。我不能控制php程序,所以不能修改它的日志。我想我要做的是注释掉上面的日志配置,并通过supervisor的命令配置中的命令行管道来装饰程序:

代码语言:javascript
复制
command=php /www/myapp/worker.php 2>&1 | sed "s/^/`date` /" > /var/log/supervisord/worker_log;

当手动运行此命令时,它似乎工作得很好。然而,supervisord似乎以某种方式阻止了它正常工作,我无法说出是如何实现的。worker.php执行得很好,但是在这种配置中,它的报告被抑制了。正因为如此,它当然不会添加时间戳。

有没有人对此有足够的了解,以便为如何实现为工人的输出添加时间戳的目标提供指导?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-07-25 10:29:58

您可以编写一个专用的包装器脚本,在调用worker代码之前将一个过滤器附加到stderr:

代码语言:javascript
复制
// 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上测试)。

票数 8
EN

Stack Overflow用户

发布于 2013-07-27 22:24:09

前面的答案(来自Jack)是正确的,因为您需要另一层代码来为每行添加时间戳。perl中的这一行代码将实现相同的结果:

代码语言:javascript
复制
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计算并替换的,因此所有行都将具有相同的日志时间戳

票数 4
EN

Stack Overflow用户

发布于 2020-09-12 11:32:46

编辑:我想我会把它留在这里。这种方法并不完全有效,因为sed命令只是永久地使用它的启动date输出,因此时间戳是不正确的。

实现这一点的另一种方法是将原始命令放在bash -c "command here"的引号中,这与您最初的尝试非常接近。

代码语言:javascript
复制
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"

(免责声明:考虑到我对这个答案不存在的轻微惊讶,如果我知道这是一种糟糕的做事方式,我也不会感到惊讶)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17800133

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档