docs: refresh architecture references for OTel migration

This commit is contained in:
2026-05-11 12:18:44 +02:00
parent 81f2477537
commit e43e03cdee
8 changed files with 86 additions and 66 deletions

View File

@@ -1170,28 +1170,32 @@ footer .colophon {
<div class="section-num">§ 08</div>
<div>
<h2 class="section-title">Instrumentation <em>symbols</em>.</h2>
<p class="section-blurb">Plan 10 added two new symbols to the per-feature container — <code>TRACER</code> and <code>LOGGER</code> — bound by a separate Rule 0 in <code>bindAll()</code> that's <strong>orthogonal</strong> to the repo binding mode. The DSN env var decides Sentry vs Noop; <code>USE_DEV_SEED</code> / <code>NODE_ENV</code> decide real vs mock repos.</p>
<p class="section-blurb">ADR-014 + ADR-017 added instrumentation symbols to the per-feature container — <code>ITracer</code>, <code>ILogger</code>, and <code>IMetrics</code> — bound by a separate Rule 0 in <code>bindAll()</code> that's <strong>orthogonal</strong> to the repo binding mode. The DSN env var decides OTel+Sentry vs Noop; <code>USE_DEV_SEED</code> / <code>NODE_ENV</code> decide real vs mock repos. <strong>Substrate: OpenTelemetry SDK.</strong> Sentry is the exporter via <code>@sentry/opentelemetry</code>.</p>
</div>
</div>
<div class="instrumentation-grid">
<div>
<h3 class="trace-h3"><code>INSTRUMENTATION_SYMBOLS.TRACER</code></h3>
<p class="trace-p">Bound by either <code>bindNoopInstrumentation</code> or <code>bindSentryInstrumentation</code> to <code>NoopTracer</code> or <code>SentryTracer</code>. Decided by Rule 0: DSN env present → Sentry; otherwise Noop.</p>
<h3 class="trace-h3"><code>INSTRUMENTATION_SYMBOLS.ITracer</code></h3>
<p class="trace-p">Bound by either <code>bindNoopInstrumentation</code> or <code>bindOtelInstrumentation</code> to <code>NoopTracer</code> or <code>OtelTracer</code>. Decided by Rule 0: DSN env present → OTel SDK + Sentry exporter; otherwise Noop. <code>OtelTracer</code> emits via <code>@opentelemetry/api</code>; spans flow to Sentry via <code>SentrySpanProcessor</code>.</p>
<h3 class="trace-h3"><code>INSTRUMENTATION_SYMBOLS.LOGGER</code></h3>
<p class="trace-p">Same rule, same lifecycle. <code>NoopLogger</code> in the absence of a DSN; <code>SentryLogger</code> when DSN is set. The Sentry adapter applies the <code>__sentryReported</code> double-report guard internally — call sites don't manage the flag.</p>
<h3 class="trace-h3"><code>INSTRUMENTATION_SYMBOLS.ILogger</code></h3>
<p class="trace-p">Same rule, same lifecycle. <code>NoopLogger</code> in the absence of a DSN; <code>OtelLogger</code> when DSN is set. <code>OtelLogger</code> emits log records via <code>@opentelemetry/api-logs</code>; errors flow to Sentry via <code>SentryLogRecordProcessor</code>. The <code>__sentryReported</code> double-report guard is applied before emitting.</p>
<h3 class="trace-h3"><code>INSTRUMENTATION_SYMBOLS.IMetrics</code></h3>
<p class="trace-p">Bound to <code>NoopMetrics</code> or <code>OtelMetrics</code>. <code>OtelMetrics</code> uses the OTel metrics API (<code>counter</code>, <code>histogram</code>, <code>gauge</code>). Per-feature adoption is opportunistic — no feature call sites required.</p>
</div>
<div>
<h3 class="trace-h3">Wiring path</h3>
<pre class="trace-tree"><code>bindAll()
└─ resolveInstrumentation() ← Rule 0 (DSN check)
└─ Noop or Sentry binders ← bind to sharedContainer
└─ resolveInstrumentation() ← Rule 0 (DSN check)
└─ bindOtelInstrumentation() ← OTel SDK init + Sentry exporter + PII scrub processors
OR bindNoopInstrumentation() ← all Noop
└─ resolveEventsAndJobs*() ← ADR-015 (env-driven bus + queue)
└─ Payload-backed in prod, in-memory in dev-seed
└─ build ctx: BindProductionContext = { config, tracer, logger, bus, queue, realtime, realtimeRegistry }
└─ required: tracer, logger, config | optional: bus, queue, realtime, realtimeRegistry
└─ build ctx: BindProductionContext = { config, tracer, logger, metrics?, bus, queue, realtime, realtimeRegistry }
└─ required: tracer, logger, config | optional: metrics, bus, queue, realtime, realtimeRegistry
└─ bindProductionX(ctx) ← single ctx object passed to each feature binder
└─ feature container also binds TRACER + LOGGER
└─ withSpan(withCapture(...)) at every use case + controller