Skip to main content
Observability ships as a set of Effect layers. One call to createSmithersObservabilityLayer installs the logger, the metrics registry, the tracing service, and (when enabled) an OTLP exporter. Metrics are always collected in-process and read back as a Prometheus exposition string; traces and logs are exported over OTLP only when enabled is set.
import {
  createSmithersObservabilityLayer,
  createSmithersRuntimeLayer,
  createSmithersOtelLayer,
  resolveSmithersObservabilityOptions,
  trackSmithersEvent,
  renderPrometheusMetrics,
  prometheusContentType,
  smithersMetrics,
  SmithersObservability,
} from "smithers-orchestrator";
Metric collection is global. renderPrometheusMetrics() and trackSmithersEvent read and write the process-wide Effect registry, so they work whether or not you have built a layer. Building a layer adds logging, tracing, and OTLP export on top.

SmithersObservability

An Effect Context.Tag for the resolved observability service. Provided by createSmithersObservabilityLayer; depend on it to read the resolved options or to open a span without importing withSmithersSpan directly.
import { Effect } from "effect";
import { SmithersObservability } from "smithers-orchestrator";

const program = Effect.gen(function* () {
  const obs = yield* SmithersObservability;
  yield* obs.withSpan("my-step", Effect.log("inside the span"));
});
SmithersObservabilityService
object
The shape behind the tag.
Source SmithersObservability.js · SmithersObservabilityService.ts · Tests observability.test.js · See also Server integration

Layers

createSmithersObservabilityLayer

Builds the full observability layer: logger, MetricsService, TracingService, the SmithersObservability service, and BunContext. The OTLP exporter is folded in only when the resolved options have enabled: true.
function createSmithersObservabilityLayer(
  options?: SmithersObservabilityOptions,
): Layer.Layer<MetricsService | TracingService | SmithersObservability | BunContext>;
options
SmithersObservabilityOptions
Partial options, resolved through resolveSmithersObservabilityOptions. See resolveSmithersObservabilityOptions for fields and defaults.
import { Effect, Layer } from "effect";
import { createSmithersObservabilityLayer } from "smithers-orchestrator";

const layer = createSmithersObservabilityLayer({
  serviceName: "my-control-plane",
  logFormat: "json",
});

await Effect.runPromise(myProgram.pipe(Effect.provide(layer)));

createSmithersRuntimeLayer

Alias of createSmithersObservabilityLayer, exported under the name used by the runtime. Same signature, same return type. Prefer it in runtime/server wiring so the intent reads clearly.
import { createSmithersRuntimeLayer } from "smithers-orchestrator";

const layer = createSmithersRuntimeLayer({ logLevel: "debug" });

createSmithersOtelLayer

The OTLP-export slice on its own. Returns Layer.empty unless enabled resolves to true, so it is safe to merge unconditionally. Use it when you already have a metrics/logging layer and only want to add OpenTelemetry traces.
function createSmithersOtelLayer(
  options?: SmithersObservabilityOptions,
): Layer.Layer<never>;
options
SmithersObservabilityOptions
Same options object. Only enabled, endpoint, and serviceName affect this layer.
import { createSmithersOtelLayer } from "smithers-orchestrator";

// No-op unless SMITHERS_OTEL_ENABLED=1 (or enabled: true).
const otel = createSmithersOtelLayer({
  endpoint: "http://localhost:4318",
  serviceName: "smithers",
});
Source createSmithersObservabilityLayer.js · createSmithersOtelLayer.js · createSmithersRuntimeLayer.js · Tests observability.test.js · See also Agent trace OTel verification

resolveSmithersObservabilityOptions

Merge partial options with environment variables and defaults. The layer factories call this for you; call it directly to inspect what a deployment resolves to.
function resolveSmithersObservabilityOptions(
  options?: SmithersObservabilityOptions,
): ResolvedSmithersObservabilityOptions;
options
SmithersObservabilityOptions
Every field is optional. Unset fields fall back to env vars, then defaults.
ResolvedSmithersObservabilityOptions
object
Every field present and concrete.
import { resolveSmithersObservabilityOptions } from "smithers-orchestrator";

