Endpoints
The Manager serves all of these on
SERVER_ADDRESS. The Worker has no API server, so it runs a health micro-server on HEALTH_PORT, which defaults to 4007.
All of them mount before authentication. Kubernetes and load-balancer probes need no token. /readyz/tenant/:id is mounted on both services; outside multi-tenant mode it returns HTTP 400 stating that multi-tenant mode is disabled.
/health and the startup self-probe
/health is not a static 200. At boot, Fetcher runs every dependency probe once, in parallel, then flips a process-wide flag on the result. Until that self-probe succeeds, /health returns 503.
The kubelet restarts a pod whose dependencies failed at boot. It does not send it traffic. The flag starts false, so a process that crashes mid-probe never reports healthy by accident. Point your liveness probe at
/health./readyz and the dependency probes
/readyz runs every registered probe on every request, in parallel, one goroutine per dependency. The handler holds no cache and no background state. A cached answer opens a window where Kubernetes keeps routing to a degraded pod.
A healthy aggregate returns 200. Anything else returns 503. The response body reports each dependency by name, with its status, its latency, and its TLS posture.
What each service probes
In multi-tenant mode, the shared MongoDB and RabbitMQ entries report
n/a with the reason multi-tenant: see /readyz/tenant/:id, and the per-tenant probes move to that endpoint.
Per-dependency timeouts
Each probe runs under a fixed deadline. The values are not configurable, so every Lerian service has the same readiness latency envelope and one dashboard threshold works across the fleet.
A probe that ignores its deadline does not block the response. The handler substitutes a
down result for it.
Circuit breaker state
Tenant resolution runs behind a circuit breaker. The
MULTI_TENANT_CIRCUIT_BREAKER_THRESHOLD variable sets how many consecutive failures open it, and it defaults to 5. The MULTI_TENANT_CIRCUIT_BREAKER_TIMEOUT_SEC variable sets how long it stays open, and it defaults to 30 seconds.
The global tenant_manager check confirms client wiring only. During tenant validation, an open Tenant Manager breaker returns 503. After validation, a tenant-scoped MongoDB or RabbitMQ check can report down, circuit breaker open, and breaker_state: open. That distinguishes a tripped breaker from an ordinary connection failure.
Drain on SIGTERM
On
SIGTERM or SIGINT, both services enter a drain before they tear down connections.
/readyzshort-circuits to 503 forREADYZ_DRAIN_DELAY_SECseconds, which defaults to 12 and has a minimum of 1.- Kubernetes removes the pod from Service endpoints while it still serves in-flight work.
- Only then do connections close.
draining with status down, and it emits metrics like any other.
Alerts keep rating through a rolling deploy. The synthetic
draining dependency keeps the metric series alive, so a dashboard shows a drain rather than a gap. Set your termination grace period above the drain window.Metrics
/metrics serves Prometheus exposition, including the Go runtime and process collectors.
The histogram buckets run from 1 ms to 5,000 ms. Metric names, labels, and buckets are a platform contract, and dashboards across the fleet depend on them.
The duration histogram records the wall-clock time the probe contributed to the handler, not the latency the probe reported for itself. That is the number that explains a slow
/readyz.
Tracing
Set
ENABLE_TELEMETRY=true and point OTEL_EXPORTER_OTLP_ENDPOINT at your collector. Fetcher then exports OpenTelemetry traces and metrics over OTLP.
Set the OTEL resource attributes for your deployment: OTEL_RESOURCE_SERVICE_NAME, OTEL_RESOURCE_SERVICE_VERSION, OTEL_RESOURCE_DEPLOYMENT_ENVIRONMENT, and OTEL_LIBRARY_NAME. The shipped examples use fetcher for the Manager and fetcher-worker for the Worker; those values are configurable, not runtime defaults.
The engine emits its own spans through a one-method port. A host that supplies no tracer gets a no-op, and behavior does not change.
What to alert on
/readyz503 outside a deploy window. One dependency name in the response body tells you which.- A rising dead-letter queue. Each message there is a job the Worker could not process. See Deployment.
selfprobe_resultat 0 for any dependency. A pod restarted into a broken dependency.- A tenant-scoped check with
breaker_state: open. An open Tenant Manager breaker can also surface as a 503 during tenant validation; the globaltenant_managercheck itself reports client wiring, not breaker state.
Next steps
Deployment
Dependencies, queues, scaling, and startup checks.
Configuration
Every environment variable, per component.
Security
Keys, signing, encryption at rest, and host validation.
Extraction jobs
Job lifecycle, terminal states, and events.

