Vortos
Tracing

Modules

TracingModule enum — disable tracing for specific framework modules at compile time. ModuleAwareTracer returns NoOpSpan for disabled modules.

Modules

ModuleAwareTracer sits at the outermost layer of the decorator chain. It reads the vortos.module attribute from startSpan() calls and returns NoOpSpan immediately for disabled modules — the sampling check and inner tracer are never called.

For framework-owned hot paths, Vortos also removes disabled instrumentation at container build time where possible. For example, disabling HTTP tracing removes the HTTP tracing subscriber instead of injecting it and checking a gate on every request.

TracingModule Enum

enum TracingModule: string
{
    case Http          = 'http';
    case Auth          = 'auth';
    case Authorization = 'authorization';
    case Cache         = 'cache';
    case Persistence   = 'persistence';
    case Messaging     = 'messaging';
    case Cqrs          = 'cqrs';
    case RateLimit     = 'rate_limit';
    case Quota         = 'quota';
    case Audit         = 'audit';
}

Disable Modules

config/tracing.php
use Vortos\Tracing\Config\TracingModule;

// Disable one module
$config->disable(TracingModule::Cache);

// Disable multiple
$config->disable(TracingModule::Cache, TracingModule::Auth);

// Re-enable
$config->enable(TracingModule::Cache);

How It Works

Framework components tag their spans with vortos.module:

// Inside CacheRedisAdapter
$span = $this->tracer->startSpan('cache.get', [
    'vortos.module' => TracingModule::Cache,  // ← module tag
    'cache.key'     => $key,
]);

ModuleAwareTracer checks this attribute:

public function startSpan(string $name, array $attributes = []): SpanInterface
{
    $module = $attributes['vortos.module'] ?? null;

    if ($module instanceof TracingModule && $this->isDisabled($module)) {
        return new NoOpSpan(); // ← zero cost, inner never called
    }

    return $this->inner->startSpan($name, $attributes);
}

Spans without a vortos.module attribute always pass through — no module tag means no module filtering applies.

When to Disable Modules

ModuleWhen to DisableWhy
CacheCommon — very noisyCache hits generate many spans; usually not useful in traces
AuthModerateAuth runs on every request; adds noise without insight
RateLimitModerateRate limit checks are fast; spans add noise
QuotaModerateSimilar to rate limit
AuditRarelyAudit has its own separate log — tracing it is redundant
HttpRarelyHTTP spans are often the most useful for debugging
PersistenceNever in prodDB query spans are gold for performance debugging
MessagingNeverConsumer spans are critical for message flow debugging

Blocked traffic

Rate-limited requests, security-blocked requests, and basic 404 responses are intentionally cheap. The request is counted by metrics through http_blocked_total, but expensive trace enrichment is skipped.

This prevents bot scans and abuse traffic from creating high trace volume or vendor cost.

Custom Spans with Module Tags

When writing your own spans, use vortos.module to make them respectable of the disable config:

$span = $this->tracer->startSpan('user.permission.check', [
    'vortos.module' => TracingModule::Authorization,
    'user.id'       => $identity->id(),
    'permission'    => $permission,
]);

Or omit the tag for spans that should always be traced regardless of module config:

// Always traced — no module tag
$span = $this->tracer->startSpan('payment.charge', [
    'payment.id'     => $payment->getId(),
    'payment.amount' => $payment->getAmount(),
]);

On this page