VOOZH about

URL: https://deepwiki.com/hypervel/sentry/5.2-aop-aspects

⇱ AOP Aspects | hypervel/sentry | DeepWiki


Loading...
Menu

AOP Aspects

Purpose and Scope

This document describes the Aspect-Oriented Programming (AOP) aspects used in the Sentry integration to intercept and enhance framework operations. Two aspects provide critical cross-cutting concerns:

  1. CoroutineAspect: Manages Sentry context propagation in Hyperf's coroutine environment and captures exceptions that occur within coroutines
  2. GuzzleHttpClientAspect: Automatically records breadcrumbs for outbound HTTP requests made via Guzzle HTTP client

For information about request-level context enrichment, see page 5.1. For broader architectural context about how aspects fit into the system, see page 2.


Overview

The Sentry integration uses AOP aspects to intercept critical framework operations and automatically inject Sentry monitoring capabilities. Aspects are registered in the service provider and automatically applied by Hyperf's dependency injection container.

Registered Aspects

The following aspects are registered with the framework:

Aspect ClassTargetPurpose
CoroutineAspectHyperf\Coroutine\Coroutine::createPropagates Sentry context across coroutine boundaries and captures exceptions
GuzzleHttpClientAspectGuzzleHttp\Client::transferRecords breadcrumbs for outbound HTTP requests with detailed request/response data

Sources: src/SentryServiceProvider.php49-52

Configuration

Enable or disable the coroutine aspect via the configuration file:


When set to false, the aspect is bypassed entirely, and context propagation must be managed manually.

Sources: src/Aspects/CoroutineAspect.php33 </old_str> <new_str>

Configuration

Coroutine Aspect Configuration

Enable or disable the coroutine aspect via the configuration file:


When set to false, the aspect is bypassed entirely, and context propagation must be managed manually.

Sources: src/Aspects/CoroutineAspect.php33


GuzzleHttpClientAspect

The GuzzleHttpClientAspect class intercepts Guzzle HTTP client requests to automatically record breadcrumbs containing detailed information about outbound HTTP calls. This provides visibility into external API interactions and helps diagnose integration issues.

Interception Target

The aspect intercepts the following method:

GuzzleHttp\Client::transfer

This is the core method that executes HTTP transfers in Guzzle, making it the ideal interception point for recording all outbound HTTP requests.

Sources: src/Aspects/GuzzleHttpClientAspect.php21-23

Breadcrumb Recording Mechanism

The aspect wraps Guzzle's on_stats callback to capture transfer statistics after each request completes. The recorded breadcrumb includes comprehensive request and response metadata.

HTTP Request Interception Flow


Sources: src/Aspects/GuzzleHttpClientAspect.php29-89

Captured Data

The aspect captures extensive metadata about each HTTP request:

Request Data

Data FieldDescriptionSource
http.request.methodHTTP method (GET, POST, etc.)$request->getMethod()
http.request.full_urlComplete URL with query string$request->getUri()
http.request.pathURL path component$request->getUri()->getPath()
http.request.schemeProtocol (http/https)$request->getUri()->getScheme()
http.request.hostTarget hostname$request->getUri()->getHost()
http.request.portTarget port$request->getUri()->getPort()
http.request.user_agentUser-Agent header value$request->getHeaderLine('User-Agent')
http.request.headersAll request headers$request->getHeaders()
http.request.body.sizeRequest body size in bytesstrlen($options['body'])

Response Data

Data FieldDescriptionSource
http.response.status_codeHTTP status code$response->getStatusCode()
http.response.reasonStatus reason phrase$response->getReasonPhrase()
http.response.body.sizeResponse body size in bytes$response->getBody()->getSize()
http.response.headersAll response headers$response->getHeaders()
durationTransfer time in milliseconds$stats->getTransferTime() * 1000

Sources: src/Aspects/GuzzleHttpClientAspect.php51-86

Configuration Control

The aspect provides multiple levels of configuration control:

Global Toggle

The aspect respects the guzzle breadcrumb toggle in the Switcher configuration:


Sources: src/Aspects/GuzzleHttpClientAspect.php32-34

Per-Request Opt-Out

Individual requests can opt out of Sentry tracking using the no_sentry_aspect option:


This is useful for:

  • Excluding health check requests to internal services
  • Preventing tracking of requests to Sentry itself (avoiding infinite loops)
  • Skipping high-frequency polling requests that would generate excessive breadcrumbs

Sources: src/Aspects/GuzzleHttpClientAspect.php44-46

Client-Level Configuration

The option can also be set at the client level to exclude all requests from a specific client instance:


Sources: src/Aspects/GuzzleHttpClientAspect.php37-46

Breadcrumb Integration

