Skip to content

Commit

Permalink
Do not lazy load Sentry on resolving (#189)
Browse files Browse the repository at this point in the history
* Do not lazy load Sentry

This way the Hub has the current (configured) client and users can use the Hub or SDK methods to configure their environment and/or capture exception with the already configured client.

* Update php-cs-fixer to work on PHP 7.3

* Combine Lumen & Laravel service providers

* Cleanup the test command

* Little cleanups / cs

* Stop test command if no DSN was found
  • Loading branch information
stayallive authored and HazAT committed Feb 15, 2019
1 parent d0ac515 commit b03ae4f
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 196 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"phpunit/phpunit": "7.3.*",
"laravel/framework": "5.7.*",
"orchestra/testbench": "3.7.*",
"friendsofphp/php-cs-fixer": "2.7.*"
"friendsofphp/php-cs-fixer": "2.14.*"
},
"autoload": {
"psr-0": {
Expand Down
6 changes: 1 addition & 5 deletions src/Sentry/Laravel/LogChannel.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,7 @@ class LogChannel extends LogManager
*/
public function __invoke(array $config)
{
$handler = new SentryHandler(
$this->app->make('sentry'),
isset($config['level']) ? $config['level'] : null,
isset($config['bubble']) ? $config['bubble'] : true
);
$handler = new SentryHandler($this->app->make('sentry'), $config['level'] ?? null, $config['bubble'] ?? true);

return new Logger($this->parseChannel($config), [$this->prepareHandler($handler, $config)]);
}
Expand Down
105 changes: 0 additions & 105 deletions src/Sentry/Laravel/LumenServiceProvider.php

This file was deleted.

115 changes: 56 additions & 59 deletions src/Sentry/Laravel/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

namespace Sentry\Laravel;

use function Sentry\configureScope;
use Sentry\ClientBuilder;
use Sentry\State\Hub;
use Sentry\ClientBuilder;
use Illuminate\Log\LogManager;
use Laravel\Lumen\Application as Lumen;
use Illuminate\Foundation\Application as Laravel;
use Illuminate\Support\ServiceProvider as IlluminateServiceProvider;

class ServiceProvider extends \Illuminate\Support\ServiceProvider
class ServiceProvider extends IlluminateServiceProvider
{
/**
* Abstract type to bind Sentry as in the Service Container.
Expand All @@ -16,108 +19,102 @@ class ServiceProvider extends \Illuminate\Support\ServiceProvider
public static $abstract = 'sentry';

/**
* Bootstrap the application events.
*
* @return void
* Boot the service provider.
*/
public function boot()
public function boot(): void
{
// Publish the configuration file
$this->publishes(array(
__DIR__ . '/../../../config/sentry.php' => config_path(static::$abstract . '.php'),
), 'config');
$this->app->make(self::$abstract);

$this->bindEvents($this->app);

if ($this->app->runningInConsole()) {
if ($this->app instanceof Laravel) {
$this->publishes([
__DIR__ . '/../../../config/sentry.php' => config_path(static::$abstract . '.php'),
], 'config');
}

$this->registerArtisanCommands();
}
}

/**
* Register the artisan commands.
* Register the service provider.
*/
protected function registerArtisanCommands()
public function register(): void
{
$this->commands(array(
'Sentry\Laravel\TestCommand',
));
if ($this->app instanceof Lumen) {
$this->app->configure('sentry');
}

$this->mergeConfigFrom(__DIR__ . '/../../../config/sentry.php', static::$abstract);

$this->configureAndRegisterClient($this->app['config'][static::$abstract]);

if (($logManager = $this->app->make('log')) instanceof LogManager) {
$logManager->extend('sentry', function ($app, array $config) {
return (new LogChannel($app))($config);
});
}
}

/**
* Bind to the Laravel event dispatcher to log events.
*
* @param $app
*/
protected function bindEvents($app)
protected function bindEvents(): void
{
$userConfig = $app['config'][static::$abstract];
$userConfig = $this->app['config'][static::$abstract];

$handler = new EventHandler($userConfig);

$handler->subscribe($app->events);
$handler->subscribe($this->app->events);

// In Laravel >=5.3 we can get the user context from the auth events
if (isset($userConfig['send_default_pii']) && $userConfig['send_default_pii'] !== false && version_compare($app::VERSION, '5.3') >= 0) {
$handler->subscribeAuthEvents($app->events);
if (isset($userConfig['send_default_pii']) && $userConfig['send_default_pii'] !== false) {
$handler->subscribeAuthEvents($this->app->events);
}
}

/**
* Register the service provider.
*
* @return void
* Register the artisan commands.
*/
public function register()
protected function registerArtisanCommands(): void
{
$this->mergeConfigFrom(__DIR__ . '/../../../config/sentry.php', static::$abstract);

$app = $this->app;
$this->commands([
TestCommand::class,
]);
}

$this->app->singleton(static::$abstract, function ($app) {
$userConfig = $app['config'][static::$abstract];
/**
* Configure and register the Sentry client with the container.
*/
protected function configureAndRegisterClient(): void
{
$this->app->singleton(static::$abstract, function () {
$basePath = base_path();
$userConfig = $this->app['config'][static::$abstract];

// We do not want this setting to hit our main client
// We do not want this setting to hit our main client because it's Laravel specific
unset($userConfig['breadcrumbs.sql_bindings']);

$options = \array_merge(
[
'environment' => $app->environment(),
'prefixes' => array($basePath),
'environment' => $this->app->environment(),
'prefixes' => [$basePath],
'project_root' => $basePath,
'in_app_exclude' => array($basePath . '/vendor'),
'integrations' => [new Integration()]
'in_app_exclude' => [$basePath . '/vendor'],
'integrations' => [new Integration],
],
$userConfig
);

$clientBuilder = ClientBuilder::create($options);
$clientBuilder->setSdkIdentifier(Version::SDK_IDENTIFIER);
$clientBuilder->setSdkVersion(Version::SDK_VERSION);
Hub::setCurrent(new Hub($clientBuilder->getClient()));

if (isset($userConfig['send_default_pii']) && $userConfig['send_default_pii'] !== false && version_compare($app::VERSION, '5.3') < 0) {
try {
// Bind user context if available
if ($app['auth']->check()) {
configureScope(function (Scope $scope) use ($app): void {
$scope->setUser(['id' => $app['auth']->user()->getAuthIdentifier()]);
});
}
} catch (Exception $e) {
error_log(sprintf('sentry.breadcrumbs error=%s', $e->getMessage()));
}
}
Hub::setCurrent(new Hub($clientBuilder->getClient()));

return Hub::getCurrent();
});

// Add a sentry log channel for Laravel 5.6+
if (version_compare($app::VERSION, '5.6') >= 0) {
$app->make('log')->extend('sentry', function ($app, array $config) {
$channel = new LogChannel($app);
return $channel($config);
});
}
}

/**
Expand Down
32 changes: 17 additions & 15 deletions src/Sentry/Laravel/TestCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Sentry\Laravel;

use Exception;
use Illuminate\Console\Command;

class TestCommand extends Command
Expand Down Expand Up @@ -38,34 +39,35 @@ public function handle()
$old_error_reporting = error_reporting(E_ALL | E_STRICT);

try {
/** @var \Sentry\State\Hub $hub */
$hub = app('sentry');

/** @var \Sentry\Client $client */
$client = $hub->getClient();

if ($client->getOptions()->getDsn()) {
$this->info("[sentry] Client DSN discovered!");
if ($hub->getClient()->getOptions()->getDsn()) {
$this->info('[sentry] Client DSN discovered!');
} else {
$this->warn('[sentry] Could not discover DSN! Check your config or .env file');

return;
}

$this->info('[sentry] Generating test event');

$ex = $this->generateTestException('command name', array('foo' => 'bar'));
$ex = $this->generateTestException('command name', ['foo' => 'bar']);

$hub->captureException($ex);

$this->info("[sentry] Sending test event");
$this->info('[sentry] Sending test event');

$lastEventId = $hub->getLastEventId();

if (!$lastEventId) {
$this->error("[sentry] There was an error sending the test event.");
$this->error("[sentry] Please check if you dsn is set properly in your config. SENTRY_LARAVEL_DSN");
$this->error('[sentry] There was an error sending the test event.');
$this->error('[sentry] Please check if you DSN is set properly in your config or .env as `SENTRY_LARAVEL_DSN`.');
} else {
$this->info("[sentry] Event sent: " . $lastEventId);
$this->info("[sentry] Event sent with ID: {$lastEventId}");
}
} catch (\Exception $e) {
$this->error("[sentry] " . $e->getMessage());
} catch (Exception $e) {
$this->error("[sentry] {$e->getMessage()}");
}

error_reporting($old_error_reporting);
Expand All @@ -79,12 +81,12 @@ public function handle()
*
* @return \Exception
*/
protected function generateTestException($command, $arg)
protected function generateTestException($command, $arg): ?Exception
{
// Do something silly
try {
throw new \Exception('This is a test exception sent from the Sentry Laravel SDK.');
} catch (\Exception $ex) {
throw new Exception('This is a test exception sent from the Sentry Laravel SDK.');
} catch (Exception $ex) {
return $ex;
}
}
Expand Down
11 changes: 0 additions & 11 deletions src/Sentry/Laravel/config.php

This file was deleted.

0 comments on commit b03ae4f

Please sign in to comment.