[译] 在PHP中使用Sentry

Sentry 是一个错误记录和聚合的平台。Sentry除了提供了PaaS平台供直接使用,更开放了私有部署方式,关于如何使用Docker快速搭建私有Sentry,可以阅读我上篇文章[译] 使用Docker安装Sentry(一个错误记录和聚合平台)

在PHP中使用Sentry非常简单。在安装库之后,您可以直接与客户端进行交互并开始提交数据。

安装库

Sentry的PHP SDK支持PHP 5.3及更高版本。 它可作为BSD许可的开放源代码库提供。

有多种方法可以为Sentry安装PHP集成。 推荐的方法是使用Composer:

composer require "sentry/sentry"
复制代码

或者,您可以手动安装它:

  1. 下载并提取最新的sentry-php档案到您的PHP项目。
  2. 在您的应用程序中需要自动加载器:
require_once '/path/to/Raven/library/Raven/Autoloader.php';
Raven_Autoloader::register();
复制代码

基础

最重要的部分是创建Sentry客户端。创建一次,并从您希望与Sentry交互的任何位置引用它:

$sentryClient = new Raven_Client('https://<key>:<secret>@sentry.io/<project>');
复制代码

捕获错误

Sentry包含用于报告任何未捕获的异常或PHP错误的基本功能。这是通过错误处理程序完成的,并为每个PHP的内置报告提供适当的钩子:

$error_handler = new Raven_ErrorHandler($sentryClient);
$error_handler->registerExceptionHandler();
$error_handler->registerErrorHandler();
$error_handler->registerShutdownFunction();
复制代码

在Raven_Client实例上调用install()将自动注册这些处理程序。

报告Exceptions

如果您想手动报告异常,可以使用captureException函数。

// 基本报告
$sentryClient->captureException($ex);

// 利用Exception提供一些额外的数据
$sentryClient->captureException($ex, array(
    'extra' => array(
        'php_version' => phpversion()
    ),
));
复制代码

报告其他错误

有时候你没有一个实际的异常对象,但是发生了一些不好的事情,你想报告它。这是CaptureMessage的用处。它会接收一条消息并将其报告给sentry。

// 捕获消息
$sentryClient->captureMessage('my log message');
复制代码

请注意,captureMessage具有与captureException稍有不同的API,以支持参数化格式:

$sentryClient->captureMessage('my %s message', array('log'), array(
    'extra' => array(
        'foo' => 'bar',
    ),
));
复制代码

可选属性

通过调用captureException或captureMessage可以提供额外的数据:

$sentryClient->captureException($ex, array(
    'attr' => 'value',
));
复制代码

额外

此事件的其他上下文。必须是一个映射。孩子可以是任何原生的JSON类型。

指纹

用于分组此事件的指纹。

array(
    'fingerprint' => ['{{ default }}', 'other value']
)
复制代码

等级

事件的级别。默认为错误。 array( 'level' => 'warning' ) sentry支持一下级别:

  • debug (the least serious)
  • info
  • warning
  • error
  • fatal (the most serious)

日志

事件的记录器名称。 array( 'logger' => 'default' )

标签

与此事件相关的标签。必须是字符串的映射

array(
    'tags' => array('key' => 'value')
)
复制代码

用户

array(
    'user' => array(
        'id' => 42,
        'email' => 'clever-girl'
    )
)
复制代码

取回事件ID

事件ID是刚刚发送的事件的全局唯一ID。此事件ID可用于从Sentry中查找确切的事件。 这通常用于向用户显示并向客户服务报告错误。 $sentryClient->getLastEventID();

用户反馈

要启用用户对崩溃报告的反馈,您需要创建一个能够识别上次事件ID的错误处理程序。

<?php

$sentry = new \Raven_Client(https://<key>:<secret>@sentry.io/<project>);

public class App {
    function error500($exc) {
        $event_id = $sentry->captureException($exc);

        return $this->render('500.html', array(
            'sentry_event_id' => $event_id,
        ), 500);
    }
}
复制代码

然后在您的模板中,您可以加载反馈小部件:

<!-- Sentry JS SDK 2.1.+ required -->
<script src="https://cdn.ravenjs.com/2.3.0/raven.min.js"></script>

{% if sentry_event_id %}
  <script>
  Raven.showReportDialog({
    eventId: '{{ sentry_event_id }}',

    // use the public DSN (dont include your secret!)
    dsn: 'https://<key>@sentry.io/<project>'
  });
  </script>
{% endif %}
复制代码

有关此功能的更多详细信息,请参阅用户反馈指南

处理故障

SDK会尽量减少故障发生,当它们发生时总会尽量避免将它们冒泡给您的应用程序。如果您确实想知道事件何时无法记录,可以使用getLastError帮助器:

if ($sentryClient->getLastError() !== null) {
    echo "Something went very, very wrong";
    // $sentryClient->getLastError() contains the error that occurred
} else {
    // Give the user feedback
    echo "Sorry, there was an error!";
    echo "Your reference ID is " . $event_id;
}
复制代码

面包屑

Sentry支持捕获面包屑 - 事件发生前发生的事件。

$sentryClient->breadcrumbs->record(array(
    'message' => 'Authenticating user as ' . $username,
    'category' => 'auth',
    'level' => 'info',
));
复制代码

过滤错误

常见的是,您可能想要阻止某些区域的自动捕获。 理想情况下,您只需避免在这种情况下向Sentry发出呼叫,但这往往说起来容易做起来难。 相反,您可以提供SDK在发送任何数据之前调用的函数,从而允许您对数据进行变异,并防止将其发送到服务器。

$sentryClient->setSendCallback(function($data) {
    $ignore_types = array('Symfony\Component\HttpKernel\Exception\NotFoundHttpException');

    if (isset($data['exception']) && in_array($data['exception']['values'][0]['type'], $ignore_types))
    {
        return false;
    }
});
复制代码

错误控制操作符

在PHP中,使用抑制运算符来避免冒泡处理错误非常常见:

$my_file = @file('non_existent_file');

在这些情况下,Sentry将永远不会捕获错误。如果您希望在该阶段捕获它,则需要手动呼叫到PHP客户端:

$my_file = @file('non_existent_file');
if (!$my_file) {
    // ...
    $sentryClient->captureLastError();
}
复制代码

测试你的连接

PHP客户端包含一个简单的帮助程序脚本,用于测试您与Sentry主服务器的连接和凭据:

$ bin/sentry test https://<key>:<secret>@sentry.io/<project>
Client configuration:
-> server: [https://sentry.io]
-> project: ___PROJECT_ID___
-> public_key: <key>
-> secret_key: <secret>

Sending a test event:
-> event ID: f1765c9aed4f4ceebe5a93df9eb2d34f

Done!复制代码