cloud-solutions/zend-sentry

此软件包已被放弃,不再维护。作者建议使用 sentry/sdk 软件包。

一个允许您将日志记录到 Sentry.io 服务的 Zend Framework 3 模块。

3.7.0 2018-10-28 23:13 UTC

README

随着新 Sentry SDK 的推出,直接与任何项目集成变得更加容易。此软件包创建了很多样板代码,其中大部分代码现在不再需要。对于 JS 集成,最好是使用 yarn 或 npm 安装 JS SDK,这样您也可以正确地打包和自动化这些内容。

一个允许您将异常、错误或您想要记录的内容自动记录到 Sentry.io 服务的 Zend Framework 3 模块。

Scrutinizer Code Quality Build Status

ZendSentry 在 MIT 许可下发布。

ZendSentry 的当前版本为 ZF3 的 3.7.0。它支持 Zend Framework >= 3.0。对于其他版本,请参阅 1.* 系列和 2.* 系列的标签。注意!我们不再支持旧分支。

最近更改

  • 3.7.0: 添加配置使用 Ravenjs 版本的功能,升级 Ravenjs 到 3.27.0
  • 3.6.0: 添加静态设置器以注入 CSP nonce(临时解决方案)
  • 3.5.0: 添加对新 Sentry DSN 的支持,弃用旧 DSN 以供后续删除
  • 3.4.0: 添加关闭使用 raven-js CDN 的可能性
  • 3.3.0: 添加将配置选项传递给 ravenjs 的可能性

介绍

什么是 Sentry?

Sentry 是一个在线服务,您可以将其中的任何内容(包括异常和错误)记录到其中。Sentry 会实时创建漂亮的报告,并为您聚合记录的数据。

什么是 ZendSentry?

它是一个模块,在您的 Zend Framework 3 应用程序和 Sentry.io 服务之间建立桥梁。它设置极其简单,开箱即用功能丰富。

