VOOZH about

URL: https://deepwiki.com/hypervel/sentry/2-core-architecture

⇱ Core Architecture | hypervel/sentry | DeepWiki


Loading...
Menu

Core Architecture

Purpose and Scope

This document explains the fundamental architectural components of the Sentry integration package: the service provider that orchestrates initialization, the Hub that serves as the central API for all Sentry operations, and the factory pattern used to create properly configured Sentry clients. This covers the core infrastructure that enables the monitoring features but does not detail specific features themselves.

For information about specific monitoring capabilities (cache, queue, logging, etc.), see Monitoring Features. For details about configuration options and the Switcher system, see Configuration.


System Overview

The core architecture consists of three primary components working together:

ComponentClassRole
Service ProviderSentryServiceProviderOrchestrates initialization, registers DI bindings, boots features, and configures coroutine context propagation
HubHubProvides the central API for capturing events, managing scopes, and creating transactions/spans
FactoriesClientBuilderFactory, HubFactoryCreate properly configured instances of Sentry SDK components using the factory pattern

The service provider follows a two-phase lifecycle: register (binding services to the DI container) and boot (initializing features and runtime behavior). The Hub manages a scope stack stored in coroutine-local context to isolate Sentry data across concurrent operations.

Initialization Flow Diagram


Sources: src/SentryServiceProvider.php63-87 src/SentryServiceProvider.php29-44 src/Factory/HubFactory.php13-16 src/Factory/ClientBuilderFactory.php38-85


Service Provider Registration

The SentryServiceProvider class extends Hypervel\Support\ServiceProvider and serves as the integration point between the Hypervel framework and the Sentry SDK. It implements two lifecycle methods: register() and boot().

Register Phase

During the register() phase src/SentryServiceProvider.php63-87 the service provider:

  1. Extends ClientBuilder to replace the default HTTP transport with HttpPoolTransport src/SentryServiceProvider.php65-75 This optimization uses a connection pool for efficient HTTP communication with Sentry's API.

  2. Binds Core Interfaces to the DI container:

    • ClientInterface → Resolved from ClientBuilder::getClient()
    • ClientBuilderClientBuilderFactory
    • HubInterfaceHubFactory
    • HttpClientInterfaceHttpClientFactory
  3. Registers Features by calling registerFeatures() src/SentryServiceProvider.php110-127 which reads the sentry.features configuration array, binds each feature class to the container, and invokes their register() methods.

Key Registration Code Structure


Sources: src/SentryServiceProvider.php63-87 src/SentryServiceProvider.php110-127

Boot Phase

During the boot() phase src/SentryServiceProvider.php29-44 the service provider:

  1. Boots Features by calling bootFeatures() src/SentryServiceProvider.php129-142 which resolves each feature from the container and invokes their boot() methods. This allows features to register event listeners, add framework macros, and perform other runtime initialization.

  2. Registers Publishing src/SentryServiceProvider.php92-97 to make the configuration file publishable via php bin/hyperf.php vendor:publish.

  3. Registers Console Commands src/SentryServiceProvider.php102-108 including AboutCommand and TestCommand for diagnostics.

  4. Configures Coroutine Context Propagation src/SentryServiceProvider.php36-43 by registering an afterCreated callback that copies the Hub's context stack from parent to child coroutines. This ensures Sentry scopes and spans are properly inherited in async operations.

Coroutine Context Propagation

Context KeyPurposeDefault Value
Hub::CONTEXT_STACK_KEYStores the Layer stack (Client + Scope pairs)null (copied from parent)

The propagation mechanism uses Context::get($key, $default, Coroutine::parentId()) to retrieve the parent coroutine's context and copy it to the child src/SentryServiceProvider.php38-42

Sources: src/SentryServiceProvider.php29-44 src/SentryServiceProvider.php129-142 src/SentryServiceProvider.php92-97 src/SentryServiceProvider.php102-108


Hub Architecture

The Hub class implements Sentry\State\HubInterface and serves as the primary API for all Sentry operations. It manages a stack of layers (Client + Scope pairs) stored in coroutine-local context.

