├── README.md ├── composer.json └── src ├── Facades └── Rollbar.php ├── RollbarLogHandler.php └── RollbarServiceProvider.php /README.md: -------------------------------------------------------------------------------- 1 | Laravel Rollbar 2 | =============== 3 | 4 | [![Build Status](http://img.shields.io/travis/jenssegers/laravel-rollbar.svg)](https://travis-ci.org/jenssegers/laravel-rollbar) [![Coverage Status](http://img.shields.io/coveralls/jenssegers/laravel-rollbar.svg)](https://coveralls.io/r/jenssegers/laravel-rollbar) 5 | 6 | Rollbar error monitoring integration for Laravel projects. This library adds a listener to Laravel's logging component. Laravel's session information will be sent in to Rollbar, as well as some other helpful information such as 'environment', 'server', and 'session'. 7 | 8 | ![rollbar](https://d37gvrvc0wt4s1.cloudfront.net/static/img/features-dashboard1.png?ts=1361907905) 9 | 10 | Installation 11 | ------------ 12 | 13 | Install using composer: 14 | 15 | ``` 16 | composer require jenssegers/rollbar 17 | ``` 18 | 19 | Add the service provider to the `'providers'` array in `config/app.php`: 20 | 21 | ```php 22 | Jenssegers\Rollbar\RollbarServiceProvider::class, 23 | ``` 24 | 25 | If you only want to enable Rollbar reporting for certain environments you can conditionally load the service provider in your `AppServiceProvider`: 26 | 27 | ```php 28 | public function register() 29 | { 30 | if ($this->app->environment('production')) { 31 | $this->app->register(\Jenssegers\Rollbar\RollbarServiceProvider::class); 32 | } 33 | } 34 | ``` 35 | 36 | Configuration 37 | ------------- 38 | 39 | This package supports configuration through the services configuration file located in `config/services.php`. All configuration variables will be directly passed to Rollbar: 40 | 41 | ```php 42 | 'rollbar' => [ 43 | 'access_token' => env('ROLLBAR_TOKEN'), 44 | 'level' => env('ROLLBAR_LEVEL'), 45 | ], 46 | ``` 47 | 48 | The level variable defines the minimum log level at which log messages are sent to Rollbar. For development you could set this either to `debug` to send all log messages, or to `none` to sent no messages at all. For production you could set this to `error` so that all info and debug messages are ignored. 49 | 50 | Usage 51 | ----- 52 | 53 | To automatically monitor exceptions, simply use the `Log` facade in your error handler in `app/Exceptions/Handler.php`: 54 | 55 | ```php 56 | public function report(Exception $exception) 57 | { 58 | \Log::error($exception); //rollbar 59 | parent::report($exception); 60 | } 61 | ``` 62 | 63 | 64 | For Laravel 4 installations, this is located in `app/start/global.php`: 65 | 66 | ```php 67 | App::error(function(Exception $exception, $code) 68 | { 69 | Log::error($exception); 70 | }); 71 | ``` 72 | 73 | Your other log messages will also be sent to Rollbar: 74 | 75 | ```php 76 | \Log::debug('Here is some debug information'); 77 | ``` 78 | 79 | *NOTE*: Fatal exceptions will always be sent to Rollbar. 80 | 81 | ### Context informaton 82 | 83 | You can pass user information as context like this: 84 | 85 | ```php 86 | \Log::error('Something went wrong', [ 87 | 'person' => ['id' => 123, 'username' => 'John Doe', 'email' => 'john@doe.com'] 88 | ]); 89 | ``` 90 | 91 | Or pass some extra information: 92 | 93 | ```php 94 | \Log::warning('Something went wrong', [ 95 | 'download_size' => 3432425235 96 | ]); 97 | ``` 98 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jenssegers/rollbar", 3 | "description": "Rollbar error monitoring integration for Laravel projects", 4 | "keywords": ["laravel", "rollbar", "monitoring", "error", "logging"], 5 | "homepage": "https://github.com/jenssegers/laravel-rollbar", 6 | "license": "MIT", 7 | "authors": [ 8 | { 9 | "name": "Jens Segers", 10 | "homepage": "https://jenssegers.com" 11 | } 12 | ], 13 | "require": { 14 | "php": ">=5.4", 15 | "illuminate/support": "^4.0|^5.0", 16 | "rollbar/rollbar": "~0.15" 17 | }, 18 | "require-dev": { 19 | "orchestra/testbench": "^3.0", 20 | "mockery/mockery": "^0.9", 21 | "satooshi/php-coveralls": "^1.0", 22 | "phpunit/phpunit": "~4.0|~5.0" 23 | }, 24 | "autoload": { 25 | "psr-4": { 26 | "Jenssegers\\Rollbar\\": "src/" 27 | } 28 | }, 29 | "extra": { 30 | "laravel": { 31 | "providers": [ 32 | "Jenssegers\\Rollbar\\RollbarServiceProvider" 33 | ], 34 | "aliases": { 35 | "Rollbar": "Jenssegers\\Rollbar\\Facades\\Rollbar" 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Facades/Rollbar.php: -------------------------------------------------------------------------------- 1 | Monolog::DEBUG, 40 | 'info' => Monolog::INFO, 41 | 'notice' => Monolog::NOTICE, 42 | 'warning' => Monolog::WARNING, 43 | 'error' => Monolog::ERROR, 44 | 'critical' => Monolog::CRITICAL, 45 | 'alert' => Monolog::ALERT, 46 | 'emergency' => Monolog::EMERGENCY, 47 | 'none' => 1000, 48 | ]; 49 | 50 | /** 51 | * Constructor. 52 | */ 53 | public function __construct(RollbarNotifier $rollbar, Application $app, $level = 'debug') 54 | { 55 | $this->rollbar = $rollbar; 56 | 57 | $this->app = $app; 58 | 59 | $this->level = $this->parseLevel($level ?: 'debug'); 60 | } 61 | 62 | /** 63 | * Log a message to Rollbar. 64 | * 65 | * @param mixed $level 66 | * @param string $message 67 | * @param array $context 68 | */ 69 | public function log($level, $message, array $context = []) 70 | { 71 | // Check if we want to log this message. 72 | if ($this->parseLevel($level) < $this->level) { 73 | return; 74 | } 75 | 76 | $context = $this->addContext($context); 77 | 78 | if ($message instanceof Exception) { 79 | $this->rollbar->report_exception($message, null, $context); 80 | } else { 81 | $this->rollbar->report_message($message, $level, $context); 82 | } 83 | } 84 | 85 | /** 86 | * Add Laravel specific information to the context. 87 | * 88 | * @param array $context 89 | */ 90 | protected function addContext(array $context = []) 91 | { 92 | // Add session data. 93 | if ($session = $this->app->session->all()) { 94 | if (empty($this->rollbar->person) or ! is_array($this->rollbar->person)) { 95 | $this->rollbar->person = []; 96 | } 97 | 98 | // Merge person context. 99 | if (isset($context['person']) and is_array($context['person'])) { 100 | $this->rollbar->person = $context['person']; 101 | unset($context['person']); 102 | } else { 103 | if ($this->rollbar->person_fn && is_callable($this->rollbar->person_fn)) { 104 | $data = @call_user_func($this->rollbar->person_fn); 105 | if (isset($data['id'])) { 106 | $this->rollbar->person = call_user_func($this->rollbar->person_fn); 107 | } 108 | } 109 | } 110 | 111 | // Add user session information. 112 | if (isset($this->rollbar->person['session'])) { 113 | $this->rollbar->person['session'] = array_merge($session, $this->rollbar->person['session']); 114 | } else { 115 | $this->rollbar->person['session'] = $session; 116 | } 117 | 118 | // User session id as user id if not set. 119 | if (! isset($this->rollbar->person['id'])) { 120 | $this->rollbar->person['id'] = $this->app->session->getId(); 121 | } 122 | } 123 | 124 | return $context; 125 | } 126 | 127 | /** 128 | * Parse the string level into a Monolog constant. 129 | * 130 | * @param string $level 131 | * @return int 132 | * 133 | * @throws \InvalidArgumentException 134 | */ 135 | protected function parseLevel($level) 136 | { 137 | if (isset($this->levels[$level])) { 138 | return $this->levels[$level]; 139 | } 140 | 141 | throw new InvalidArgumentException('Invalid log level: ' . $level); 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/RollbarServiceProvider.php: -------------------------------------------------------------------------------- 1 | app; 23 | 24 | // Listen to log messages. 25 | $app['log']->listen(function () use ($app) { 26 | $args = func_get_args(); 27 | 28 | // Laravel 5.4 returns a MessageLogged instance only 29 | if (count($args) == 1) { 30 | $level = $args[0]->level; 31 | $message = $args[0]->message; 32 | $context = $args[0]->context; 33 | } else { 34 | $level = $args[0]; 35 | $message = $args[1]; 36 | $context = $args[2]; 37 | } 38 | 39 | $app['Jenssegers\Rollbar\RollbarLogHandler']->log($level, $message, $context); 40 | }); 41 | } 42 | 43 | /** 44 | * Register the service provider. 45 | */ 46 | public function register() 47 | { 48 | // Don't register rollbar if it is not configured. 49 | if (! getenv('ROLLBAR_TOKEN') and ! $this->app['config']->get('services.rollbar')) { 50 | return; 51 | } 52 | 53 | $app = $this->app; 54 | 55 | $this->app->singleton('RollbarNotifier', function ($app) { 56 | // Default configuration. 57 | $defaults = [ 58 | 'environment' => $app->environment(), 59 | 'root' => base_path(), 60 | ]; 61 | 62 | $config = array_merge($defaults, $app['config']->get('services.rollbar', [])); 63 | 64 | $config['access_token'] = getenv('ROLLBAR_TOKEN') ?: $app['config']->get('services.rollbar.access_token'); 65 | 66 | if (empty($config['access_token'])) { 67 | throw new InvalidArgumentException('Rollbar access token not configured'); 68 | } 69 | 70 | Rollbar::$instance = $rollbar = new RollbarNotifier($config); 71 | 72 | return $rollbar; 73 | }); 74 | 75 | $this->app->singleton('Jenssegers\Rollbar\RollbarLogHandler', function ($app) { 76 | $level = getenv('ROLLBAR_LEVEL') ?: $app['config']->get('services.rollbar.level', 'debug'); 77 | 78 | return new RollbarLogHandler($app['RollbarNotifier'], $app, $level); 79 | }); 80 | 81 | // Register the fatal error handler. 82 | register_shutdown_function(function () use ($app) { 83 | if (isset($app['RollbarNotifier'])) { 84 | $app->make('RollbarNotifier'); 85 | Rollbar::report_fatal_error(); 86 | } 87 | }); 88 | 89 | // If the Rollbar client was resolved, then there is a possibility that there 90 | // are unsent error messages in the internal queue, so let's flush them. 91 | register_shutdown_function(function () use ($app) { 92 | if (isset($app['RollbarNotifier'])) { 93 | $app['RollbarNotifier']->flush(); 94 | } 95 | }); 96 | } 97 | } 98 | --------------------------------------------------------------------------------