├── .gitignore ├── web └── ErrorHandler.php ├── WithPayload.php ├── console └── ErrorHandler.php ├── psalm.xml ├── composer.json ├── log └── Target.php ├── LICENSE.md ├── Rollbar.php ├── ErrorHandlerTrait.php └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | vendor/ 3 | composer.lock 4 | -------------------------------------------------------------------------------- /web/ErrorHandler.php: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "baibaratsky/yii2-rollbar", 3 | "description": "Rollbar for Yii2", 4 | "type": "yii2-extension", 5 | "keywords": ["rollbar", "ratchetio", "ratchet.io", "yii", "yii2", "log", "error", "exception", "debug", "monitoring"], 6 | "license": "BSD-3-Clause", 7 | "homepage": "http://github.com/baibaratsky/yii2-rollbar", 8 | "authors": [ 9 | { 10 | "name": "Andrei Baibaratsky", 11 | "email": "andrei@baibaratsky.com" 12 | } 13 | ], 14 | "require": { 15 | "php": ">=8.0", 16 | "yiisoft/yii2": "^2.0", 17 | "rollbar/rollbar": "^3.1 || ^4.0.2" 18 | }, 19 | "minimum-stability": "dev", 20 | "prefer-stable": true, 21 | "autoload": { 22 | "psr-4": { 23 | "baibaratsky\\yii\\rollbar\\": "" 24 | } 25 | }, 26 | "config": { 27 | "allow-plugins": { 28 | "yiisoft/yii2-composer": true 29 | } 30 | }, 31 | "require-dev": { 32 | "vimeo/psalm": "^5.1" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /log/Target.php: -------------------------------------------------------------------------------- 1 | requestId = uniqid(gethostname(), true); 19 | parent::init(); 20 | } 21 | 22 | /** 23 | * @return void 24 | */ 25 | public function export() 26 | { 27 | foreach ($this->messages as $message) { 28 | $levelName = self::getLevelName($message[1]); 29 | Rollbar::log(Level::$levelName(), $message[0], [ 30 | 'category' => $message[2], 31 | 'request_id' => $this->requestId, 32 | 'timestamp' => (int)$message[3], 33 | ]); 34 | } 35 | } 36 | 37 | protected static function getLevelName($level): string 38 | { 39 | if (in_array($level, 40 | [Logger::LEVEL_PROFILE, Logger::LEVEL_PROFILE_BEGIN, Logger::LEVEL_PROFILE_END, Logger::LEVEL_TRACE])) { 41 | return 'debug'; 42 | } 43 | 44 | return Logger::getLevelName($level); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Rollbar for Yii2 is free software. It is released under 2 | the terms of the following BSD License. 3 | 4 | Copyright © 2015 by Andrei Baibaratsky. All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions 8 | are met: 9 | 10 | * Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in 14 | the documentation and/or other materials provided with the 15 | distribution. 16 | * The names of the copyright holders and contributors may not be 17 | used to endorse or promote products derived from this software 18 | without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 | COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 30 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | POSSIBILITY OF SUCH DAMAGE. 32 | -------------------------------------------------------------------------------- /Rollbar.php: -------------------------------------------------------------------------------- 1 | ['range', 'of', 'values], ...] 32 | */ 33 | public $ignoreExceptions = [ 34 | ['yii\web\HttpException', 'statusCode' => [404]], 35 | ]; 36 | 37 | public function init() 38 | { 39 | BaseRollbar::init([ 40 | 'enabled' => $this->enabled, 41 | 'access_token' => $this->accessToken, 42 | 'base_api_url' => $this->baseApiUrl, 43 | 'batch_size' => $this->batchSize, 44 | 'batched' => $this->batched, 45 | 'branch' => $this->branch, 46 | 'code_version' => $this->codeVersion, 47 | 'environment' => $this->environment, 48 | 'host' => $this->host, 49 | 'included_errno' => $this->includedErrno, 50 | 'logger' => $this->logger, 51 | 'person_fn' => $this->personFn, 52 | 'root' => !empty($this->root) ? Yii::getAlias($this->root) : null, 53 | 'scrub_fields' => $this->scrubFields, 54 | 'timeout' => $this->timeout, 55 | 'proxy' => $this->proxy, 56 | 'enable_utf8_sanitization' => $this->enableUtf8Sanitization, 57 | ], false, false, false); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /ErrorHandlerTrait.php: -------------------------------------------------------------------------------- 1 | 'bar', 21 | * 'xyz' => getSomeData(), 22 | * ]; 23 | * } 24 | */ 25 | public $payloadDataCallback; 26 | 27 | /** 28 | * @return void 29 | */ 30 | public function logException($exception) 31 | { 32 | $this->logExceptionRollbar($exception); 33 | 34 | parent::logException($exception); 35 | } 36 | 37 | private function getPayloadData($exception) 38 | { 39 | $payloadData = $this->payloadCallback(); 40 | 41 | if ($exception instanceof WithPayload) { 42 | $exceptionData = $exception->rollbarPayload(); 43 | if (is_array($exceptionData)) { 44 | if (is_null($payloadData)) { 45 | $payloadData = $exceptionData; 46 | } else { 47 | $payloadData = ArrayHelper::merge($exceptionData, $payloadData); 48 | } 49 | } elseif (!is_null($exceptionData)) { 50 | throw new \Exception(get_class($exception) . '::rollbarPayload() returns an incorrect result'); 51 | } 52 | } 53 | 54 | return $payloadData; 55 | } 56 | 57 | private function payloadCallback(): array|null 58 | { 59 | if (!isset($this->payloadDataCallback)) { 60 | return null; 61 | } 62 | 63 | if (!is_callable($this->payloadDataCallback)) { 64 | throw new \Exception('Incorrect callback provided'); 65 | } 66 | 67 | $payloadData = call_user_func($this->payloadDataCallback, $this); 68 | 69 | if (!is_array($payloadData) && !is_null($payloadData)) { 70 | throw new \Exception('Callback returns an incorrect result'); 71 | } 72 | 73 | return $payloadData; 74 | } 75 | 76 | /** 77 | * @return void 78 | */ 79 | protected function logExceptionRollbar($exception) 80 | { 81 | foreach (Yii::$app->get($this->rollbarComponentName)->ignoreExceptions as $ignoreRecord) { 82 | if ($exception instanceof $ignoreRecord[0]) { 83 | $ignoreException = true; 84 | foreach (array_slice($ignoreRecord, 1) as $property => $range) { 85 | if (!in_array($exception->$property, $range)) { 86 | $ignoreException = false; 87 | break; 88 | } 89 | } 90 | if ($ignoreException) { 91 | return; 92 | } 93 | } 94 | } 95 | // Check if an error coming from handleError() should be ignored. 96 | if ($exception instanceof ErrorException && Rollbar::logger()->shouldIgnoreError($exception->getCode())) { 97 | return; 98 | } 99 | 100 | $extra = $this->getPayloadData($exception); 101 | if ($extra === null) { 102 | $extra = []; 103 | } 104 | $level = $this->isFatal($exception) ? Level::CRITICAL : Level::ERROR; 105 | 106 | Rollbar::log($level, $exception, $extra, true); 107 | } 108 | 109 | protected function isFatal($exception): bool 110 | { 111 | return $exception instanceof \Error 112 | || ($exception instanceof ErrorException 113 | && ErrorException::isFatalError(['type' => $exception->getSeverity()])); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Rollbar for Yii2 2 | ================ 3 | [![Packagist](https://img.shields.io/packagist/l/baibaratsky/yii2-rollbar.svg)](https://github.com/baibaratsky/yii2-rollbar/blob/master/LICENSE.md) 4 | [![Dependency Status](https://www.versioneye.com/user/projects/55ba6130653762001a00189a/badge.svg?style=flat)](https://www.versioneye.com/user/projects/55ba6130653762001a00189a) 5 | [![Packagist](https://img.shields.io/packagist/v/baibaratsky/yii2-rollbar.svg)](https://packagist.org/packages/baibaratsky/yii2-rollbar) 6 | [![Packagist](https://img.shields.io/packagist/dt/baibaratsky/yii2-rollbar.svg)](https://packagist.org/packages/baibaratsky/yii2-rollbar) 7 | 8 | This extension is the way to integrate [Rollbar](http://rollbar.com/) service with your Yii2 application. 9 | For Yii 1.* use [yii-rollbar](https://github.com/baibaratsky/yii-rollbar). 10 | 11 | 12 | Installation 13 | ------------ 14 | The preferred way to install this extension is through [composer](http://getcomposer.org/download/). 15 | 16 | To install, either run 17 | ``` 18 | $ php composer.phar require baibaratsky/yii2-rollbar:1.9.* 19 | ``` 20 | or add 21 | ``` 22 | "baibaratsky/yii2-rollbar": "1.9.*" 23 | ``` 24 | to the `require` section of your `composer.json` file. 25 | 26 | If you want to use it with **Yii prior to 2.0.13**, you need yii2-rollbar of the version `1.6.*`. 27 | 28 | Usage 29 | ----- 30 | 0. Add the component configuration in your *global* `main.php` config file: 31 | ```php 32 | 'bootstrap' => ['rollbar'], 33 | 'components' => [ 34 | 'rollbar' => [ 35 | 'class' => 'baibaratsky\yii\rollbar\Rollbar', 36 | 'accessToken' => 'POST_SERVER_ITEM_ACCESS_TOKEN', 37 | 38 | // You can specify exceptions to be ignored by yii2-rollbar: 39 | // 'ignoreExceptions' => [ 40 | // ['yii\web\HttpException', 'statusCode' => [400, 404]], 41 | // ['yii\web\HttpException', 'statusCode' => [403], 'message' => ['This action is forbidden']], 42 | // ], 43 | ], 44 | ], 45 | ``` 46 | 47 | 0. Add the *web* error handler configuration in your *web* config file: 48 | ```php 49 | 'components' => [ 50 | 'errorHandler' => [ 51 | 'class' => 'baibaratsky\yii\rollbar\web\ErrorHandler', 52 | 53 | // You can include additional data in a payload: 54 | // 'payloadDataCallback' => function (\baibaratsky\yii\rollbar\web\ErrorHandler $errorHandler) { 55 | // return [ 56 | // 'exceptionCode' => $errorHandler->exception->getCode(), 57 | // 'rawRequestBody' => Yii::$app->request->getRawBody(), 58 | // ]; 59 | // }, 60 | ], 61 | ], 62 | ``` 63 | 64 | 0. Add the *console* error handler configuration in your *console* config file: 65 | ```php 66 | 'components' => [ 67 | 'errorHandler' => [ 68 | 'class' => 'baibaratsky\yii\rollbar\console\ErrorHandler', 69 | ], 70 | ], 71 | ``` 72 | 73 | 74 | Payload from your exceptions 75 | ---------------------------- 76 | If you want your exceptions to send some additional data to Rollbar, 77 | it is possible by implementing the `WithPayload` interface. 78 | ```php 79 | use baibaratsky\yii\rollbar\WithPayload; 80 | 81 | class SomeException extends \Exception implements WithPayload 82 | { 83 | public function rollbarPayload() 84 | { 85 | return ['foo' => 'bar']; 86 | } 87 | } 88 | ``` 89 | 90 | 91 | Log Target 92 | ---------- 93 | You may want to collect your logs produced by `Yii::error()`, `Yii::info()`, etc. in Rollbar. 94 | Put the following code in your config: 95 | ```php 96 | 'log' => [ 97 | 'targets' => [ 98 | [ 99 | 'class' => 'baibaratsky\yii\rollbar\log\Target', 100 | 'levels' => ['error', 'warning', 'info'], // Log levels you want to appear in Rollbar 101 | 102 | // It is highly recommended that you specify certain categories. 103 | // Otherwise, the exceptions and errors handled by the error handlers will be duplicated. 104 | 'categories' => ['application'], 105 | ], 106 | ], 107 | ], 108 | ``` 109 | 110 | The log target also appends `category` and `request_id` parameters to the log messages. 111 | `request_id` is useful if you want to have a *yii2-debug*-like grouping. 112 | --------------------------------------------------------------------------------