Context Keys

The Hub uses three context keys defined as class constants src/Hub.php33-37:


Sources: src/Hub.php33-37

Scope Management

The Hub provides methods for managing scope isolation:

MethodPurposeImplementation
pushScope()Creates a new layer with a cloned scope on the stacksrc/Hub.php58-69
popScope()Removes the topmost layer from the stacksrc/Hub.php71-82
withScope(callable)Executes a callback with a temporary scope, automatically popping itsrc/Hub.php332-341
configureScope(callable)Modifies the current scope in-placesrc/Hub.php163-166

The scope stack is stored in Context::get(self::CONTEXT_STACK_KEY) and retrieved via getStackTop() src/Hub.php391-400 which initializes the stack with a default layer if it doesn't exist.

Scope Stack Diagram


Sources: src/Hub.php58-82 src/Hub.php332-341 src/Hub.php163-166 src/Hub.php391-400

Event Capture Methods

The Hub provides methods for capturing various types of events:

MethodPurposeReturns
captureMessage(string, ?Severity, ?EventHint)Captures a text message?EventId
captureException(Throwable, ?EventHint)Captures an exception?EventId
captureEvent(Event, ?EventHint)Captures a pre-constructed event?EventId
captureLastError(?EventHint)Captures the last PHP error?EventId
captureCheckIn(...)Captures a cron monitor check-in?string (checkInId)

All capture methods follow the same pattern src/Hub.php84-135:

  1. Retrieve the client via getClient()
  2. If client exists, delegate to the client's capture method, passing the current scope
  3. Store the returned EventId in CONTEXT_LAST_EVENT_ID_KEY
  4. Return the EventId

Event Capture Flow


Sources: src/Hub.php84-135 src/Hub.php346-374

Transaction and Span Management

The Hub manages distributed tracing through transactions and spans:

MethodPurpose
startTransaction(TransactionContext, array)Creates a new transaction with sampling logic
getTransaction()Retrieves the current transaction from scope
setSpan(?Span)Sets the active span on the current scope
getSpan()Retrieves the active span from scope

The startTransaction() method src/Hub.php172-313 implements complex sampling logic:

  1. Creates a Transaction instance
  2. Checks if tracing is enabled
  3. Determines sampling decision based on:
    • Parent sampling decision (propagated via distributed tracing headers)
    • traces_sampler callback if configured
    • Parent sample rate if available
    • traces_sample_rate configuration value
  4. If sampled, initializes the span recorder and optionally starts profiling

Transaction Sampling Decision Tree


Sources: src/Hub.php172-313 src/Hub.php315-330 src/Hub.php320-330

Client Resolution

The getClient() method src/Hub.php43-46 resolves the Sentry client either from the Hub's constructor parameter or by retrieving it from the DI container:

public function getClient(): ?ClientInterface
{
 return $this->client ?? ApplicationContext::getContainer()->get(ClientInterface::class);
}

This lazy resolution pattern allows the Hub to be instantiated before the client is fully configured, which is important during the service provider registration phase.

Sources: src/Hub.php43-46


Factory Pattern

The integration uses the Factory pattern to create properly configured instances of Sentry SDK components. Two primary factories exist:

ClientBuilderFactory

The ClientBuilderFactory src/Factory/ClientBuilderFactory.php24-188 is responsible for creating a configured ClientBuilder instance. Its __invoke() method:

  1. Retrieves User Configuration from config/sentry.php src/Factory/ClientBuilderFactory.php39

  2. Removes Specific Options that are framework-specific and not part of the Sentry SDK configuration src/Factory/ClientBuilderFactory.php26-35:

