VOOZH about

URL: https://deepwiki.com/hypervel/telescope/2.4.1-guzzle-http-client-aspect

⇱ Guzzle HTTP Client Aspect | hypervel/telescope | DeepWiki


Loading...
Last indexed: 7 February 2026 (146f77)
Menu

Guzzle HTTP Client Aspect

Purpose and Scope

The GuzzleHttpClientAspect class uses Hyperf's AOP system to intercept calls to GuzzleHttp\Client::transfer(), enabling transparent monitoring of outgoing HTTP requests. The aspect injects a callback into Guzzle's on_stats option and delegates all data extraction to HttpClientWatcher.

This is one of two HTTP client monitoring implementations in Telescope. See HTTP Client Watchers for comparison between HttpClientWatcher (Guzzle-specific, AOP-based) and ClientRequestWatcher (generic HTTP client monitoring). For the general watcher pattern, see Watcher Overview and Base Pattern.

AOP Architecture

The aspect uses Hyperf's AOP system to intercept method calls at runtime. The GuzzleHttpClientAspect class defines a single interception target and delegates all processing to the injected HttpClientWatcher instance.


Sources: src/Aspects/GuzzleHttpClientAspect.php1-29

Aspect Registration

The aspect declares its interception target via the $classes property:

PropertyValuePurpose
$classes[Client::class . '::transfer']Intercepts GuzzleHttp\Client::transfer()

The transfer() method is Guzzle's internal method that executes HTTP requests through the handler stack. Intercepting at this level captures all requests regardless of the public method used (get(), post(), request(), etc.).

Sources: src/Aspects/GuzzleHttpClientAspect.php14-16

Delegation Pattern

The process() method implements minimal delegation, immediately passing the ProceedingJoinPoint to HttpClientWatcher::recordRequest():


Sources: src/Aspects/GuzzleHttpClientAspect.php23-27 src/Watchers/HttpClientWatcher.php35-83

HttpClientWatcher Integration

Recording Checks

HttpClientWatcher::recordRequest() performs multiple checks before injecting monitoring:

CheckConfiguration SourcePurpose
$this->options['enabled']config('telescope.watchers.client_request.enabled')Watcher enabled flag
Telescope::$startedTelescope::start()Global initialization state
Telescope::isRecording()Context: SHOULD_RECORDRuntime recording control
$options['telescope_enabled']Request options arrayPer-request opt-out
$guzzleConfig['telescope_enabled']Guzzle client config propertyPer-client opt-out

If any check fails, the method calls $proceedingJoinPoint->process() immediately, bypassing monitoring overhead.

Sources: src/Watchers/HttpClientWatcher.php37-51

Callback Injection Strategy

The watcher injects a callback into Guzzle's on_stats option rather than wrapping request execution. This callback executes after request completion, providing access to request/response data without blocking execution.

Callback Injection Mechanism


Closure Binding for Configuration Access: The watcher uses closure binding to access Guzzle's private $config property:


This avoids reflection while enabling client-level configuration checks.

Sources: src/Watchers/HttpClientWatcher.php44 src/Watchers/HttpClientWatcher.php54-82

Data Extraction Pipeline

Request Data Extraction

HttpClientWatcher::getRequest() extracts data from PSR-7 RequestInterface and TransferStats:





































FieldSourceProcessing
method$request->getMethod()Direct extraction
uri(string) $request->getUri()Cast to string
headers$request->getHeaders()Normalized via headers() method
payload$request->getBody()Extracted via getRequestPayload()
duration$stats->getTransferTime()Converted to milliseconds (floor)

Sources: src/Watchers/HttpClientWatcher.php85-94

Request Payload Extraction

HttpClientWatcher::getRequestPayload() extracts request bodies with size limiting and JSON decoding:


Size Limiting: Default 64 KB (configurable via request_size_limit). Oversized bodies are truncated with " (truncated...)" suffix.

JSON Decoding: Valid JSON arrays trigger parameter hiding via Telescope::$hiddenResponseParameters (naming is historical; applies to both request and response payloads).

Error Handling: Exceptions return "Purged By Telescope: {message}", preventing monitoring failures from breaking requests.

Stream Management: Streams are rewound before and after reading (if isSeekable() returns true), preserving original request state.

Sources: src/Watchers/HttpClientWatcher.php99-128

Response Data Extraction

HttpClientWatcher::getResponse() extracts response metadata:

