Skip to content

Span Context

A unified, async-friendly, temporal context for your entire request lifecycle.

What is a Span?

In Sugoi, a Span is a temporal context object that spans the full lifecycle of an operation—most commonly, a single request or event. Unlike traditional frameworks that tightly couple context to the thread or request object, Sugoi’s Span is designed to be:

  • Thread-independent
  • Serializable across async jobs
  • Aware of protocol, user, and trace metadata
  • Scoped to the logical unit of work, not just the HTTP request

Why Span?

Modern cloud-native systems are complex. A single logical user interaction might:

  • Start via HTTP
  • Trigger a background job
  • Send a Kafka message
  • Update a database
  • Emit logs and metrics

Features

Each of those steps often runs on different threads, or even different services. Traditional context handling can’t track them all.

Sugoi’s Span solves this by acting as the request envelope, designed to follow your logic—not your infrastructure.

FeatureDescription
TraceabilityIntegrates with OpenTelemetry and sets trace/span IDs
Auth ContextCarries user identity (AuthContext), tenant ID, etc.
MetadataHolds structured metadata ($span->set('key', 'value'))
TimingsCaptures startAt, duration.ms, and latency tracking
Protocol AwarenessKnows what kind of interaction is happening (http, ws, rpc, etc.)
LoggingEmits structured logs enriched with tracing + context data
ForkableUse $span->fork() to create child spans for background jobs or detached flows
Async-SafeFully independent of PHP’s thread or request-local context
Lifecycle ManagementAutomatically ends span on destruction (or use $span->end())

Auth Integration

Setting an authenticated user on the span does more than store a reference. It also triggers protocol-level integrations for stateful requests:

  • Web: Automatically binds the user to the current session
  • WebSocket: Binds the user to the connection ID

This makes it easy to treat async workers like first-class citizens, with full access to auth and tenant context.

php
$span->setAuth(new MyCustomAuthContext('user-id', 'tenant-id'));

For stateless integrations like HTTP APIs and Messaging, the auth context is not bound and will only apply to the span as it is passed around.

Logging & Telemetry

The Span implements PSR-3 LoggerInterface, so you can log directly through it:

php
$span->log('info', 'User created a product', ['product_id' => 123]);

All logs are automatically enriched with:

  • trace id
  • span id
  • user id
  • tenant id
  • protocol
  • start_time
  • custom metadata

Forking for Async

php
Events::emit(new AuditJob($span->fork('job.audit'))); // Pass it anywhere

This maintains a logical hierarchy in your traces, even across service boundaries.

Advanced Usage

  • Access trace ID: $span->getTraceId()
  • Get start time: $span->getStartTime()
  • Add metadata: $span->set('key', 'value')
  • Retrieve metadata: $span->get('key')