Removed OptionPurpose
breadcrumbsFeature-specific breadcrumb configuration
cronsConsole scheduling feature configuration
enableFeature toggle
ignore_commandsConsole command filtering
integrationsCustom integration registration
tracingFeature-specific tracing configuration
featuresFeature system configuration
poolHTTP connection pool configuration
  1. Merges with Defaults including framework-specific paths src/Factory/ClientBuilderFactory.php57-63:

    • prefixes: [BASE_PATH] - Sets the project root for stack trace context
    • in_app_exclude: [BASE_PATH . '/vendor'] - Excludes vendor code from in-app frames
    • environment: env('APP_ENV', 'production') - Defaults environment from Laravel/Hypervel convention
  2. Resolves HTTP Client from the container if configured src/Factory/ClientBuilderFactory.php70-75

  3. Creates ClientBuilder and sets SDK identification src/Factory/ClientBuilderFactory.php77-84:

    ClientBuilder::create($options)
     ->setSdkIdentifier(Version::getSdkIdentifier())
     ->setSdkVersion(Version::getSdkVersion())
    
  4. Resolves Integrations by calling resolveIntegrations() src/Factory/ClientBuilderFactory.php87-157

Integration Resolution Process

The resolveIntegrations() method src/Factory/ClientBuilderFactory.php87-157:

  1. Removes default SDK integrations that conflict with the framework:

    • ErrorListenerIntegration - Framework handles errors
    • ExceptionListenerIntegration - Framework handles exceptions
    • FatalErrorListenerIntegration - Framework handles fatal errors
    • RequestIntegration - Replaced with framework-aware version
  2. Replaces RequestIntegration with a version that uses RequestFetcher to resolve requests from the framework context rather than PHP globals src/Factory/ClientBuilderFactory.php136-137

  3. Adds framework-specific integrations src/Factory/ClientBuilderFactory.php140-147:

    • Hypervel\Sentry\Integrations\Integration - Base integration
    • ExceptionContextIntegration - Adds exception context data
    • RequestIntegration - Enriches events with request data
  4. Merges user-provided integrations from configuration src/Factory/ClientBuilderFactory.php95-97

ClientBuilder Configuration Flow


Sources: src/Factory/ClientBuilderFactory.php24-188 src/Factory/ClientBuilderFactory.php87-157

HubFactory

The HubFactory src/Factory/HubFactory.php11-17 is simpler, creating a new Hub instance without any constructor parameters:


The Hub will lazy-load the client via getClient() when needed, resolving it from the container at that time.

Sources: src/Factory/HubFactory.php11-17


Dependency Injection Bindings

The service provider establishes the following bindings in the DI container:

Core Sentry Bindings


Binding Registration Order

The bindings are registered in this specific order src/SentryServiceProvider.php65-86:

  1. Extend ClientBuilder - Replaces transport before factory creates it
  2. Bind ClientInterface - Closure that retrieves ClientBuilder and calls getClient()
  3. Bind ClientBuilder - Maps to ClientBuilderFactory::class
  4. Bind HubInterface - Maps to HubFactory::class
  5. Bind HttpClientInterface - Maps to HttpClientFactory::class
  6. Register Features - Binds each feature class to itself

This order ensures that the transport extension is applied before any client is created, and that all dependencies are available when features are registered.

Sources: src/SentryServiceProvider.php65-86


Transport Optimization

The service provider extends the ClientBuilder class src/SentryServiceProvider.php65-75 to replace the default HTTP transport with HttpPoolTransport, which uses a connection pool for improved performance:


The Pool class manages persistent HTTP connections to Sentry's API, reducing the overhead of establishing new connections for each event. The pool configuration is read from config/pools.sentry and merged with the Sentry options.

Transport Architecture

ComponentPurpose
HttpPoolTransportImplements Sentry\Transport\TransportInterface, delegates to pool
PoolManages connection pool, handles connection reuse and cleanup
Connection Pool ConfigConfigures pool size, timeout, and connection parameters

Sources: src/SentryServiceProvider.php65-75


Configuration Provider Method

The service provider implements a static getProviderConfig() method src/SentryServiceProvider.php46-61 that returns framework-specific configuration:


This configuration registers:

  1. AOP Aspects that intercept framework operations:

    • GuzzleHttpClientAspect - Intercepts HTTP client calls to add tracing
    • CoroutineAspect - Manages Sentry context in coroutine environments
  2. Class Map Override that replaces Sentry\SentrySdk with a framework-compatible version that uses the DI container instead of static state

Sources: src/SentryServiceProvider.php46-61