FieldSourceProcessing
response_status$response->getStatusCode()Direct extraction
response_headers$response->getHeaders()Direct extraction (no normalization)
response$response->getBody()Delegated to getResponsePayload()

Sources: src/Watchers/HttpClientWatcher.php130-137

Response Payload Extraction

HttpClientWatcher::getResponsePayload() handles multiple response content types:


Content Type Handling:

  • JSON arrays: Decoded with parameter hiding via Telescope::$hiddenResponseParameters
  • text/plain: Returned verbatim
  • 3xx redirects: Returns "Redirected to {Location}"
  • Empty body: Returns "Empty Response"
  • Other: Returns "HTML Response"

Size Limiting: Default 64 KB (configurable via response_size_limit), matching request limit behavior.

Sources: src/Watchers/HttpClientWatcher.php139-181

Privacy and Security Controls

Header Normalization

HttpClientWatcher::headers() normalizes header names and applies privacy filtering:


Normalization Process:

  1. Convert header names to lowercase via array_map()
  2. Join multi-value headers with ", " separator
  3. Combine keys and values via array_combine()
  4. Apply Telescope::$hiddenRequestHeaders filtering

Sources: src/Watchers/HttpClientWatcher.php186-202

Parameter Hiding

HttpClientWatcher::hideParameters() redacts sensitive data:

Parameter SourceApplied ToPurpose
Telescope::$hiddenRequestHeadersRequest headersRedact sensitive headers (e.g., Authorization)
Telescope::$hiddenResponseParametersRequest/response payloadsRedact sensitive body parameters

The method uses Arr::get() and Arr::set() for dot-notation key support:


Supports nested paths like "user.password" for deep redaction.

Sources: src/Watchers/HttpClientWatcher.php207-216

Configuration Options

HttpClientWatcher supports multi-level configuration:

Configuration Hierarchy

















































Configuration LevelOptionTypeDefaultDescription
GlobalenabledbooleanfalseWatcher enable flag
Globalrequest_size_limitinteger64Request body size limit (KB)
Globalresponse_size_limitinteger64Response body size limit (KB)
Clienttelescope_enabledbooleannullPer-client opt-out
Requesttelescope_enabledbooleannullPer-request opt-out

Per-Client Opt-Out Example:


Per-Request Opt-Out Example:


Sources: src/Watchers/HttpClientWatcher.php37-51 src/Watchers/HttpClientWatcher.php107 src/Watchers/HttpClientWatcher.php149

Error Handling and Reliability

Multi-layer error handling ensures monitoring failures never break HTTP requests:

Callback-Level Exception Catching

The on_stats callback wraps all extraction logic in try-catch:


Sources: src/Watchers/HttpClientWatcher.php56-75

Stream Reading Error Handling

getRequestPayload() and getResponsePayload() implement try-catch-finally for stream operations:


Guarantees:

  1. Stream errors don't propagate to application
  2. Streams always rewound (if seekable)
  3. Diagnostic messages returned on failure

Sources: src/Watchers/HttpClientWatcher.php101-128 src/Watchers/HttpClientWatcher.php148-178

Entry Recording

After data extraction, the watcher creates an IncomingEntry and records via Telescope::recordClientRequest():


Automatic Tagging: Entries are tagged with request hostname via $request->getUri()->getHost(), enabling destination-based filtering in the UI.

Entry Type: Telescope::recordClientRequest() assigns type "client_request" for storage categorization.

Sources: src/Watchers/HttpClientWatcher.php69-72

Registration Pattern

HttpClientWatcher implements an empty register() method:


Monitoring occurs entirely through GuzzleHttpClientAspect. The watcher functions as a service for the aspect rather than an event listener.

Sources: src/Watchers/HttpClientWatcher.php26-30

Summary

The Guzzle HTTP Client Aspect demonstrates Telescope's hybrid monitoring approach:

ComponentRoleMechanism
GuzzleHttpClientAspectInterceptionHyperf AOP
HttpClientWatcherData extractionService delegation
on_stats callbackTimingGuzzle's native hook
Telescope::recordClientRequest()StorageTelescope core

This architecture provides transparent HTTP client monitoring without requiring application code changes, while maintaining configurability at global, client, and request levels. The multi-layer error handling ensures monitoring reliability never compromises application functionality.

Sources: src/Aspects/GuzzleHttpClientAspect.php1-29 src/Watchers/HttpClientWatcher.php1-220