const resolved = resolveSmithersObservabilityOptions({ serviceName: "ci" });
// { enabled: false, endpoint: "http://localhost:4318", serviceName: "ci", ... }
Source resolveSmithersObservabilityOptions.js · ResolvedSmithersObservabilityOptions.ts · Tests observability-options.test.js

trackSmithersEvent

Map a SmithersEvent onto the metric registry. Returns an Effect<void> that increments the relevant counters, updates gauges, and records durations for that event type. Every event also bumps the smithers_events_emitted_total counter. The runtime calls this on each emitted event; call it yourself only when feeding events from outside the engine.
function trackSmithersEvent(event: SmithersEvent): Effect.Effect<void>;
event
SmithersEvent
required
A discriminated union keyed by type. See Event types.
import { Effect } from "effect";
import { trackSmithersEvent } from "smithers-orchestrator";

await Effect.runPromise(
  trackSmithersEvent({
    type: "NodeFinished",
    runId: "RUN_ID",
    nodeId: "NODE_ID",
    iteration: 0,
    attempt: 1,
    timestampMs: Date.now(),
  }),
);
Source trackEvent.js · SmithersEvent.ts · Tests effect-metrics-track.test.js · See also Event types

Prometheus

renderPrometheusMetrics

Render the entire metric registry as a Prometheus exposition string, with # HELP/# TYPE headers and every catalog metric present at zero even before it fires. Refreshes the process gauges (uptime, RSS, heap) on each call. This is what the server’s GET /metrics route returns.
function renderPrometheusMetrics(): string;

prometheusContentType

The exact Content-Type for a Prometheus response: text/plain; version=0.0.4; charset=utf-8. Pair it with the rendered body.
import { renderPrometheusMetrics, prometheusContentType } from "smithers-orchestrator";

// Inside any HTTP handler:
function handleMetrics() {
  return new Response(renderPrometheusMetrics(), {
    headers: { "Content-Type": prometheusContentType },
  });
}
The built-in server already exposes this at GET /metrics. See Server integration. Use these directly only when wiring metrics into your own HTTP layer.
Source renderPrometheusMetrics.js · prometheusContentType.js · Tests observability-prometheus.test.js · See also Server integration

Metrics catalog

smithersMetrics is the registry of every metric, an object keyed by the camelCase names below whose values are the underlying Effect Metrics. Each metric renders under its Prometheus name; histograms also emit _bucket, _sum, and _count series. The table groups the core metrics by area; the registry holds more (gateway, devtools, agent, alert, supervisor families).
import { smithersMetrics } from "smithers-orchestrator";

const everyMetric = Object.values(smithersMetrics); // all Effect Metrics

Runs and nodes

MetricKindMeaning
smithers_runs_totalcounterRuns started
smithers_runs_finished_totalcounterRuns finished
smithers_runs_failed_totalcounterRuns failed
smithers_runs_cancelled_totalcounterRuns cancelled
smithers_runs_resumed_totalcounterRuns resumed
smithers_runs_continued_totalcounterRuns continued-as-new
smithers_nodes_startedcounterNodes started
smithers_nodes_finishedcounterNodes finished
smithers_nodes_failedcounterNodes failed
smithers_node_retries_totalcounterNode retries
smithers_errors_totalcounterErrors
smithers_events_emitted_totalcounterEvents emitted
smithers_runs_activegaugeActive runs
smithers_nodes_activegaugeActive nodes
smithers_scheduler_queue_depthgaugeScheduler queue depth
smithers_scheduler_concurrency_utilizationgaugeScheduler concurrency utilization
smithers_run_duration_mshistogramRun duration
smithers_node_duration_mshistogramNode duration
smithers_attempt_duration_mshistogramPer-attempt duration
smithers_scheduler_wait_duration_mshistogramScheduler wait time
smithers_snapshots_capturedcounterSnapshots captured
smithers_forks_createdcounterRun forks created
smithers_replays_startedcounterReplays started
smithers_snapshot_duration_mshistogramSnapshot duration

