Skip to main content

Observability

Coverage is not uniform across the four apps. Do not assume a signal exists just because it exists somewhere. The matrix below is the important part of this page.

Coverage matrix

Console has the widest blast radius — it can delete an organisation and put the whole platform into maintenance — and the least instrumentation.

Pipelines

The three datasets

The security logger is created with protectAll = true (apps/webapp/lib/axiom/server.ts:110) — a different redaction posture from the general logger. Worker dataset names are set in the Fly config: cona_temporal-workers and cona_temporal-activity, with _staging suffixes in staging.

Security events

proxy.ts emits to the security dataset at four points: Logs are flushed through flushAllLoggers(event) in a finally block so a thrown handler cannot lose them.

@cona/observability

The shared core, with a colocated test for every module:

Sampling

Deterministic, controlled by two environment variables (sampling.ts:3-4):
  • CONA_LOG_SAMPLING_ENABLED
  • CONA_LOG_SAMPLING_RULES — a map of rule name to rate
Being deterministic rather than random means the same request either always samples in or always samples out, so a traced request stays complete.

OpenTelemetry

@cona/opentelemetry wraps setup and holds the only @prisma/* import in the repository — @prisma/instrumentation at src/dependencies.ts:10. Workers export metrics straight to Axiom OTLP: worker.ts:377-378 notes OTLP export is best-effort: the telemetry package absorbs exporter failures so observability can never block shutdown. Worker-side OTel wiring lives in telemetry.ts, temporal-opentelemetry.ts, and temporal-metrics.ts.

Notes

Staging runs a failure probe. OBSERVABILITY_PROBE_ENABLED = 1 in staging, 0 in production, driving observabilityFailureProbeWorkflow. Browser logs take a detour. The client cannot write to Axiom directly, so api/axiom/ingest forwards them. Portal has its own copy of this route. Runtime context is split by environment. server-runtime-context.ts and browser-runtime-context.ts in webapp, worker-runtime-context.ts in workers, all feeding @cona/observability’s runtime-context.ts. Error classification is deliberate. lib/axiom/request-error-classification.ts decides which request failures are worth reporting — expected 4xx responses do not become alerts.