Skip to content

Commit

Permalink
Add support for Spotlight
Browse files Browse the repository at this point in the history
  • Loading branch information
cleptric committed Nov 22, 2023
1 parent 0ac1dbe commit 1dfa5d3
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 3 deletions.
5 changes: 5 additions & 0 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,11 @@ parameters:
count: 1
path: src/Options.php

-
message: "#^Method Sentry\\\\Options\\:\\:getSpotlight\\(\\) should return bool\\|string but returns mixed\\.$#"
count: 1
path: src/Options.php

-
message: "#^Method Sentry\\\\Options\\:\\:getTags\\(\\) should return array\\<string, string\\> but returns mixed\\.$#"
count: 1
Expand Down
22 changes: 22 additions & 0 deletions src/Options.php
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,26 @@ public function setLogger(LoggerInterface $logger): self
return $this;
}

/**
* @return string|bool
*/
public function getSpotlight()
{
return $this->options['spotlight'];
}

/**
* @param string|bool $spotlight
*/
public function setSpotlight($spotlight): self
{
$options = array_merge($this->options, ['spotlight' => $spotlight]);

$this->options = $this->resolver->resolve($options);

return $this;
}

/**
* Gets the release tag to be passed with every event sent to Sentry.
*/
Expand Down Expand Up @@ -984,6 +1004,7 @@ private function configureOptions(OptionsResolver $resolver): void
'context_lines' => 5,
'environment' => $_SERVER['SENTRY_ENVIRONMENT'] ?? null,
'logger' => null,
'spotlight' => false,
'release' => $_SERVER['SENTRY_RELEASE'] ?? null,
'dsn' => $_SERVER['SENTRY_DSN'] ?? null,
'server_name' => gethostname(),
Expand Down Expand Up @@ -1031,6 +1052,7 @@ private function configureOptions(OptionsResolver $resolver): void
$resolver->setAllowedTypes('in_app_exclude', 'string[]');
$resolver->setAllowedTypes('in_app_include', 'string[]');
$resolver->setAllowedTypes('logger', ['null', LoggerInterface::class]);
$resolver->setAllowedTypes('spotlight', ['string', 'bool']);
$resolver->setAllowedTypes('release', ['null', 'string']);
$resolver->setAllowedTypes('dsn', ['null', 'string', 'bool', Dsn::class]);
$resolver->setAllowedTypes('server_name', 'string');
Expand Down
58 changes: 58 additions & 0 deletions src/Spotlight/SpotlightClient.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

declare(strict_types=1);

namespace Sentry\Spotlight;

use Sentry\HttpClient\Request;
use Sentry\HttpClient\Response;

/**
* @internal
*/
class SpotlightClient
{
public static function sendRequest(Request $request, string $url): Response
{
if (!\extension_loaded('curl')) {
throw new \RuntimeException('The cURL PHP extension must be enabled to use the SpotlightClient.');
}

$requestData = $request->getStringBody();
if ($requestData === null) {
throw new \RuntimeException('The request data is empty.');
}

$curlHandle = curl_init();

curl_setopt($curlHandle, \CURLOPT_URL, $url);
curl_setopt($curlHandle, \CURLOPT_HTTPHEADER, [
'Content-Type: application/x-sentry-envelope',
]);
curl_setopt($curlHandle, \CURLOPT_TIMEOUT, 2.0);
curl_setopt($curlHandle, \CURLOPT_CONNECTTIMEOUT, 1.0);
curl_setopt($curlHandle, \CURLOPT_ENCODING, '');
curl_setopt($curlHandle, \CURLOPT_POST, true);
curl_setopt($curlHandle, \CURLOPT_POSTFIELDS, $requestData);
curl_setopt($curlHandle, \CURLOPT_RETURNTRANSFER, true);
curl_setopt($curlHandle, \CURLOPT_HTTP_VERSION, \CURL_HTTP_VERSION_1_1);

$body = curl_exec($curlHandle);

if ($body === false) {
$errorCode = curl_errno($curlHandle);
$error = curl_error($curlHandle);
curl_close($curlHandle);

$message = 'cURL Error (' . $errorCode . ') ' . $error;

return new Response(0, [], $message);
}

$statusCode = curl_getinfo($curlHandle, \CURLINFO_HTTP_CODE);

curl_close($curlHandle);

return new Response($statusCode, [], '');
}
}
29 changes: 26 additions & 3 deletions src/Transport/HttpTransport.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Sentry\HttpClient\Request;
use Sentry\Options;
use Sentry\Serializer\PayloadSerializerInterface;
use Sentry\Spotlight\SpotlightClient;

/**
* @internal
Expand Down Expand Up @@ -66,6 +67,31 @@ public function __construct(
*/
public function send(Event $event): Result
{
$request = new Request();
$request->setStringBody($this->payloadSerializer->serialize($event));

$spotlight = $this->options->getSpotlight();
if ($spotlight || \is_string($spotlight)) {
try {
$spotLightResponse = SpotlightClient::sendRequest(
$request,
\is_string($spotlight) ? $spotlight : 'http://localhost:8969/stream'
);

if ($spotLightResponse->hasError()) {
$this->logger->info(
sprintf('Failed to send the event to Sentry. Reason: "%s".', $spotLightResponse->getError()),
['event' => $event]
);
}
} catch (\Throwable $exception) {
$this->logger->info(
sprintf('Failed to send the event to Spotlight. Reason: "%s".', $exception->getMessage()),
['exception' => $exception, 'event' => $event]
);
}
}

if ($this->options->getDsn() === null) {
return new Result(ResultStatus::skipped(), $event);
}
Expand All @@ -80,9 +106,6 @@ public function send(Event $event): Result
return new Result(ResultStatus::rateLimit());
}

$request = new Request();
$request->setStringBody($this->payloadSerializer->serialize($event));

try {
$response = $this->httpClient->sendRequest($request, $this->options);
} catch (\Throwable $exception) {
Expand Down

0 comments on commit 1dfa5d3

Please sign in to comment.