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.
Feature | Description |
---|---|
Traceability | Integrates with OpenTelemetry and sets trace/span IDs |
Auth Context | Carries user identity (AuthContext), tenant ID, etc. |
Metadata | Holds structured metadata ($span->set('key', 'value')) |
Timings | Captures startAt, duration.ms, and latency tracking |
Protocol Awareness | Knows what kind of interaction is happening (http, ws, rpc, etc.) |
Logging | Emits structured logs enriched with tracing + context data |
Forkable | Use $span->fork() to create child spans for background jobs or detached flows |
Async-Safe | Fully independent of PHP’s thread or request-local context |
Lifecycle Management | Automatically 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.
$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:
$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
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')