Skip to content

Commit a733bbb

Browse files
committed
Drop Laravel Lumen support (#579)
1 parent acbf236 commit a733bbb

File tree

8 files changed

+66
-164
lines changed

8 files changed

+66
-164
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## Unreleased
44

5+
- Drop support for Laravel Lumen (#579)
6+
57
## 2.14.2
68

79
- Fix extracting command input resulting in errors when calling Artisan commands programatically with `null` as an argument value (#589)

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ try {
7878

7979
## Laravel Version Compatibility
8080

81+
- Laravel Lumen is supported until `2.14.x`
8182
- Laravel `<= 4.2.x` is supported until `0.8.x`
8283
- Laravel `<= 5.7.x` on PHP `<= 7.0` is supported until `0.11.x`
8384
- Laravel `>= 5.x.x` on PHP `>= 7.1` is supported in all versions

composer.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
"symfony/psr-http-message-bridge": "^1.0 | ^2.0",
2929
"nyholm/psr7": "^1.0"
3030
},
31+
"conflict": {
32+
"laravel/lumen-framework": "*"
33+
},
3134
"autoload": {
3235
"psr-0": {
3336
"Sentry\\Laravel\\": "src/"

src/Sentry/Laravel/Integration.php

Lines changed: 42 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Illuminate\Support\Str;
77
use Sentry\SentrySdk;
88
use Sentry\Tracing\Span;
9+
use Sentry\Tracing\TransactionSource;
910
use function Sentry\addBreadcrumb;
1011
use function Sentry\configureScope;
1112
use Sentry\Breadcrumb;
@@ -122,67 +123,48 @@ public static function flushEvents(): void
122123
* @param \Illuminate\Routing\Route $route
123124
*
124125
* @return string
126+
*
127+
* @internal This helper is used in various places to extra meaninful info from a Laravel Route object.
128+
* @deprecated This will be removed in version 3.0, use `extractNameAndSourceForRoute` instead.
125129
*/
126130
public static function extractNameForRoute(Route $route): string
127131
{
128-
$routeName = null;
129-
130-
// someaction (route name/alias)
131-
if ($route->getName()) {
132-
$routeName = self::extractNameForNamedRoute($route->getName());
133-
}
134-
135-
// Some\Controller@someAction (controller action)
136-
if (empty($routeName) && $route->getActionName()) {
137-
$routeName = self::extractNameForActionRoute($route->getActionName());
138-
}
139-
140-
// /someaction // Fallback to the url
141-
if (empty($routeName) || $routeName === 'Closure') {
142-
$routeName = '/' . ltrim($route->uri(), '/');
143-
}
144-
145-
return $routeName;
132+
return self::extractNameAndSourceForRoute($route)[0];
146133
}
147134

148135
/**
149-
* Extract the readable name for a Lumen route.
136+
* Extract the readable name for a route and the transaction source for where that route name came from.
150137
*
151-
* @param array $routeData The array of route data
152-
* @param string $path The path of the request
138+
* @param \Illuminate\Routing\Route $route
153139
*
154-
* @return string
140+
* @return array{0: string, 1: \Sentry\Tracing\TransactionSource}
141+
*
142+
* @internal This helper is used in various places to extra meaninful info from a Laravel Route object.
155143
*/
156-
public static function extractNameForLumenRoute(array $routeData, string $path): string
144+
public static function extractNameAndSourceForRoute(Route $route): array
157145
{
146+
$source = null;
158147
$routeName = null;
159148

160-
$route = $routeData[1] ?? [];
161-
162-
// someaction (route name/alias)
163-
if (!empty($route['as'])) {
164-
$routeName = self::extractNameForNamedRoute($route['as']);
149+
// some.action (route name/alias)
150+
if ($route->getName()) {
151+
$source = TransactionSource::component();
152+
$routeName = self::extractNameForNamedRoute($route->getName());
165153
}
166154

167155
// Some\Controller@someAction (controller action)
168-
if (empty($routeName) && !empty($route['uses'])) {
169-
$routeName = self::extractNameForActionRoute($route['uses']);
156+
if (empty($routeName) && $route->getActionName()) {
157+
$source = TransactionSource::component();
158+
$routeName = self::extractNameForActionRoute($route->getActionName());
170159
}
171160

172-
// /someaction // Fallback to the url
161+
// /some/{action} // Fallback to the route uri (with parameter placeholders)
173162
if (empty($routeName) || $routeName === 'Closure') {
174-
$routeUri = array_reduce(
175-
array_keys($routeData[2]),
176-
static function ($carry, $key) use ($routeData) {
177-
return str_replace($routeData[2][$key], "{{$key}}", $carry);
178-
},
179-
$path
180-
);
181-
182-
$routeName = '/' . ltrim($routeUri, '/');
163+
$source = TransactionSource::route();
164+
$routeName = '/' . ltrim($route->uri(), '/');
183165
}
184166

185-
return $routeName;
167+
return [$routeName, $source];
186168
}
187169

188170
/**
@@ -247,7 +229,25 @@ public static function sentryTracingMeta(): string
247229
}
248230

249231
$content = sprintf('<meta name="sentry-trace" content="%s"/>', $span->toTraceparent());
250-
// $content .= sprintf('<meta name="sentry-trace-data" content="%s"/>', $span->getDescription());
232+
233+
return $content;
234+
}
235+
236+
/**
237+
* Retrieve the meta tags with baggage information to link this request to front-end requests.
238+
* This propagates the Dynamic Sampling Context.
239+
*
240+
* @return string
241+
*/
242+
public static function sentryBaggageMeta(): string
243+
{
244+
$span = self::currentTracingSpan();
245+
246+
if ($span === null) {
247+
return '';
248+
}
249+
250+
$content = sprintf('<meta name="baggage" content="%s"/>', $span->toBaggage());
251251

252252
return $content;
253253
}

src/Sentry/Laravel/ServiceProvider.php

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
use Illuminate\Foundation\Application as Laravel;
77
use Illuminate\Foundation\Http\Kernel as HttpKernel;
88
use Illuminate\Log\LogManager;
9-
use Laravel\Lumen\Application as Lumen;
109
use RuntimeException;
1110
use Sentry\ClientBuilder;
1211
use Sentry\ClientBuilderInterface;
@@ -48,10 +47,7 @@ public function boot(): void
4847
if ($this->hasDsnSet()) {
4948
$this->bindEvents();
5049

51-
if ($this->app instanceof Lumen) {
52-
$this->app->middleware(SetRequestMiddleware::class);
53-
$this->app->middleware(SetRequestIpMiddleware::class);
54-
} elseif ($this->app->bound(HttpKernelInterface::class)) {
50+
if ($this->app->bound(HttpKernelInterface::class)) {
5551
/** @var \Illuminate\Foundation\Http\Kernel $httpKernel */
5652
$httpKernel = $this->app->make(HttpKernelInterface::class);
5753

@@ -78,10 +74,6 @@ public function boot(): void
7874
*/
7975
public function register(): void
8076
{
81-
if ($this->app instanceof Lumen) {
82-
$this->app->configure(static::$abstract);
83-
}
84-
8577
$this->mergeConfigFrom(__DIR__ . '/../../../config/sentry.php', static::$abstract);
8678

8779
$this->configureAndRegisterClient();

src/Sentry/Laravel/Tracing/Middleware.php

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Sentry\Tracing\Span;
1212
use Sentry\Tracing\SpanContext;
1313
use Sentry\Tracing\TransactionContext;
14+
use Sentry\Tracing\TransactionSource;
1415
use Symfony\Component\HttpFoundation\Response;
1516

1617
class Middleware
@@ -90,9 +91,8 @@ public function terminate($request, $response): void
9091
* @param float|null $timestamp The unix timestamp of the booted event, default to `microtime(true)` if not `null`.
9192
*
9293
* @return void
93-
* @internal This method should only be invoked right after the application has finished "booting":
94-
* For Laravel this is from the application `booted` callback.
95-
* For Lumen this is right before returning from the `bootstrap/app.php` file.
94+
*
95+
* @internal This method should only be invoked right after the application has finished "booting".
9696
*/
9797
public function setBootedTimestamp(?float $timestamp = null): void
9898
{
@@ -102,11 +102,11 @@ public function setBootedTimestamp(?float $timestamp = null): void
102102
private function startTransaction(Request $request, HubInterface $sentry): void
103103
{
104104
$requestStartTime = $request->server('REQUEST_TIME_FLOAT', microtime(true));
105-
$sentryTraceHeader = $request->header('sentry-trace');
106105

107-
$context = $sentryTraceHeader
108-
? TransactionContext::fromSentryTrace($sentryTraceHeader)
109-
: new TransactionContext;
106+
$context = TransactionContext::fromHeaders(
107+
$request->header('sentry-trace', ''),
108+
$request->header('baggage', '')
109+
);
110110

111111
$context->setOp('http.server');
112112
$context->setData([
@@ -180,38 +180,26 @@ private function hydrateRequestData(Request $request): void
180180
$route = $request->route();
181181

182182
if ($route instanceof Route) {
183-
$this->updateTransactionNameIfDefault(
184-
Integration::extractNameForRoute($route)
185-
);
183+
[$transactionName, $transactionSource] = Integration::extractNameAndSourceForRoute($route);
184+
185+
$this->updateTransactionNameIfDefault($transactionName, $transactionSource);
186186

187187
$this->transaction->setData([
188188
'name' => $route->getName(),
189189
'action' => $route->getActionName(),
190190
'method' => $request->getMethod(),
191191
]);
192-
} elseif (is_array($route) && count($route) === 3) {
193-
$this->updateTransactionNameIfDefault(
194-
Integration::extractNameForLumenRoute($route, $request->path())
195-
);
196-
197-
$action = $route[1] ?? [];
198-
199-
$this->transaction->setData([
200-
'name' => $action['as'] ?? null,
201-
'action' => $action['uses'] ?? 'Closure',
202-
'method' => $request->getMethod(),
203-
]);
204192
}
205193

206-
$this->updateTransactionNameIfDefault('/' . ltrim($request->path(), '/'));
194+
$this->updateTransactionNameIfDefault('/' . ltrim($request->path(), '/'), TransactionSource::url());
207195
}
208196

209197
private function hydrateResponseData(Response $response): void
210198
{
211199
$this->transaction->setHttpStatus($response->getStatusCode());
212200
}
213201

214-
private function updateTransactionNameIfDefault(?string $name): void
202+
private function updateTransactionNameIfDefault(?string $name, ?TransactionSource $source): void
215203
{
216204
// Ignore empty names (and `null`) for caller convenience
217205
if (empty($name)) {
@@ -226,5 +214,6 @@ private function updateTransactionNameIfDefault(?string $name): void
226214
}
227215

228216
$this->transaction->setName($name);
217+
$this->transaction->getMetadata()->setSource($source ?? TransactionSource::custom());
229218
}
230219
}

src/Sentry/Laravel/Tracing/ServiceProvider.php

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,9 @@
66
use Illuminate\Contracts\View\Engine;
77
use Illuminate\Contracts\View\View;
88
use Illuminate\Foundation\Http\Kernel as HttpKernel;
9-
use Illuminate\Queue\QueueManager;
109
use Illuminate\View\Engines\EngineResolver;
1110
use Illuminate\View\Factory as ViewFactory;
1211
use InvalidArgumentException;
13-
use Laravel\Lumen\Application as Lumen;
1412
use Sentry\Laravel\BaseServiceProvider;
1513
use Sentry\Serializer\RepresentationSerializer;
1614

@@ -29,9 +27,7 @@ public function boot(): void
2927

3028
$this->bindViewEngine($tracingConfig);
3129

32-
if ($this->app instanceof Lumen) {
33-
$this->app->middleware(Middleware::class);
34-
} elseif ($this->app->bound(HttpKernelInterface::class)) {
30+
if ($this->app->bound(HttpKernelInterface::class)) {
3531
/** @var \Illuminate\Foundation\Http\Kernel $httpKernel */
3632
$httpKernel = $this->app->make(HttpKernelInterface::class);
3733

@@ -55,11 +51,9 @@ public function register(): void
5551
return new BacktraceHelper($options, new RepresentationSerializer($options));
5652
});
5753

58-
if (!$this->app instanceof Lumen) {
59-
$this->app->booted(function () {
60-
$this->app->make(Middleware::class)->setBootedTimestamp();
61-
});
62-
}
54+
$this->app->booted(function () {
55+
$this->app->make(Middleware::class)->setBootedTimestamp();
56+
});
6357
}
6458

6559
private function bindEvents(array $tracingConfig): void

test/Sentry/IntegrationTest.php

Lines changed: 0 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -162,83 +162,4 @@ public function testExtractingNameForRouteWithStrippedBaseNamespaceFromAction():
162162

163163
Integration::setControllersBaseNamespace(null);
164164
}
165-
166-
public function testExtractingNameForLumenRouteWithName(): void
167-
{
168-
$route = [0, ['as' => $routeName = 'foo-bar'], []];
169-
170-
$this->assertSame($routeName, Integration::extractNameForLumenRoute($route, '/some-route'));
171-
}
172-
173-
public function testExtractingNameForLumenRouteWithAction(): void
174-
{
175-
$route = [0, ['uses' => $controller = 'SomeController@someAction'], []];
176-
177-
$this->assertSame($controller, Integration::extractNameForLumenRoute($route, '/some-route'));
178-
}
179-
180-
public function testExtractingNameForLumenRouteWithoutName(): void
181-
{
182-
$url = '/some-route';
183-
184-
$this->assertSame($url, Integration::extractNameForLumenRoute([0, [], []], $url));
185-
}
186-
187-
public function testExtractingNameForLumenRouteWithParamInUrl(): void
188-
{
189-
$route = [1, [], ['param1' => 'foo']];
190-
191-
$url = '/foo/bar/baz';
192-
193-
$this->assertSame('/{param1}/bar/baz', Integration::extractNameForLumenRoute($route, $url));
194-
}
195-
196-
public function testExtractingNameForLumenRouteWithParamsInUrl(): void
197-
{
198-
$route = [1, [], ['param1' => 'foo', 'param2' => 'bar']];
199-
200-
$url = '/foo/bar/baz';
201-
202-
$this->assertSame('/{param1}/{param2}/baz', Integration::extractNameForLumenRoute($route, $url));
203-
}
204-
205-
public function testExtractingNameForLumenRouteWithActionAndName(): void
206-
{
207-
$route = [0, [
208-
'as' => $routeName = 'foo-bar',
209-
'uses' => 'SomeController@someAction',
210-
], []];
211-
212-
$this->assertSame($routeName, Integration::extractNameForLumenRoute($route, '/some-route'));
213-
}
214-
215-
public function testExtractingNameForLumenRouteWithAutoGeneratedName(): void
216-
{
217-
// We fake a generated name here, Laravel generates them each starting with `generated::`
218-
$route = [0, ['as' => 'generated::KoAePbpBofo01ey4'], []];
219-
220-
$url = '/some-route';
221-
222-
$this->assertSame($url, Integration::extractNameForLumenRoute($route, $url));
223-
}
224-
225-
public function testExtractingNameForLumenRouteWithIncompleteGroupName(): void
226-
{
227-
$route = [0, ['as' => 'group-name.'], []];
228-
229-
$url = '/some-route';
230-
231-
$this->assertSame($url, Integration::extractNameForLumenRoute($route, $url));
232-
}
233-
234-
public function testExtractingNameForLumenRouteWithStrippedBaseNamespaceFromAction(): void
235-
{
236-
Integration::setControllersBaseNamespace('BaseNamespace');
237-
238-
$route = [0, ['uses' => 'BaseNamespace\\SomeController@someAction'], []];
239-
240-
$this->assertSame('SomeController@someAction', Integration::extractNameForLumenRoute($route, '/some-route'));
241-
242-
Integration::setControllersBaseNamespace(null);
243-
}
244165
}

0 commit comments

Comments
 (0)