Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,32 @@ php:
env:
matrix:
# All versions below should be test on PHP ^7.1 (Sentry SDK requrement)
- LARAVEL=5.1.* TESTBENCH=3.1.* PHPUNIT=5.7.* SENTRY=^2.3
- LARAVEL=5.2.* TESTBENCH=3.2.* PHPUNIT=5.7.* SENTRY=^2.3
- LARAVEL=5.3.* TESTBENCH=3.3.* PHPUNIT=5.7.* SENTRY=^2.3
- LARAVEL=5.4.* TESTBENCH=3.4.* PHPUNIT=5.7.* SENTRY=^2.3
- LARAVEL=5.5.* TESTBENCH=3.5.* PHPUNIT=6.5.* SENTRY=^2.3
- LARAVEL=5.6.* TESTBENCH=3.6.* PHPUNIT=7.5.* SENTRY=^2.3
- LARAVEL=5.7.* TESTBENCH=3.7.* PHPUNIT=7.5.* SENTRY=^2.3
- LARAVEL=5.8.* TESTBENCH=3.8.* PHPUNIT=7.5.* SENTRY=^2.3
- LARAVEL=5.1.* TESTBENCH=3.1.* PHPUNIT=5.7.* SENTRY=^3.0
- LARAVEL=5.2.* TESTBENCH=3.2.* PHPUNIT=5.7.* SENTRY=^3.0
- LARAVEL=5.3.* TESTBENCH=3.3.* PHPUNIT=5.7.* SENTRY=^3.0
- LARAVEL=5.4.* TESTBENCH=3.4.* PHPUNIT=5.7.* SENTRY=^3.0
- LARAVEL=5.5.* TESTBENCH=3.5.* PHPUNIT=6.5.* SENTRY=^3.0
- LARAVEL=5.6.* TESTBENCH=3.6.* PHPUNIT=7.5.* SENTRY=^3.0
- LARAVEL=5.7.* TESTBENCH=3.7.* PHPUNIT=7.5.* SENTRY=^3.0
- LARAVEL=5.8.* TESTBENCH=3.8.* PHPUNIT=7.5.* SENTRY=^3.0

# All versions below only support PHP ^7.2 (Laravel requirement)
- LARAVEL=^6.0 TESTBENCH=4.7.* PHPUNIT=8.4.* SENTRY=^2.3
- LARAVEL=^7.0 TESTBENCH=5.1.* PHPUNIT=8.4.* SENTRY=^2.3
- LARAVEL=^6.0 TESTBENCH=4.7.* PHPUNIT=8.4.* SENTRY=^3.0
- LARAVEL=^7.0 TESTBENCH=5.1.* PHPUNIT=8.4.* SENTRY=^3.0

# We add one more test using the next version of Laravel which only support PHP ^7.3 (Laravel requirement)
- LARAVEL=8.x-dev@dev TESTBENCH=^6.0 PHPUNIT=8.4.* SENTRY=^2.3 COMPOSER_STABILITY=dev
- LARAVEL=8.x-dev@dev TESTBENCH=^6.0 PHPUNIT=8.4.* SENTRY=^3.0 COMPOSER_STABILITY=dev

matrix:
fast_finish: true
allow_failures:
- php: 7.3
env: LARAVEL=8.x-dev@dev TESTBENCH=^6.0 PHPUNIT=8.4.* SENTRY=^2.3 COMPOSER_STABILITY=dev
env: LARAVEL=8.x-dev@dev TESTBENCH=^6.0 PHPUNIT=8.4.* SENTRY=^3.0 COMPOSER_STABILITY=dev
- php: 7.4
env: LARAVEL=8.x-dev@dev TESTBENCH=^6.0 PHPUNIT=8.4.* SENTRY=^2.3 COMPOSER_STABILITY=dev
env: LARAVEL=8.x-dev@dev TESTBENCH=^6.0 PHPUNIT=8.4.* SENTRY=^3.0 COMPOSER_STABILITY=dev
exclude:
- php: 7.2
env: LARAVEL=8.x-dev@dev TESTBENCH=^6.0 PHPUNIT=8.4.* SENTRY=^2.3 COMPOSER_STABILITY=dev
env: LARAVEL=8.x-dev@dev TESTBENCH=^6.0 PHPUNIT=8.4.* SENTRY=^3.0 COMPOSER_STABILITY=dev

cache:
directories:
Expand Down
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,29 @@

## Unreleased

## 2.0.0

