Runtime Observability
Nexphant is designed for long-running, stateful environments, making observability and deep introspection critical. The framework provides structured context-aware logging, fine-grained metrics, and trace propagation through the nexphant/observability package.
Structured Context-Aware Logger
The Logger class handles logging. Unlike traditional stateless loggers, the Nexphant Logger automatically merges the active asynchronous execution context (e.g. trace_id, span_id, owner_id, owner_type, worker_id, job_id) into every log entry.
Basic Logging
use Nexphant\Observability\Logger;
$logger = new Logger(STDOUT, 'info', structured: true);
$logger->info('User logged in successfully', ['user_id' => 42]);Automatic Context Merging
When structured is enabled, the logger outputs JSON. If a request is running within a fiber context, the output will automatically include runtime telemetry:
{
"timestamp": 1718224531.023,
"level": "info",
"message": "User logged in successfully",
"context": {
"trace_id": "8f9b2c4d-91a0-47b2-bd73-a602187f581e",
"span_id": "c3a1d4e2",
"owner_id": "req-9988",
"owner_type": "request",
"user_id": 42
}
}Log Levels
Nexphant supports the following levels defined in Logger::LEVELS:
debuginfowarningerrorcritical
Helper Events
The logger provides pre-configured logging methods for framework events:
$logger->queueJob($jobId, $jobName, 'completed');
$logger->workerEvent($workerId, 'started', ['memory' => 12500000]);
$logger->timerEvent($timerId, 'fired');
$logger->channelEvent($channelId, 'closed');Metrics Collection
The Metrics facade maps to the underlying RuntimeMetrics and MetricsCollector classes to record gauges, counters, and histograms:
use Nexphant\Observability\Metrics;
// Increment a counter
Metrics::increment('http_requests_total');
Metrics::increment('database_queries_total', 5);
// Update a gauge
Metrics::gauge('memory_active_bytes', memory_get_usage(true));
// Record a histogram timing
Metrics::histogram('request_duration_ms', 12.4);
// Retrieve a counter or gauge value
$requestCount = Metrics::counter('http_requests_total');
$currentMemory = Metrics::gauge('memory_active_bytes');Tracing Context
Every unit of execution inherits standard tracing identifiers from the RuntimeContext. You can retrieve these manually from the context:
use Nexphant\Runtime\Runtime;
$ctx = Runtime::context();
$traceId = $ctx->traceId(); // Identifies the top-level request or job flow
$spanId = $ctx->spanId(); // Identifies the current sub-operation/fiber segment
$ownerId = $ctx->ownerId(); // UUID of the current execution ownerThese identifiers propagate automatically when you spawn new tasks (Runtime::spawn()) or dispatch jobs.
Live Performance & Fiber Introspection
To check fiber scheduling, resource leaks, and active owners on the event loop, query the RuntimeMetrics singleton:
use Nexphant\Runtime\Runtime;
// Get a snapshot of all metrics collected by the runtime
$snapshot = Runtime::metrics()->snapshot();
print_r($snapshot);Metrics Included in Snapshot:
- Fibers:
active_fibers,suspended_fibers,fibers_running,fibers_completed,fibers_failed,fibers_cancelled. - Resources:
resource_leaks_total,resources_total,resources_leaked(grouped by resource type). - Owners:
owners_alive,owners_total,owners_alive_by_type(grouped by owner type).