Approvals and timers

MetricKindMeaning
smithers_approvals_requestedcounterApprovals requested
smithers_approvals_grantedcounterApprovals granted
smithers_approvals_deniedcounterApprovals denied
smithers_approval_pendinggaugePending approvals
smithers_external_wait_async_pendinggaugePending external waits
smithers_approval_wait_duration_mshistogramApproval wait duration
smithers_timers_createdcounterTimers created
smithers_timers_firedcounterTimers fired
smithers_timers_cancelledcounterTimers cancelled
smithers_timers_pendinggaugePending timers
smithers_timers_delay_mshistogramTimer fire delay

Cache and tokens

MetricKindMeaning
smithers_cache_hitscounterCache hits
smithers_cache_missescounterCache misses
smithers_tokens_input_totalcounterInput tokens
smithers_tokens_output_totalcounterOutput tokens
smithers_tokens_cache_read_totalcounterCache read tokens
smithers_tokens_cache_write_totalcounterCache write tokens
smithers_tokens_reasoning_totalcounterReasoning tokens
smithers_tokens_input_per_callhistogramInput tokens per call
smithers_tokens_output_per_callhistogramOutput tokens per call
smithers_tokens_context_window_per_callhistogramContext window per call

Database

MetricKindMeaning
smithers_db_retriescounterDB retries
smithers_db_transaction_retriescounterDB transaction retries
smithers_db_transaction_rollbackscounterDB transaction rollbacks
smithers_db_query_mshistogramDB query duration
smithers_db_transaction_mshistogramDB transaction duration

HTTP and hot reload

MetricKindMeaning
smithers_http_requestscounterHTTP requests
smithers_http_request_duration_mshistogramHTTP request duration
smithers_hot_reloadscounterHot reloads
smithers_hot_reload_failurescounterHot reload failures
smithers_hot_reload_duration_mshistogramHot reload duration

Tools

MetricKindMeaning
smithers_tool_calls_totalcounterTool calls
smithers_tool_calls_errors_totalcounterTool call errors
smithers_tool_output_truncated_totalcounterTool outputs truncated
smithers_tool_duration_mshistogramTool duration

Sandbox

MetricKindMeaning
smithers_sandbox_created_totalcounterSandboxes created
smithers_sandbox_completed_totalcounterSandboxes completed
smithers_sandbox_activegaugeActive sandboxes
smithers_sandbox_duration_mshistogramSandbox duration
smithers_sandbox_bundle_size_byteshistogramSandbox bundle size
smithers_sandbox_transport_duration_mshistogramSandbox transport duration
smithers_sandbox_patch_counthistogramSandbox patch count

Memory

MetricKindMeaning
smithers_memory_fact_readscounterMemory fact reads
smithers_memory_fact_writescounterMemory fact writes
smithers_memory_recall_queriescounterMemory recall queries
smithers_memory_message_savescounterMemory messages saved
smithers_memory_recall_duration_mshistogramMemory recall duration

OpenAPI tools

MetricKindMeaning
smithers_openapi_tool_callscounterOpenAPI tool calls
smithers_openapi_tool_call_errorscounterOpenAPI tool call errors
smithers_openapi_tool_duration_mshistogramOpenAPI tool duration

VCS and process

MetricKindMeaning
smithers_vcs_duration_mshistogramVCS operation duration
smithers_process_uptime_secondsgaugeProcess uptime
smithers_process_memory_rss_bytesgaugeProcess RSS memory
smithers_process_heap_used_bytesgaugeProcess heap used
Source smithersMetrics.js · metrics · Tests effect-metrics-definitions.test.js · See also Server integration, Event types