功能和能力

  • 自动将未捕获的 PHP 异常记录到 Sentry。
  • 自动将 PHP 错误记录到 Sentry。
  • 自动将未捕获的 JavaScript 错误记录到 Sentry。
  • 通过触发事件监听器捕获异常到 Sentry。
  • 通过触发事件监听器将您想要记录的任何内容记录到 Sentry。
  • HTTP 以及 CLI 的 ZF 异常策略(自动选择)。
  • 日志操作返回 Sentry 事件 ID。
  • Raven 已注册为服务。
  • 覆盖 Raven 配置默认值。
  • 将配置选项传递给 ravenjs。
  • 配置错误信息。
  • 向内联脚本渲染注入 Content-Security-Policynonce。这使得您可以创建一个不包含unsafe-inline` 作为脚本源头的 CSP。

安装

此模块可在 Packagist 上找到。在您的项目 composer.json 中使用:

{   
    "require": {
        "cloud-solutions/zend-sentry": "3.7.0"
}

运行 php composer.phar update 以将其下载到您的 vendor 文件夹并设置自动加载。

现在将 zend-sentry.local.php.dist 复制到 yourapp/config/autoload/zend-sentry.local.php 并添加您的 Sentry API 密钥。然后将 zend-sentry.global.php.dist 复制到同一位置,也删除 .dist。如有必要,调整设置。

ZendSentry 添加到您的 application.config.php 中的模块数组中,最好是第一个模块。

就是这样。您不需要做任何事情,一切都在这个阶段正常工作,试试看。祝您记录愉快!

基本自动使用

同样,您不需要编写任何代码就能使其工作。默认设置将确保 Sentry 被注册为错误和异常处理器,尝试触发错误或抛出一些异常。您应该会立即在 Sentry 控制台中看到它们。ZendSentry 还打包了自己的 ExceptionStrategies,以确保 ZF 本来可以拦截的异常被记录。

手动使用

此外,该模块在应用程序级别注册了一个日志事件监听器。因此,您可以从应用程序的任何地方触发自定义日志事件。

在控制器中,您可以这样做:

$this->getEventManager()->trigger('log', $this, array(
    'priority' => \Zend\Log\Logger::INFO, 
    'message' => 'I am a message and I have been logged'
));

或者,您可以存储返回的 Sentry event_id 以供处理

$eventID = $this->getEventManager()->trigger('log', $this, array(
    'priority' => \Zend\Log\Logger::INFO,
    'message' => 'I am a message and I have been logged'
));

现在您可以告诉您的用户或 API 消费者该 ID,以便他们可以引用它,例如在请求支持时。

请确保将 "log" 作为第一个参数,将 $this 自定义上下文字符串作为第二个参数传递。保持一致性,因为 Sentry 将使用此信息对您的日志条目进行分组。作为第三个参数,您想要传递一个包含优先级键和消息键的数组。最好使用由 Zend Framework 提供的优先级。它们将被映射到 Sentry 的自己的优先级。

除了未捕获的异常和错误会自动记录之外,您还可以通过直接使用相应的监听器手动记录捕获或未捕获的异常。

try {
    throw new Exception('throw and catch');
} catch (Exception $exception) {
    $result = $this->getEventManager()->trigger('logException', $this, array('exception' => $exception));

    //get Sentry event_id by retrieving it from the EventManager ResultCollection
    $eventID = $result->last();
}

使用标签

您还可以向 Sentry 传递自己的标签。该服务将自动为这些标签创建过滤和排序。当使用 log 事件时,您可以可选地按如下方式传递标签:

$this->getEventManager()->trigger('log', $this, array(
    'priority' => \Zend\Log\Logger::INFO,
    'message' => 'I am a message with a language tag',
    'tags' => array('language' => 'en'),
    'extra' => array('email' => 'test@test.com'),
));

如果手动使用 logException 事件,您也可以传递标签

try {
    throw new Exception('throw and catch with tags');
} catch (Exception $exception) {
    $this->getEventManager()->trigger('logException', $this, array('exception' => $exception, 'tags' => array('language' => 'fr')));
}

注意! 每个标签都需要一个键和一个值。

请参阅以下如何使用标签自动记录异常的说明。

Raven 作为服务

该模块将 Raven_Client 注册为应用程序范围内的服务。通常您不需要直接访问它,因为触发事件监听器会让您的代码更干净。直接使用 Raven 有助于添加用户上下文的例子之一是在引导过程中:

if ($authenticationService->hasIdentity()) {
    $ravenClient = $this->serviceManager->get('raven');
    $ravenClient->user_context($authenticationService->getIdentity()->userID);
}

如果您想添加一些将与每个自动条目一起发送的标签到上下文,您也可以直接使用 Raven。例如,您可能想在 AbstractActionController::preDispatch() 中这样做:

$serviceManager = $mvcEvent->getApplication()->getServiceManager();
if ($serviceManager->has('raven')) {
    $ravenClient = $serviceManager->get('raven');
    $ravenClient->tags_context(
        [
            'locale'  => $this->translator()->getLocale(),
        ]
    );
}

注入 CSP nonce(注意!这是一个临时解决方案)

如果您已经在您的应用中实现了内容安全策略(Content Security Policy),那么您可能正在使用nonce来处理动态内联JavaScript。如果是这样,现在您可以将其nonce注入到ZendSentry中

ZendSentry::setCSPNonce(ContentSecurityPolicy::getNonce());

...其中ContentSecurityPolicy是您实现该HTTP头的方式。

如果您注入了nonce,ZendSentry会将其作为一个属性添加到Raven加载脚本中。示例

<script type="text/javascript" nonce="qlQa7LCu2ZLoVZzpn5s9OJNq7QE=">
    //<![CDATA[
    if (typeof Raven !== 'undefined') Raven.config('https://yourpublickey@sentry.io/5374', []).install()
    //]]>
</script>

请注意,我们将这视为一种临时解决方案。对于ZendSentry来说,最好定义自己的CSP头。目前,Zend Framework没有正确处理多个CSP头(请参阅zend-http中的这个问题)。

配置选项

仅作记录,这里是实际的全球配置选项副本

/**
 * Turn ZendSentry off or on as a whole package
 */
'use-module' => true,

/**
 * Attach a generic logger event listener so you can log custom messages from anywhere in your app
 */
'attach-log-listener' => true,

/**
 * Register the Sentry logger as PHP error handler
 */
'handle-errors' => true,

/**
 * Should the previously registered error handler be called as well?
 */
'call-existing-error-handler' => true,

/**
 * Register Sentry as shutdown error handler
 */
'handle-shutdown-errors' => true,

/**
 * Register the Sentry logger as PHP exception handler
 */
'handle-exceptions' => true,

/**
 * Should the previously registered exception handler be called as well
 */
'call-existing-exception-handler' => true,

/**
 * Which errors should be reported to sentry (bitmask), e. g. E_ALL ^ E_DEPRECATED
 * Defaults to -1 to report all possible errors (equivalent to E_ALL in >= PHP 5.4)
 */
'error-reporting' => -1,

/**
 * Should exceptions be displayed on the screen?
 */
'display-exceptions' => false,

/**
 * If Exceptions are displayed on screen, this is the default message
 */
'default-exception-message' => 'Oh no. Something went wrong, but we have been notified. If you are testing, tell us your eventID: %s',

/**
 * If Exceptions are displayed on screen, this is the default message in php cli mode
 */
'default-exception-console-message' => "Oh no. Something went wrong, but we have been notified.\n",

/**
 * Should Sentry also log javascript errors?
 */
'handle-javascript-errors' => true,

/**
 * Should ZendSentry load raven-js via CDN?
 * If you set this to false you'll need to make sure to load raven-js some other way.
 */
'use-ravenjs-cdn' => true,

/**
 * Change the raven-js version loaded via CDN if you need to downgrade or we're lagging behind with updating.
 * No BC breaks, ZendSentry will set the version if your config is missing the key.
 */
'ravenjs-version' => '3.27.0',

/**
 * Alternatively, if not using CDN, you can specify a path or url to raven-js.
 * Set to empty to disable but make sure to load raven-js some other way.
 */
'ravenjs-source' => '/js/raven.min.js',

/**
 * Set raven config options for the getsentry/sentry-php package here.
 * Raven has sensible defaults set in Raven_Client, if you need to override them, this is where you can do it.
 */
'raven-config' => array(),

/**
 * Set ravenjs config options for the getsentry/raven-js package here.
 * This will be json encoded and passed to raven-js when doing Raven.install().
 */
'ravenjs-config' => array(),

尝试一下

一些想法,如何从控制器或视图尝试不同的功能

// Test logging of PHP errors
// trigger_error('can I trigger an error from a controller');

// Test logging of PHP exceptions
// throw new \Exception('Some exception gets logged.');

// Throw a javascript error and see it logged (add to view or layout)
// $headScript->appendScript("throw new Error('A javascript error should be logged.');");