OrkStageOrkStage

Observability

Follow an OrkStage installation through JSON logs with correlation ids, health endpoints, deployment events and the audit log. Metrics and tracing are planned.

Logs

The API and the worker write structured JSON logs (Pino) to stdout. Each line carries service and context fields and the correlation id of the request. Tokens, secrets, cookies and authorization headers are redacted. LOG_LEVEL sets the level (info by default).

docker compose --profile platform logs -f api worker

The correlation id starts at the HTTP request (x-correlation-id) and travels into the deployment, the OpenTofu runs, the audit events and the webhook deliveries. Search your log store for it to follow one operation end to end.

Health endpoints

EndpointMeaning
GET /api/v1/healthzLiveness: the API process answers.
GET /api/v1/readyzReadiness: Postgres and Redis are reachable. The Compose health check calls it.

Operational data in the product

  • Deployments: every step with its duration, attempts and failure class, plus the event log and the Gantt timeline.
  • Overview: instances, deployments, failures and incidents, with trends.
  • Audit log: every change, filtered by tenant (GET /audit).
  • Webhook deliveries: status, attempts and the last error of each endpoint.

Metrics and tracing

The API and the worker export OpenTelemetry traces and metrics over OTLP when OTEL_EXPORTER_OTLP_ENDPOINT is set (for example http://otel-collector:4318). Without it, nothing is loaded and nothing is exported. OTEL_EXPORTER_OTLP_HEADERS and the other standard OTEL_* variables work as usual, so a hosted backend (Grafana Cloud, Honeycomb, Datadog) can receive the data directly.

Traces

  • Incoming HTTP requests (the health probes are left out), outgoing fetch calls (provider APIs, webhooks), Redis and Prisma queries.
  • Queue jobs continue the trace of the request that queued them: a deployment shows as one trace from POST /instances/:id/deploy through the worker's job deployments span.
  • Spans carry tenant.id, instance.id, deployment.id and deployment.kind where they apply.

Metrics

MetricUnitAttributes
http.server.request.duration (request count and duration)smethod, status code
orkstage.queue.depthjobsqueue, state
orkstage.job.durationsqueue, outcome
orkstage.job.retriescountqueue
orkstage.deployment.duration (success and failure rates from its outcome)skind, outcome
orkstage.provider.request.durationsprovider, operation, outcome
orkstage.provider.errorscountprovider, operation, failure.class
orkstage.health_check.count (failure rate: share not HEALTHY)countprovider, state
orkstage.incident.openedcountsource
orkstage.incident.time_to_resolve (MTTR)s
orkstage.notification.failurescountchannel

Try it locally

pnpm platform:observe    # the stack plus an OpenTelemetry Collector and Jaeger

Deploy an instance, then open Jaeger at http://localhost:16686 (service orkstage-api) for the trace, and http://localhost:8889/metrics for the metrics in Prometheus format. The collector configuration is otel-collector.yaml in the development workspace.

Service level objectives

Targets for running OrkStage, not guarantees to customers. Each one names the metric that measures it.

ObjectiveTargetMeasured with
API availability99.9% of requests without a 5xxhttp.server.request.duration by status
Control plane read latencyp95 under 300 ms for GEThttp.server.request.duration
Deployment orchestrationover 99% succeed, not counting provider side failuresorkstage.deployment.duration by outcome, with orkstage.provider.errors
Notification deliveryover 99% deliveredorkstage.notification.failures against notifications sent
Status page availabilityat least the API'shttp.server.request.duration for /status

Alert on a burn rate (for example 2% of the monthly error budget in one hour), not on single failures. Until dashboards exist, also alert on readyz, container restarts and deployment.failed webhooks.

On this page