VOOZH about

URL: https://deepwiki.com/hypervel/sentry/2.1-service-provider

⇱ Service Provider | hypervel/sentry | DeepWiki


Loading...
Menu

Service Provider

Purpose and Scope

The SentryServiceProvider is the central orchestrator for the Hypervel Sentry integration. It manages the complete lifecycle of the Sentry SDK within the Hypervel framework, from initial dependency injection setup through runtime monitoring. This page documents the service provider's two-phase initialization process, its dependency injection bindings, feature management system, and critical coroutine context propagation mechanism.

For information about how individual features work, see Feature System Overview. For details about the Hub and factory classes, see Hub and Factories.

Overview

The SentryServiceProvider extends Hypervel's base ServiceProvider class and serves as the integration point between the Hypervel framework and the Sentry SDK. It has the highest importance score (14.68) in the codebase, reflecting its critical role in coordinating all Sentry functionality.

The provider operates in two distinct phases:

  1. Registration Phase: Establishes dependency injection bindings and registers features without executing any framework-dependent code
  2. Boot Phase: Activates features, registers event listeners, and sets up coroutine context propagation after all framework services are available

Diagram: Service Provider in System Context


Sources: src/SentryServiceProvider.php1-143

Lifecycle Phases

Registration Phase

The registration phase occurs when the Hypervel application loads the service provider. During this phase, the provider must only set up dependency injection bindings without executing any code that depends on framework services being fully initialized.

Diagram: Registration Phase Execution Flow


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

Transport Customization

The first operation in the registration phase is customizing the Sentry SDK's HTTP transport layer. The provider calls $this->app->extend(ClientBuilder::class) to modify the ClientBuilder before it creates any clients src/SentryServiceProvider.php65-75

The extension replaces the default HTTP transport with HttpPoolTransport, which uses a Pool instance for efficient HTTP connection reuse. The pool is configured with three parameters:

  1. $builder->getOptions() - Sentry SDK options
  2. $this->app - The DI container instance
  3. $this->app->get(ConfigInterface::class)->get('pools.sentry', []) - Pool-specific configuration

This design allows connection pooling behavior to be customized via the pools.sentry configuration key.

Key Implementation Details:

AspectImplementation
MethodContainer::extend(ClientBuilder::class)
Transport ClassHypervel\Sentry\Transport\HttpPoolTransport
Pool ClassHypervel\Sentry\Transport\Pool
Configuration Sourceconfig('pools.sentry')
PurposeEnable HTTP connection pooling for performance

Sources: src/SentryServiceProvider.php65-75

Core Bindings

After transport customization, the provider establishes dependency injection bindings for Sentry SDK interfaces. These bindings enable framework-wide access to Sentry functionality via dependency injection:

Dependency Injection Bindings

InterfaceImplementationResolution Strategy
ClientInterfaceInline factoryResolves ClientBuilder, calls getClient()
ClientBuilderClientBuilderFactoryFactory creates configured builder
HubInterfaceHubFactoryFactory creates Hub with client
HttpClientInterfaceHttpClientFactoryFactory creates HTTP client

The binding of ClientInterface src/SentryServiceProvider.php77-81 is notable because it uses an inline factory closure rather than a dedicated factory class. This closure resolves the ClientBuilder from the container and immediately calls getClient() to produce a configured Sentry client.

Sources: src/SentryServiceProvider.php77-86

Feature Registration

The final step in the registration phase is discovering and registering features. The provider reads the list of enabled features from config('sentry.features') and processes them in two loops:

Loop 1: Container Binding src/SentryServiceProvider.php112-115

Each feature class is bound to itself in the container via $this->app->bind($feature, $feature). This self-binding pattern enables the container to resolve feature instances.

Loop 2: Feature Registration src/SentryServiceProvider.php117-126

After binding, the provider resolves each feature instance via $this->app->get($feature) and calls its register() method. This allows features to set up their own container bindings and prepare for booting. The entire operation is wrapped in a try-catch block that silently catches any Throwable, ensuring that a failing feature doesn't prevent the application from starting.

Sources: src/SentryServiceProvider.php110-127

Boot Phase

The boot phase executes after all service providers have completed their registration phase and the framework is fully initialized. The provider can now safely interact with framework services.

Diagram: Boot Phase Execution Flow


