Health API

Piko exposes /live and /ready endpoints on a separate port (default 9090, bound to localhost). Each endpoint aggregates every registered health probe and returns an overall state. This page documents the interfaces and built-in probes. Source of truth: health.go.

Endpoints

EndpointPurposeFailure consequence
/liveIs the application running (not deadlocked)?Orchestrator typically restarts the container.
/readyIs the application ready to serve traffic?Orchestrator typically withholds traffic until ready.

Both run on a separate health HTTP server. The default configuration binds to 127.0.0.1:9090. Expose on 0.0.0.0 for container orchestrators only when necessary, because the health endpoint reveals internal service state.

Interface

HealthProbe

type HealthProbe interface {
    Name() string
    Check(ctx context.Context, checkType HealthCheckType) HealthStatus
}
  • Name() returns the probe's display name (appears in the aggregated output).
  • Check(ctx, checkType) runs the probe. Return quickly for liveness; readiness may do a thorough connection check.

Types

HealthCheckType

ConstantMeaning
HealthCheckLivenessIs the service alive?
HealthCheckReadinessIs the service ready to accept traffic?

HealthState

ConstantMeaning
HealthStateHealthyComponent is working normally.
HealthStateDegradedComponent is working but with reduced performance or limited features.
HealthStateUnhealthyComponent is not working.

HealthStatus

type HealthStatus struct {
    Name         string
    State        HealthState
    Message      string
    Timestamp    time.Time
    Duration     string
    Dependencies []*HealthStatus
}

Dependencies lets a probe report the health of nested sub-components (for example, a database probe that wraps separate replica probes).

Registration

ssr := piko.New(
    piko.WithCustomHealthProbe(&RedisProbe{client: redisClient}),
)

See the bootstrap options reference for TLS options on the health endpoint (WithHealthTLS).

Built-in probes

Piko registers probes for its internal services automatically:

  • RegistryService (artefact storage and metadata)
  • OrchestratorService (task queue and workers)
  • CollectionService (content providers)
  • RenderService (template rendering pipeline)
  • StorageService (file and blob storage)
  • EmailService (email delivery)
  • CryptoService (encryption operations)
  • CacheService (cache backends)

Piko also registers any component that implements LifecycleComponent as a health probe. Its default probe reports the component as healthy for liveness and degraded for readiness, because it did not supply a readiness check. Implement LifecycleHealthProbe for fine-grained readiness.

Response format

A healthy response:

{
  "status": "healthy",
  "probes": [
    { "name": "RegistryService", "state": "healthy", "duration": "2ms" },
    { "name": "ApplicationRedisCache", "state": "healthy", "duration": "1ms" }
  ]
}

Any probe in unhealthy state promotes the overall status to unhealthy and returns HTTP 503.

Configuration

Configure the health probe in func main via With* options:

ssr := piko.New(
    piko.WithHealthEnabled(true),
    piko.WithHealthProbePort(9090),
    piko.WithHealthBindAddress("127.0.0.1"),
    piko.WithHealthLivePath("/live"),
    piko.WithHealthReadyPath("/ready"),
    piko.WithHealthCheckTimeout(5*time.Second),
)

Expose externally only when the orchestrator needs it:

piko.WithHealthBindAddress("0.0.0.0")

See bootstrap options for the full surface.

See also