The aspect uses the Integration::addBreadcrumb() helper to record breadcrumbs with appropriate metadata:


The breadcrumb is created with:

  • Level: Breadcrumb::LEVEL_INFO
  • Type: Breadcrumb::TYPE_DEFAULT
  • Category: "guzzle"
  • Message: The request URI
  • Data: The complete request/response metadata

Sources: src/Aspects/GuzzleHttpClientAspect.php75-81

Original Callback Preservation

The aspect preserves any existing on_stats callback provided by the application code:


This ensures that application-level statistics tracking continues to function alongside Sentry monitoring.

Sources: src/Aspects/GuzzleHttpClientAspect.php48-85

Usage Example

The aspect operates transparently without requiring explicit code changes:


The breadcrumb appears in Sentry with the following structure:

Category: guzzle
Message: https://api.example.com/users
Level: info
Data:
 - http.request.method: POST
 - http.request.full_url: https://api.example.com/users
 - http.response.status_code: 201
 - duration: 145.23 (ms)
 - [additional request/response metadata]

Sources: src/Aspects/GuzzleHttpClientAspect.php29-89

Implementation Details

Class Structure


Sources: src/Aspects/GuzzleHttpClientAspect.php19-28


Aspect Registration

Both aspects are registered in SentryServiceProvider::getProviderConfig() and automatically applied by Hyperf's AOP system:


The order of aspect registration can affect behavior when multiple aspects intercept the same method, though the two Sentry aspects target different methods and do not conflict.

Sources: src/SentryServiceProvider.php46-61


Aspect Registration Flow

The following diagram illustrates how aspects are registered and applied during application bootstrap:


Sources: src/SentryServiceProvider.php46-61


CoroutineAspect

The CoroutineAspect class intercepts coroutine creation to ensure Sentry context is correctly propagated across asynchronous boundaries and exceptions are captured.

Interception Target

The aspect intercepts the following method:

Hyperf\Coroutine\Coroutine::create

This method is called whenever a new coroutine is spawned in the Hyperf framework, making it the ideal interception point for context propagation.

Sources: src/Aspects/CoroutineAspect.php17-19

Context Propagation Mechanism

The aspect propagates specific context keys from the parent coroutine to child coroutines:

Context KeyPurpose
SentrySdk::classMaintains the Sentry Hub instance and current scope across coroutines
Psr\Http\Message\ServerRequestInterface::classPreserves the HTTP request context for request-scoped tracing

Context Propagation Diagram


The implementation reads context from the parent coroutine's context storage and writes it to the child coroutine's context storage before executing the callable:

Sources: src/Aspects/CoroutineAspect.php40-48

Exception Capture

When an exception occurs within a coroutine, the aspect automatically captures it and reports it to Sentry before re-throwing it to preserve normal error handling flow.

Exception Handling Flow


Key behaviors:

  1. Disable duplicate reporting: Calls HypervelCoroutine::enableReportException(false) to prevent Hyperf's default exception handler from also reporting the exception
  2. Capture to Sentry: Sends the exception to the current Hub via captureException()
  3. Preserve original behavior: Re-throws the exception so that application-level error handling continues normally

Sources: src/Aspects/CoroutineAspect.php50-56

Configuration Control

The aspect respects the coroutine feature toggle in the Switcher configuration. When disabled, the aspect performs no interception and allows coroutines to execute normally.


This allows operators to disable coroutine context propagation if needed, for example during debugging or performance testing.

Sources: src/Aspects/CoroutineAspect.php26-35


Implementation Details

Class Structure


Sources: src/Aspects/CoroutineAspect.php15-28

Integration with Service Provider

The service provider complements the aspect's context propagation with an additional mechanism that runs after coroutines are created:


The afterCreated callback in SentryServiceProvider::boot() propagates the Hub's context stack, which contains the scope stack and current span information:

Sources: src/SentryServiceProvider.php36-43 src/Aspects/CoroutineAspect.php21-24

Context Key Constants

The aspect maintains a list of context keys to propagate. These keys are defined as an array property:


This design allows for easy extension if additional context needs to be propagated in the future.

Sources: src/Aspects/CoroutineAspect.php21-24


Usage Example

The aspect operates transparently without requiring explicit code changes. When application code spawns a coroutine:


The aspect automatically:

  1. Propagates the Hub instance to the child coroutine
  2. Propagates the HTTP request context
  3. Captures any exceptions and reports them to Sentry
  4. Re-throws exceptions to preserve normal error handling

Sources: src/Aspects/CoroutineAspect.php30-60


Configuration

Enable or disable the coroutine aspect via the configuration file:


When set to false, the aspect is bypassed entirely, and context propagation must be managed manually.

Sources: src/Aspects/CoroutineAspect.php33