Sources: src/SentryServiceProvider.php29-44 src/SentryServiceProvider.php129-142

Feature Booting

The bootFeatures() method src/SentryServiceProvider.php129-142 follows the same pattern as feature registration but calls each feature's boot() method instead. During booting, features:

  • Register event listeners with the framework's event dispatcher
  • Add macros to framework classes (e.g., sentryMonitor on scheduled tasks)
  • Set up any runtime monitoring hooks

Like registration, each feature is wrapped in a try-catch to ensure fault isolation.

Sources: src/SentryServiceProvider.php129-142

Command Registration

The provider registers two console commands for diagnostics and testing:

CommandClassPurpose
sentry:aboutAboutCommandDisplay Sentry integration information
sentry:testTestCommandSend test events to verify Sentry connectivity

These commands are registered via commands() src/SentryServiceProvider.php102-108 making them available to the Hypervel CLI.

Sources: src/SentryServiceProvider.php102-108

Configuration Publishing

The registerPublishing() method src/SentryServiceProvider.php92-97 makes the package's configuration file publishable to the application's config directory:

publishes([
 __DIR__ . '/../config/sentry.php' => config_path('sentry.php'),
], 'sentry-config');

Users can publish the configuration with:

php bin/hyperf.php vendor:publish hypervel/sentry

Sources: src/SentryServiceProvider.php92-97

Coroutine Context Propagation

The most critical aspect of the boot phase is setting up coroutine context propagation src/SentryServiceProvider.php36-43 Hypervel applications run in a coroutine environment where each HTTP request or background job may spawn multiple child coroutines. Without explicit propagation, Sentry context (current span, scope, breadcrumbs) would be lost when crossing coroutine boundaries.

The provider registers a callback with Coroutine::afterCreated() that executes immediately after each new coroutine is created src/SentryServiceProvider.php36-43:

Context Propagation Mechanism:

StepMethod CallPurpose
1Coroutine::parentId()Gets the parent coroutine's ID
2Context::get($key, $default, $parentId)Retrieves value from parent coroutine's context
3Context::set($key, $parentValue)Copies value to child coroutine's context
4Key: Hub::CONTEXT_STACK_KEYContains the Sentry scope stack

The callback iterates over a predefined set of keys (currently only Hub::CONTEXT_STACK_KEY) and copies each key's value from the parent coroutine to the child coroutine. This ensures that when a child coroutine starts, it inherits its parent's Sentry scope stack, maintaining trace continuity and proper scope isolation across concurrent operations.

Sources: src/SentryServiceProvider.php36-43

Provider Configuration

The getProviderConfig() static method src/SentryServiceProvider.php46-61 returns configuration that the Hypervel framework uses to set up AOP (Aspect-Oriented Programming) and class mapping:

Diagram: Provider Configuration Structure


Configuration Elements:

KeyValuePurpose
aspects[0]GuzzleHttpClientAspect::classIntercepts Guzzle HTTP client calls for tracing
aspects[1]CoroutineAspect::classIntercepts coroutine operations for context management
annotations.scan.class_mapSentrySdk::class => class_map/SentrySdk.phpOverrides Sentry SDK's static SentrySdk class with coroutine-aware version

The class map override is particularly important: it replaces the Sentry SDK's global static Hub instance with a version that uses Hypervel's coroutine-aware context storage, ensuring proper isolation between concurrent requests.

Sources: src/SentryServiceProvider.php46-61

Summary

The SentryServiceProvider orchestrates the entire Sentry integration lifecycle through:

  1. Transport Optimization: Replacing default HTTP transport with connection-pooled HttpPoolTransport
  2. Dependency Injection: Binding Sentry interfaces to factory implementations
  3. Feature Management: Discovering, registering, and booting modular monitoring features
  4. AOP Integration: Registering aspects for transparent coroutine and HTTP tracing
  5. Coroutine Safety: Propagating Sentry context across coroutine boundaries
  6. Developer Tools: Providing CLI commands and publishable configuration

The two-phase lifecycle (register → boot) ensures proper initialization ordering, while the try-catch protection around feature operations ensures fault isolation. The provider's design enables the rest of the integration to function correctly in Hypervel's coroutine-based architecture.

Sources: src/SentryServiceProvider.php1-143