Skip to main content

Overview

This guide covers monitoring and observing a running ISCL Core instance. ISCL produces structured JSON logs via pino (Fastify’s built-in logger), exposes a health endpoint for liveness probes, and writes an append-only audit trail in SQLite that doubles as a source of operational metrics. Together, these three signals give ops engineers full visibility into the transaction pipeline without requiring additional instrumentation.

Structured logging (pino)

Fastify uses pino for structured JSON logging. Every log line is a self-contained JSON object written to stdout. The logger is configured in packages/core/src/api/app.ts:
When the server starts via packages/core/src/main.ts, logger: true is always passed, so production instances emit info-level logs by default.

Log format

Every log entry includes these standard pino fields: Fastify automatically logs every HTTP request and response, attaching the reqId to both entries for correlation.

Example log output

A fatal startup failure (e.g., port already in use) logs at level 60:

Log levels

Configuring log level

  • buildApp({ logger: true }) — info level (default in production)
  • buildApp({ logger: false }) — disabled (used in test suites)
  • Future: ISCL_LOG_LEVEL env var support is planned for v0.2+
To temporarily lower the level for debugging in a non-production environment, modify the Fastify constructor call in app.ts:

Request correlation

Every inbound HTTP request receives a unique reqId (e.g., req-1, req-2). Use this value to correlate the request log with its response log, any intermediate error logs, and downstream RPC calls.
When troubleshooting a failed transaction, search your log aggregator for the reqId to see the full request lifecycle.

Health monitoring

Health endpoint

GET /v1/health returns the current server status:
The response schema enforces additionalProperties: false, so these are the only fields returned. A 200 response with status: "ok" confirms the Fastify server and its registered routes are operational. Additionally, every response includes an X-ISCL-Version header (currently 0.1.0) that external monitors can check without parsing the body.

Monitoring pattern

  • Poll GET /v1/health every 30 seconds from your monitoring system.
  • Alert if: response takes longer than 5 seconds, status is not "ok", or 3+ consecutive failures occur.
For Docker deployments, add a container-level healthcheck:

Environment variables

The server binds to a configurable host and port (from packages/core/src/main.ts):
Ensure your health checks target the correct host and port.

Audit events as observability

The SQLite audit trail (@clavion/audit) records every significant step in the transaction pipeline. These 14 event types serve double duty as observability signals.

Event catalog

Alert-worthy conditions

Set up alerts for these conditions in your monitoring system.

Key metrics

Derive these operational metrics from audit events and HTTP responses:

Deriving metrics from SQLite

Broadcast error rate over the last hour:
Approval latency (average seconds):

Log forwarding

ISCL produces newline-delimited JSON (ndjson) on stdout. This format is natively supported by all major log aggregation systems.
Use Filebeat to ship container logs to Elasticsearch:

Future: Prometheus and OpenTelemetry

Planned for v0.2+. These features are not yet available.
  • Prometheus /metrics endpoint — histograms for request latency by route, counters for transaction types (transfer, swap, approve), gauges for pending approvals.
  • OpenTelemetry trace spans — spans across the full tx pipeline (build, preflight, approve, sign, broadcast) with intentId as the correlation ID.
  • Distributed tracing — propagate trace context from adapter (Domain A) through ISCL Core (Domain B) to RPC nodes, enabling end-to-end latency analysis.
  • Alertmanager integration — fire alerts based on Prometheus rules for broadcast failures, signing denials, and approval TTL expiry.

Next steps