**Breaking Change**: This version uses the [envelope endpoint](https://develop.sentry.dev/sdk/envelopes/). If you are
using an on-premise installation it requires Sentry version `>= v20.6.0` to work. If you are using
[sentry.io](https://sentry.io) nothing will change and no action is needed.

**Tracing API / Monitor Performance**

In this version we released API for Tracing. `\Sentry\startTransaction` is your entry point for manual instrumentation.
More information can be found in our [Performance](https://docs.sentry.io/platforms/php/guides/laravel/performance/) docs.

- Using `^3.0` of Sentry PHP SDK
- Add support for Tracing, enable it by setting `traces_sample_rate` in the config to a value > 0 (the value should be larger than `0.0` and smaller or equal than `1.0` (to send everything))

## 2.0.0-beta1

**Breaking Change**: This version uses the [envelope endpoint](https://develop.sentry.dev/sdk/envelopes/). If you are
using an on-premise installation it requires Sentry version `>= v20.6.0` to work. If you are using
[sentry.io](https://sentry.io) nothing will change and no action is needed.

- Using `3.0.0-beta1` of Sentry PHP SDK
- Add support for Tracing, enable it by setting `traces_sample_rate` in the config to a value > 0 (the value should be larger than `0.0` and smaller or equal than `1.0` (to send everything))

## 1.9.0

- Respect the `SENTRY_ENVIRONMENT` environment variable to override the Laravel environment (#354)
Expand Down
9 changes: 5 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
}
],
"require": {
"php": "^7.1",
"php": "^7.2",
"illuminate/support": "5.0 - 5.8 | ^6.0 | ^7.0 | ^8.0",
"sentry/sdk": "^2.1"
"sentry/sdk": "^3.0"
},
"require-dev": {
"phpunit/phpunit": "^8.0",
Expand Down Expand Up @@ -57,12 +57,13 @@
},
"extra": {
"branch-alias": {
"dev-master": "1.x-dev",
"dev-master": "2.x-dev",
"dev-0.x": "0.x-dev"
},
"laravel": {
"providers": [
"Sentry\\Laravel\\ServiceProvider"
"Sentry\\Laravel\\ServiceProvider",
"Sentry\\Laravel\\Tracing\\ServiceProvider"
],
"aliases": {
"Sentry": "Sentry\\Laravel\\Facade"
Expand Down
1 change: 1 addition & 0 deletions config/sentry.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@
// @see: https://docs.sentry.io/error-reporting/configuration/?platform=php#send-default-pii
'send_default_pii' => false,

'traces_sample_rate' => \floatval(env('SENTRY_TRACES_SAMPLE_RATE', 0.0)),
];
39 changes: 20 additions & 19 deletions src/Sentry/Laravel/EventHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@
use Illuminate\Queue\QueueManager;
use Illuminate\Routing\Events\RouteMatched;
use Illuminate\Routing\Route;
use Illuminate\Support\Str;
use RuntimeException;
use Sentry\Breadcrumb;
use Sentry\SentrySdk;
use Sentry\State\Scope;
use Sentry\Tracing\SpanContext;
use Sentry\Tracing\Transaction;

class EventHandler
{
Expand Down Expand Up @@ -194,26 +195,16 @@ public function __call($method, $arguments)
*/
protected function routerMatchedHandler(Route $route)
{
$routeName = null;
$routeName = Integration::extractNameForRoute($route) ?? '<unlabeled transaction>';

if ($route->getName()) {
// someaction (route name/alias)
$routeName = $route->getName();
$transaction = SentrySdk::getCurrentHub()->getTransaction();

// Laravel 7 route caching generates a route names if the user didn't specify one
// theirselfs to optimize route matching. These route names are useless to the
// developer so if we encounter a generated route name we discard the value
if (Str::startsWith($routeName, 'generated::')) {
$routeName = null;
}
}

if (empty($routeName) && $route->getActionName()) {
// SomeController@someAction (controller action)
$routeName = $route->getActionName();
} elseif (empty($routeName) || $routeName === 'Closure') {
// /someaction // Fallback to the url
$routeName = $route->uri();
if ($transaction instanceof Transaction) {
$transaction->setName($routeName);
$transaction->setData([
'action' => $route->getActionName(),
'name' => $route->getName()
]);
}

Integration::addBreadcrumb(new Breadcrumb(
Expand Down Expand Up @@ -287,6 +278,16 @@ private function addQueryBreadcrumb($query, $bindings, $time, $connectionName)
$data['bindings'] = $bindings;
}

$transaction = SentrySdk::getCurrentHub()->getTransaction();
if (null !== $transaction) {
$context = new SpanContext();
$context->setOp('sql.query');
$context->setDescription($query);
$context->setStartTimestamp(microtime(true) - $time / 1000);
$context->setEndTimestamp($context->getStartTimestamp() + $time / 1000);
$transaction->startChild($context);
}

Integration::addBreadcrumb(new Breadcrumb(
Breadcrumb::LEVEL_INFO,
Breadcrumb::TYPE_DEFAULT,
Expand Down
83 changes: 81 additions & 2 deletions src/Sentry/Laravel/Integration.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

namespace Sentry\Laravel;

use Illuminate\Routing\Route;
use Illuminate\Support\Str;
use Sentry\FlushableClientInterface;
use Sentry\SentrySdk;
use Sentry\Tracing\Span;
use function Sentry\addBreadcrumb;
use function Sentry\configureScope;
use Sentry\Breadcrumb;
Expand All @@ -30,7 +33,9 @@ public function setupOnce(): void
return $event;
}

$event->setTransaction($self->getTransaction());
if (null === $event->getTransaction()) {
$event->setTransaction($self->getTransaction());
}

return $event;
});
Expand Down Expand Up @@ -71,7 +76,7 @@ public static function configureScope(callable $callback): void
/**
* @return null|string
*/
public static function getTransaction()
public static function getTransaction(): ?string
{
return self::$transaction;
}
Expand All @@ -98,4 +103,78 @@ public static function flushEvents(): void
$client->flush();
}
}

/**
* Extract the readable name for a route.
*
* @param \Illuminate\Routing\Route $route
*
* @return string|null
*/
public static function extractNameForRoute(Route $route): ?string
{
$routeName = null;

if (empty($routeName) && $route->getName()) {
// someaction (route name/alias)
$routeName = $route->getName();

// Laravel 7 route caching generates a route names if the user didn't specify one
// theirselfs to optimize route matching. These route names are useless to the
// developer so if we encounter a generated route name we discard the value
if (Str::startsWith($routeName, 'generated::')) {
$routeName = null;
}

// If the route name ends with a `.` we assume an incomplete group name prefix
// we discard this value since it will most likely not mean anything to the
// developer and will be duplicated by other unnamed routes in the group
if (Str::endsWith($routeName, '.')) {
$routeName = null;
}
}

if (empty($routeName) && $route->getActionName()) {
// SomeController@someAction (controller action)
$routeName = ltrim($route->getActionName(), '\\');
}

if (empty($routeName) || $routeName === 'Closure') {
// /someaction // Fallback to the url
$routeName = '/' . ltrim($route->uri(), '/');
}

return $routeName;
}

/**
* Retrieve the meta tags with tracing information to link this request to front-end requests.
*
* @return string
*/
public static function sentryTracingMeta(): string
{
$span = self::currentTracingSpan();

if ($span === null) {
return '';
}

$content = sprintf('<meta name="sentry-trace" content="%s"/>', $span->toTraceparent());
// $content .= sprintf('<meta name="sentry-trace-data" content="%s"/>', $span->getDescription());

return $content;
}

/**
* Get the current active tracing span from the scope.
*
* @return \Sentry\Tracing\Span|null
*
* @internal This is used internally as an easy way to retrieve the current active tracing span.
*/
public static function currentTracingSpan(): ?Span
{
return SentrySdk::getCurrentHub()->getSpan();
}
}
86 changes: 86 additions & 0 deletions src/Sentry/Laravel/PublishConfigCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?php

namespace Sentry\Laravel;

use Illuminate\Console\Command;

class PublishConfigCommand extends Command
{
/**
* Laravel 5.0.x: The name and signature of the console command.
*
* @var string
*/
protected $name = 'sentry:publish';

/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'sentry:publish';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Publishes the Sentry Config';

/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$this->info('[Sentry] Publishing config ...');
$this->call('vendor:publish', [
'--provider' => 'Sentry\Laravel\ServiceProvider'
]);

if ($this->confirm('Enable Performance Monitoring?', true)) {
$this->setEnvironmentValue(['SENTRY_TRACES_SAMPLE_RATE' => 1.0]);

$this->info('[Sentry] Added `SENTRY_TRACES_SAMPLE_RATE=1` to your .env file.');

$testCommandPrompt = 'Want to send a test Event & Transaction?';
$args = ['--transaction' => true];
} else {
$testCommandPrompt = 'Want to send a test Event?';
$args = [];
}

if ($this->confirm($testCommandPrompt, true)) {
$this->call('sentry:test', $args);
}
}

public function setEnvironmentValue(array $values)
{
$envFile = app()->environmentFilePath();
$str = file_get_contents($envFile);

if (count($values) > 0) {
foreach ($values as $envKey => $envValue) {

$str .= "\n"; // In case the searched variable is in the last line without \n
$keyPosition = strpos($str, "{$envKey}=");
$endOfLinePosition = strpos($str, "\n", $keyPosition);
$oldLine = substr($str, $keyPosition, $endOfLinePosition - $keyPosition);

// If key does not exist, add it
if (!$keyPosition || !$endOfLinePosition || !$oldLine) {
$str .= "{$envKey}={$envValue}\n";
} else {
$str = str_replace($oldLine, "{$envKey}={$envValue}", $str);
}

}
}

$str = substr($str, 0, -1);
if (!file_put_contents($envFile, $str)) return false;
return true;
}
}
3 changes: 3 additions & 0 deletions src/Sentry/Laravel/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Sentry\Laravel;

use Illuminate\Contracts\Http\Kernel as HttpKernelInterface;
use Sentry\SentrySdk;
use Sentry\State\Hub;
use Sentry\ClientBuilder;
Expand All @@ -12,6 +13,7 @@
use Sentry\Integration as SdkIntegration;
use Illuminate\Foundation\Application as Laravel;
use Illuminate\Support\ServiceProvider as IlluminateServiceProvider;
use Illuminate\Support\Facades\Storage;

class ServiceProvider extends IlluminateServiceProvider
{
Expand Down Expand Up @@ -91,6 +93,7 @@ protected function registerArtisanCommands(): void
{
$this->commands([
TestCommand::class,
PublishConfigCommand::class,
]);
}

Expand Down
Loading