| 1 |
<?php |
| 2 |
|
| 3 |
declare (strict_types=1); |
| 4 |
namespace WCPOS\Vendor\Sentry; |
| 5 |
|
| 6 |
use WCPOS\Vendor\Psr\Log\LoggerInterface; |
| 7 |
use WCPOS\Vendor\Sentry\Attachment\Attachment; |
| 8 |
use WCPOS\Vendor\Sentry\HttpClient\HttpClientInterface; |
| 9 |
use WCPOS\Vendor\Sentry\Integration\IntegrationInterface; |
| 10 |
use WCPOS\Vendor\Sentry\Integration\OTLPIntegration; |
| 11 |
use WCPOS\Vendor\Sentry\Logs\Logs; |
| 12 |
use WCPOS\Vendor\Sentry\Metrics\Metrics; |
| 13 |
use WCPOS\Vendor\Sentry\Metrics\TraceMetrics; |
| 14 |
use WCPOS\Vendor\Sentry\State\HubInterface; |
| 15 |
use WCPOS\Vendor\Sentry\State\Scope; |
| 16 |
use WCPOS\Vendor\Sentry\Tracing\PropagationContext; |
| 17 |
use WCPOS\Vendor\Sentry\Tracing\SpanContext; |
| 18 |
use WCPOS\Vendor\Sentry\Tracing\Transaction; |
| 19 |
use WCPOS\Vendor\Sentry\Tracing\TransactionContext; |
| 20 |
use WCPOS\Vendor\Sentry\Transport\TransportInterface; |
| 21 |
/** |
| 22 |
* Creates a new Client and Hub which will be set as current. |
| 23 |
* |
| 24 |
* @param array{ |
| 25 |
* attach_metric_code_locations?: bool, |
| 26 |
* attach_stacktrace?: bool, |
| 27 |
* before_breadcrumb?: callable, |
| 28 |
* before_send?: callable, |
| 29 |
* before_send_check_in?: callable, |
| 30 |
* before_send_log?: callable, |
| 31 |
* before_send_transaction?: callable, |
| 32 |
* capture_silenced_errors?: bool, |
| 33 |
* context_lines?: int|null, |
| 34 |
* default_integrations?: bool, |
| 35 |
* dsn?: string|bool|Dsn|null, |
| 36 |
* enable_logs?: bool, |
| 37 |
* enable_metrics?: bool, |
| 38 |
* environment?: string|null, |
| 39 |
* error_types?: int|null, |
| 40 |
* http_client?: HttpClientInterface|null, |
| 41 |
* http_compression?: bool, |
| 42 |
* http_connect_timeout?: int|float, |
| 43 |
* http_proxy?: string|null, |
| 44 |
* http_proxy_authentication?: string|null, |
| 45 |
* http_ssl_verify_peer?: bool, |
| 46 |
* http_timeout?: int|float, |
| 47 |
* http_enable_curl_share_handle?: bool, |
| 48 |
* ignore_exceptions?: array<class-string>, |
| 49 |
* ignore_transactions?: array<string>, |
| 50 |
* in_app_exclude?: array<string>, |
| 51 |
* in_app_include?: array<string>, |
| 52 |
* integrations?: IntegrationInterface[]|callable(IntegrationInterface[]): IntegrationInterface[], |
| 53 |
* logger?: LoggerInterface|null, |
| 54 |
* log_flush_threshold?: int|null, |
| 55 |
* metric_flush_threshold?: int|null, |
| 56 |
* max_breadcrumbs?: int, |
| 57 |
* max_request_body_size?: "none"|"never"|"small"|"medium"|"always", |
| 58 |
* max_value_length?: int, |
| 59 |
* org_id?: int|null, |
| 60 |
* prefixes?: array<string>, |
| 61 |
* profiles_sample_rate?: int|float|null, |
| 62 |
* profiles_sampler?: callable|null, |
| 63 |
* release?: string|null, |
| 64 |
* sample_rate?: float|int, |
| 65 |
* send_attempts?: int, |
| 66 |
* send_default_pii?: bool, |
| 67 |
* server_name?: string, |
| 68 |
* spotlight?: bool, |
| 69 |
* spotlight_url?: string, |
| 70 |
* strict_trace_continuation?: bool, |
| 71 |
* tags?: array<string>, |
| 72 |
* trace_propagation_targets?: array<string>|null, |
| 73 |
* traces_sample_rate?: float|int|null, |
| 74 |
* traces_sampler?: callable|null, |
| 75 |
* transport?: TransportInterface|null, |
| 76 |
* } $options The client options |
| 77 |
*/ |
| 78 |
function init(array $options = []) : void |
| 79 |
{ |
| 80 |
$client = ClientBuilder::create($options)->getClient(); |
| 81 |
SentrySdk::init()->bindClient($client); |
| 82 |
} |
| 83 |
/** |
| 84 |
* Captures a message event and sends it to Sentry. |
| 85 |
* |
| 86 |
* @param string $message The message |
| 87 |
* @param Severity|null $level The severity level of the message |
| 88 |
* @param EventHint|null $hint Object that can contain additional information about the event |
| 89 |
*/ |
| 90 |
function captureMessage(string $message, ?Severity $level = null, ?EventHint $hint = null) : ?EventId |
| 91 |
{ |
| 92 |
return SentrySdk::getCurrentHub()->captureMessage($message, $level, $hint); |
| 93 |
} |
| 94 |
/** |
| 95 |
* Captures an exception event and sends it to Sentry. |
| 96 |
* |
| 97 |
* @param \Throwable $exception The exception |
| 98 |
* @param EventHint|null $hint Object that can contain additional information about the event |
| 99 |
*/ |
| 100 |
function captureException(\Throwable $exception, ?EventHint $hint = null) : ?EventId |
| 101 |
{ |
| 102 |
return SentrySdk::getCurrentHub()->captureException($exception, $hint); |
| 103 |
} |
| 104 |
/** |
| 105 |
* Captures a new event using the provided data. |
| 106 |
* |
| 107 |
* @param Event $event The event being captured |
| 108 |
* @param EventHint|null $hint May contain additional information about the event |
| 109 |
*/ |
| 110 |
function captureEvent(Event $event, ?EventHint $hint = null) : ?EventId |
| 111 |
{ |
| 112 |
return SentrySdk::getCurrentHub()->captureEvent($event, $hint); |
| 113 |
} |
| 114 |
/** |
| 115 |
* Logs the most recent error (obtained with {@see error_get_last()}). |
| 116 |
* |
| 117 |
* @param EventHint|null $hint Object that can contain additional information about the event |
| 118 |
*/ |
| 119 |
function captureLastError(?EventHint $hint = null) : ?EventId |
| 120 |
{ |
| 121 |
return SentrySdk::getCurrentHub()->captureLastError($hint); |
| 122 |
} |
| 123 |
/** |
| 124 |
* Captures a check-in and sends it to Sentry. |
| 125 |
* |
| 126 |
* @param string $slug Identifier of the Monitor |
| 127 |
* @param CheckInStatus $status The status of the check-in |
| 128 |
* @param int|float|null $duration The duration of the check-in |
| 129 |
* @param MonitorConfig|null $monitorConfig Configuration of the Monitor |
| 130 |
* @param string|null $checkInId A check-in ID from the previous check-in |
| 131 |
*/ |
| 132 |
function captureCheckIn(string $slug, CheckInStatus $status, $duration = null, ?MonitorConfig $monitorConfig = null, ?string $checkInId = null) : ?string |
| 133 |
{ |
| 134 |
return SentrySdk::getCurrentHub()->captureCheckIn($slug, $status, $duration, $monitorConfig, $checkInId); |
| 135 |
} |
| 136 |
/** |
| 137 |
* Execute the given callable while wrapping it in a monitor check-in. |
| 138 |
* |
| 139 |
* @param string $slug Identifier of the Monitor |
| 140 |
* @param callable $callback The callable that is going to be monitored |
| 141 |
* @param MonitorConfig|null $monitorConfig Configuration of the Monitor |
| 142 |
* |
| 143 |
* @return mixed |
| 144 |
*/ |
| 145 |
function withMonitor(string $slug, callable $callback, ?MonitorConfig $monitorConfig = null) |
| 146 |
{ |
| 147 |
$checkInId = SentrySdk::getCurrentHub()->captureCheckIn($slug, CheckInStatus::inProgress(), null, $monitorConfig); |
| 148 |
$status = CheckInStatus::ok(); |
| 149 |
$duration = 0; |
| 150 |
try { |
| 151 |
$start = \microtime(\true); |
| 152 |
$result = $callback(); |
| 153 |
$duration = \microtime(\true) - $start; |
| 154 |
return $result; |
| 155 |
} catch (\Throwable $e) { |
| 156 |
$status = CheckInStatus::error(); |
| 157 |
throw $e; |
| 158 |
} finally { |
| 159 |
SentrySdk::getCurrentHub()->captureCheckIn($slug, $status, $duration, $monitorConfig, $checkInId); |
| 160 |
} |
| 161 |
} |
| 162 |
/** |
| 163 |
* Records a new breadcrumb which will be attached to future events. They |
| 164 |
* will be added to subsequent events to provide more context on user's |
| 165 |
* actions prior to an error or crash. |
| 166 |
* |
| 167 |
* @param Breadcrumb|string $category The category of the breadcrumb, can be a Breadcrumb instance as well (in which case the other parameters are ignored) |
| 168 |
* @param string|null $message Breadcrumb message |
| 169 |
* @param array<string, mixed> $metadata Additional information about the breadcrumb |
| 170 |
* @param string $level The error level of the breadcrumb |
| 171 |
* @param string $type The type of the breadcrumb |
| 172 |
* @param float|null $timestamp Optional timestamp of the breadcrumb |
| 173 |
*/ |
| 174 |
function addBreadcrumb($category, ?string $message = null, array $metadata = [], string $level = Breadcrumb::LEVEL_INFO, string $type = Breadcrumb::TYPE_DEFAULT, ?float $timestamp = null) : void |
| 175 |
{ |
| 176 |
SentrySdk::getCurrentHub()->addBreadcrumb($category instanceof Breadcrumb ? $category : new Breadcrumb($level, $type, $category, $message, $metadata, $timestamp)); |
| 177 |
} |
| 178 |
/** |
| 179 |
* Calls the given callback passing to it the current scope so that any |
| 180 |
* operation can be run within its context. |
| 181 |
* |
| 182 |
* @param callable $callback The callback to be executed |
| 183 |
*/ |
| 184 |
function configureScope(callable $callback) : void |
| 185 |
{ |
| 186 |
SentrySdk::getCurrentHub()->configureScope($callback); |
| 187 |
} |
| 188 |
/** |
| 189 |
* Creates a new scope with and executes the given operation within. The scope |
| 190 |
* is automatically removed once the operation finishes or throws. |
| 191 |
* |
| 192 |
* @param callable $callback The callback to be executed |
| 193 |
* |
| 194 |
* @phpstan-template T |
| 195 |
* |
| 196 |
* @phpstan-param callable(Scope): T $callback |
| 197 |
* |
| 198 |
* @return mixed|void The callback's return value, upon successful execution |
| 199 |
* |
| 200 |
* @phpstan-return T |
| 201 |
*/ |
| 202 |
function withScope(callable $callback) |
| 203 |
{ |
| 204 |
return SentrySdk::getCurrentHub()->withScope($callback); |
| 205 |
} |
| 206 |
/** |
| 207 |
* Starts an isolated context for the current logical execution. |
| 208 |
* |
| 209 |
* A provided hub is used as-is, allowing runtimes with their own HubInterface |
| 210 |
* implementation to manage hub isolation. When no hub is provided, the SDK |
| 211 |
* creates an isolated hub from the baseline. |
| 212 |
* |
| 213 |
* If a context is already active, this function is a no-op and the provided hub |
| 214 |
* is ignored. Use SentrySdk::setCurrentHub() to replace the active context's hub. |
| 215 |
* |
| 216 |
* @param HubInterface|null $hub The hub to use for the new context |
| 217 |
*/ |
| 218 |
function startContext(?HubInterface $hub = null) : void |
| 219 |
{ |
| 220 |
SentrySdk::startContext($hub); |
| 221 |
} |
| 222 |
/** |
| 223 |
* Ends and flushes the active context for the current logical execution. |
| 224 |
* |
| 225 |
* When no context is active this is a no-op. |
| 226 |
* |
| 227 |
* @param int|null $timeout The maximum number of seconds to wait while flushing the client transport |
| 228 |
*/ |
| 229 |
function endContext(?int $timeout = null) : void |
| 230 |
{ |
| 231 |
SentrySdk::endContext($timeout); |
| 232 |
} |
| 233 |
/** |
| 234 |
* Executes the given callback within an isolated context. |
| 235 |
* |
| 236 |
* If a context is already active for the current logical execution, it is reused. |
| 237 |
* |
| 238 |
* @param callable $callback The callback to execute |
| 239 |
* @param int|null $timeout The maximum number of seconds to wait while flushing the client transport |
| 240 |
* |
| 241 |
* @phpstan-template T |
| 242 |
* |
| 243 |
* @phpstan-param callable(): T $callback |
| 244 |
* |
| 245 |
* @return mixed |
| 246 |
* |
| 247 |
* @phpstan-return T |
| 248 |
*/ |
| 249 |
function withContext(callable $callback, ?int $timeout = null) |
| 250 |
{ |
| 251 |
return SentrySdk::withContext($callback, $timeout); |
| 252 |
} |
| 253 |
/** |
| 254 |
* Starts a new `Transaction` and returns it. This is the entry point to manual |
| 255 |
* tracing instrumentation. |
| 256 |
* |
| 257 |
* A tree structure can be built by adding child spans to the transaction, and |
| 258 |
* child spans to other spans. To start a new child span within the transaction |
| 259 |
* or any span, call the respective `startChild()` method. |
| 260 |
* |
| 261 |
* Every child span must be finished before the transaction is finished, |
| 262 |
* otherwise the unfinished spans are discarded. |
| 263 |
* |
| 264 |
* The transaction must be finished with a call to its `finish()` method, at |
| 265 |
* which point the transaction with all its finished child spans will be sent to |
| 266 |
* Sentry. |
| 267 |
* |
| 268 |
* @param TransactionContext $context Properties of the new transaction |
| 269 |
* @param array<string, mixed> $customSamplingContext Additional context that will be passed to the {@see Tracing\SamplingContext} |
| 270 |
*/ |
| 271 |
function startTransaction(TransactionContext $context, array $customSamplingContext = []) : Transaction |
| 272 |
{ |
| 273 |
return SentrySdk::getCurrentHub()->startTransaction($context, $customSamplingContext); |
| 274 |
} |
| 275 |
/** |
| 276 |
* Execute the given callable while wrapping it in a span added as a child to the current transaction and active span. |
| 277 |
* If there is no transaction active this is a no-op and the scope passed to the trace callable will be unused. |
| 278 |
* |
| 279 |
* @template T |
| 280 |
* |
| 281 |
* @param callable(Scope): T $trace The callable that is going to be traced |
| 282 |
* @param SpanContext $context The context of the span to be created |
| 283 |
* |
| 284 |
* @return T |
| 285 |
*/ |
| 286 |
function trace(callable $trace, SpanContext $context) |
| 287 |
{ |
| 288 |
return SentrySdk::getCurrentHub()->withScope(static function (Scope $scope) use($context, $trace) { |
| 289 |
$parentSpan = $scope->getSpan(); |
| 290 |
$span = null; |
| 291 |
// If there is a span set on the scope and it's sampled there is an active transaction. |
| 292 |
// If that is the case we create the child span and set it on the scope. |
| 293 |
// Otherwise we only execute the callable without creating a span. |
| 294 |
if ($parentSpan !== null && $parentSpan->getSampled()) { |
| 295 |
$span = $parentSpan->startChild($context); |
| 296 |
$scope->setSpan($span); |
| 297 |
} |
| 298 |
try { |
| 299 |
return $trace($scope); |
| 300 |
} finally { |
| 301 |
if ($span !== null) { |
| 302 |
$span->finish(); |
| 303 |
$scope->setSpan($parentSpan); |
| 304 |
} |
| 305 |
} |
| 306 |
}); |
| 307 |
} |
| 308 |
/** |
| 309 |
* Returns the OTLP traces endpoint configured for the current client. |
| 310 |
*/ |
| 311 |
function getOtlpTracesEndpointUrl() : ?string |
| 312 |
{ |
| 313 |
$hub = SentrySdk::getCurrentHub(); |
| 314 |
$client = $hub->getClient(); |
| 315 |
if ($client === null) { |
| 316 |
return null; |
| 317 |
} |
| 318 |
$integration = $hub->getIntegration(OTLPIntegration::class); |
| 319 |
if ($integration instanceof OTLPIntegration && $integration->getCollectorUrl() !== null) { |
| 320 |
return $integration->getCollectorUrl(); |
| 321 |
} |
| 322 |
$dsn = $client->getOptions()->getDsn(); |
| 323 |
if ($dsn === null) { |
| 324 |
return null; |
| 325 |
} |
| 326 |
return $dsn->getOtlpTracesEndpointUrl(); |
| 327 |
} |
| 328 |
/** |
| 329 |
* Creates the current Sentry traceparent string, to be used as a HTTP header value |
| 330 |
* or HTML meta tag value. |
| 331 |
* This function is context aware, as in it either returns the traceparent based |
| 332 |
* on the current span, or the scope's propagation context. |
| 333 |
*/ |
| 334 |
function getTraceparent() : string |
| 335 |
{ |
| 336 |
$hub = SentrySdk::getCurrentHub(); |
| 337 |
$client = $hub->getClient(); |
| 338 |
if ($client !== null) { |
| 339 |
$options = $client->getOptions(); |
| 340 |
if ($options->isTracingEnabled()) { |
| 341 |
$span = SentrySdk::getCurrentHub()->getSpan(); |
| 342 |
if ($span !== null) { |
| 343 |
return $span->toTraceparent(); |
| 344 |
} |
| 345 |
} |
| 346 |
} |
| 347 |
$traceParent = ''; |
| 348 |
$hub->configureScope(static function (Scope $scope) use(&$traceParent) { |
| 349 |
if ($scope->hasExternalPropagationContext()) { |
| 350 |
return; |
| 351 |
} |
| 352 |
$traceParent = $scope->getPropagationContext()->toTraceparent(); |
| 353 |
}); |
| 354 |
return $traceParent; |
| 355 |
} |
| 356 |
/** |
| 357 |
* Creates the current W3C traceparent string, to be used as a HTTP header value |
| 358 |
* or HTML meta tag value. |
| 359 |
* This function is context aware, as in it either returns the traceparent based |
| 360 |
* on the current span, or the scope's propagation context. |
| 361 |
* |
| 362 |
* @deprecated since version 4.12. To be removed in version 5.0. |
| 363 |
*/ |
| 364 |
function getW3CTraceparent() : string |
| 365 |
{ |
| 366 |
return ''; |
| 367 |
} |
| 368 |
/** |
| 369 |
* Creates the baggage content string, to be used as a HTTP header value |
| 370 |
* or HTML meta tag value. |
| 371 |
* This function is context aware, as in it either returns the baggage based |
| 372 |
* on the current span or the scope's propagation context. |
| 373 |
*/ |
| 374 |
function getBaggage() : string |
| 375 |
{ |
| 376 |
$hub = SentrySdk::getCurrentHub(); |
| 377 |
$client = $hub->getClient(); |
| 378 |
if ($client !== null) { |
| 379 |
$options = $client->getOptions(); |
| 380 |
if ($options->isTracingEnabled()) { |
| 381 |
$span = SentrySdk::getCurrentHub()->getSpan(); |
| 382 |
if ($span !== null) { |
| 383 |
return $span->toBaggage(); |
| 384 |
} |
| 385 |
} |
| 386 |
} |
| 387 |
$baggage = ''; |
| 388 |
$hub->configureScope(static function (Scope $scope) use(&$baggage) { |
| 389 |
if ($scope->hasExternalPropagationContext()) { |
| 390 |
return; |
| 391 |
} |
| 392 |
$baggage = $scope->getPropagationContext()->toBaggage(); |
| 393 |
}); |
| 394 |
return $baggage; |
| 395 |
} |
| 396 |
/** |
| 397 |
* Continue a trace based on HTTP header values. |
| 398 |
* If the SDK is configured with enabled tracing, |
| 399 |
* this function returns a populated TransactionContext. |
| 400 |
* In any other cases, it populates the propagation context on the scope. |
| 401 |
*/ |
| 402 |
function continueTrace(string $sentryTrace, string $baggage) : TransactionContext |
| 403 |
{ |
| 404 |
// With the new `strict_trace_continuation`, it's possible that we start two new |
| 405 |
// traces if we parse the TransactionContext and PropagationContext from the same |
| 406 |
// headers. To make sure the trace is the same, we will create one transaction |
| 407 |
// context from headers and copy relevant information over. |
| 408 |
$transactionContext = TransactionContext::fromHeaders($sentryTrace, $baggage); |
| 409 |
$propagationContext = PropagationContext::fromDefaults(); |
| 410 |
$metadata = $transactionContext->getMetadata(); |
| 411 |
$traceId = $transactionContext->getTraceId() ?? $propagationContext->getTraceId(); |
| 412 |
$transactionContext->setTraceId($traceId); |
| 413 |
$propagationContext->setTraceId($traceId); |
| 414 |
$propagationContext->setParentSpanId($transactionContext->getParentSpanId()); |
| 415 |
$propagationContext->setSampleRand($metadata->getSampleRand()); |
| 416 |
$dynamicSamplingContext = $metadata->getDynamicSamplingContext(); |
| 417 |
if ($dynamicSamplingContext !== null) { |
| 418 |
$propagationContext->setDynamicSamplingContext($dynamicSamplingContext); |
| 419 |
} |
| 420 |
$hub = SentrySdk::getCurrentHub(); |
| 421 |
$hub->configureScope(static function (Scope $scope) use($propagationContext) : void { |
| 422 |
$scope->setPropagationContext($propagationContext); |
| 423 |
}); |
| 424 |
return $transactionContext; |
| 425 |
} |
| 426 |
/** |
| 427 |
* Get the Sentry Logs client. |
| 428 |
*/ |
| 429 |
function logger() : Logs |
| 430 |
{ |
| 431 |
return Logs::getInstance(); |
| 432 |
} |
| 433 |
/** |
| 434 |
* @deprecated use `traceMetrics` instead |
| 435 |
*/ |
| 436 |
function metrics() : Metrics |
| 437 |
{ |
| 438 |
return Metrics::getInstance(); |
| 439 |
} |
| 440 |
function traceMetrics() : TraceMetrics |
| 441 |
{ |
| 442 |
return TraceMetrics::getInstance(); |
| 443 |
} |
| 444 |
/** |
| 445 |
* @deprecated use `traceMetrics` instead |
| 446 |
*/ |
| 447 |
function trace_metrics() : TraceMetrics |
| 448 |
{ |
| 449 |
return TraceMetrics::getInstance(); |
| 450 |
} |
| 451 |
/** |
| 452 |
* Adds a feature flag evaluation to the current scope. |
| 453 |
* When invoked repeatedly for the same name, the most recent value is used. |
| 454 |
*/ |
| 455 |
function addFeatureFlag(string $name, bool $result) : void |
| 456 |
{ |
| 457 |
SentrySdk::getCurrentHub()->configureScope(static function (Scope $scope) use($name, $result) { |
| 458 |
$scope->addFeatureFlag($name, $result); |
| 459 |
}); |
| 460 |
} |
| 461 |
/** |
| 462 |
* Adds an attachment to the current scope. For large attachments, it might be helpful |
| 463 |
* to use the SDK Sidecar Transport: https://docs.sentry.io/platforms/php/agent/. |
| 464 |
*/ |
| 465 |
function addAttachment(Attachment $attachment) : void |
| 466 |
{ |
| 467 |
SentrySdk::getCurrentHub()->configureScope(static function (Scope $scope) use($attachment) { |
| 468 |
$scope->addAttachment($attachment); |
| 469 |
}); |
| 470 |
} |
| 471 |
/** |
| 472 |
* Flushes all buffered telemetry data. |
| 473 |
* |
| 474 |
* This is a convenience facade that forwards the flush operation to all |
| 475 |
* internally managed components. |
| 476 |
* |
| 477 |
* Calling this method is equivalent to invoking `flush()` on each component |
| 478 |
* individually. It does not change flushing behavior, improve performance, |
| 479 |
* or reduce the number of network requests. |
| 480 |
*/ |
| 481 |
function flush() : void |
| 482 |
{ |
| 483 |
SentrySdk::flush(); |
| 484 |
} |
| 485 |
|