实战Sentry

不管你用什么编程语言,都会面临如何处理错误日志的问题。很多程序员对错误日志放任自流,直到出现故障了才追悔莫及,如果问我怎么办,我会推荐Sentry

Sentry 是一个错误记录和聚合的平台,只要看看它漂亮的界面就会喜欢上它:

sentry

sentry

关于如何安装 Sentry,官方文档里已经给出了详细的说明,建议大家仔细阅读,一般通过Virtualenv来安装 Sentry,具体可以参考:学习搭建Python环境

提醒:我在安装 7.5 的时候,测试有循环重定向,如果你也是可以安装 7.4:

pip install sentry==7.4.3

安装完毕后,假设我们要监控 PHP 错误日志,那么通常是在我们的业务代码里嵌入官方的PHP SDK,不过这样肯定会影响到性能,好在我们可以通过错误日志曲线救国,只要定期扫描错误日志,把新生成的数据发送给 Sentry 就好了。

如何才能发现新生成的数据呢?需要记录扫描到了哪个位置,可以通过 Logcheck 中提供的 logtail 或者 logtail2 来实现这个功能,至于它俩的区别,可以参见 man 文档,简单点儿说,如果日志被 rotate 的话,logtail 可能会丢失旧日志中的数据,而 logtail2 不会。

<?php

require_once __DIR__ . '/raven-php/lib/Raven/Autoloader.php';

Raven_Autoloader::register();

$dsn = 'http://your/dsn';

$options = array(
    'tags' => array(
        'php_version' => phpversion(),
    ),
    'trace' => false,
);

$pattern_content = '^\[([^]]+)] PHP ([^:]+):\s+(.+)';

$parrern_level = implode('|', array(
    'debug',
    'info',
    'warning',
    'error',
    'fatal',
));

$client = new Raven_Client($dsn, $options);

while (($line = fgets(STDIN)) !== false) {
    if (!preg_match("/{$pattern_content}/", $line, $match)) {
        continue;
    }

    list($line, $timestamp, $level, $message) = $match;

    $timestamp = gmdate('Y-m-d\TH:i:s\Z', strtotime($timestamp));

    preg_match("/{$parrern_level}/i", $level, $match);

    $level = isset($match[0]) ? $match[0] : 'error';

    $client->captureMessage($message, array(), array(
        'timestamp' => $timestamp,
        'level' => $level,
    ));
}

?>

做好了以上这些准备工作,剩下的只要通过管道把新数据传递给 PHP 脚本即可:

shell> logtail2 -f /path/to/php/error/log | php /path/to/script

建议通过 crontab 定时运行此命令,但是需要注意用 flock 保护一下,以免拥堵。

参考链接:在生产环境部署sentry进行错误收集和提醒

发表评论

Close Menu