Skip to content
Why did we open-source our inference engine? Read the post

Monitoring & Observability

SIE exposes monitoring across the control plane and worker pods. Inside each Kubernetes worker pod, the SIE server sidecar owns queue health; the Python sie-server adapter owns model execution. Use health endpoints for orchestration. Application metrics leave each process once over OTLP, then the bundled OpenTelemetry Collector routes them to Prometheus and Grafana, with optional fan-out to a remote observability backend. WebSocket streams provide interactive status.

SIE exposes Kubernetes-compatible health probes for liveness and readiness checks. In Docker, the Python sie-server process owns these endpoints. In Kubernetes, the gateway, config service, and both containers inside each worker pod have their own health contract.

Component/healthz/readyz
sie-gatewayProcess liveness, returns okProcess readiness. It does not wait for SIE server sidecar health or sie-config
SIE server sidecar (worker-sidecar container)Process livenessFresh IPC Ping to the in-pod Python process and no active drain
sie-serverPython process livenessAdapter process ready to receive work
sie-configConfig process livenessRegistry initialized and able to serve config endpoints
curl http://localhost:8080/healthz
# Returns: ok

Use /healthz for Kubernetes liveness probes. A failed check triggers container restart.

curl http://localhost:8080/readyz
# Returns: ok

Use /readyz for Kubernetes readiness probes. On the gateway, readiness means the process can accept traffic and return 503 PROVISIONING for cold-start capacity; worker-pod availability is exposed through /health, inference responses, and metrics.

Kubernetes configuration:

livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /readyz
port: 8080
initialDelaySeconds: 5
periodSeconds: 5

SIE services emit canonical OpenTelemetry metrics once over OTLP. Application containers do not expose a Prometheus /metrics endpoint. The bundled OpenTelemetry Collector receives OTLP and exposes Prometheus-compatible metrics on port 9464. It can also fan out the same observations to a remote OTLP backend.

Canonical OpenTelemetry names use dots. The collector owns the underscore-form Prometheus compatibility names used by PromQL, Grafana, alerts, and KEDA. The checked-in telemetry contract defines the full inventory, attributes, histogram boundaries, and export eligibility.

Canonical OpenTelemetry namePrometheus wire nameTypeDescription
sie.gateway.requestssie_gateway_requests_totalCounterGateway inference responses by operation, outcome, HTTP status, and machine profile
sie.gateway.request.durationsie_gateway_request_duration_secondsHistogramEnd-to-end gateway request latency
sie.gateway.lane.queue.depthsie_gateway_lane_queue_depthGaugeExact JetStream pending and delivered-but-unacknowledged work by physical lane
sie.gateway.lane.queue.snapshot.timestampsie_gateway_lane_queue_snapshot_timestamp_secondsGaugeFreshness companion for exact-lane queue depth
sie.worker.requestssie_worker_requests_totalCounterCompleted worker items by operation, outcome, backend, lane, model, and profile
sie.worker.request.durationsie_worker_request_duration_secondsHistogramPer-item worker latency
sie.worker.batch.sizesie_worker_batch_sizeHistogramItems in each formed batch
sie.worker.queue.depthsie_worker_queue_depthGaugeCurrent worker queue depth
sie.worker.model.loadedsie_worker_model_loadedGaugeCurrent model residency
sie.worker.model.memorysie_worker_model_memory_bytesGaugeModel memory reported by the active backend

The bundled kube-prometheus-stack installs Prometheus, Grafana, Alertmanager, and the Prometheus Operator. Enabling it also creates the collector, its ServiceMonitor, the SIE alert rules, and dashboard ConfigMaps:

helm upgrade --install sie oci://ghcr.io/superlinked/charts/sie-cluster \
--version 0.6.26 \
--namespace sie \
--create-namespace \
--set kube-prometheus-stack.install=true

With an existing Prometheus Operator, set serviceMonitor.enabled=true instead. If Prometheus runs outside the SIE namespace, add its namespace to observability.otel.collector.prometheus.networkPolicy.scrapeNamespaceNames.

Scrape the collector, not the gateway or workers. For a release named sie in namespace sie, the static equivalent of the chart-managed ServiceMonitor is:

# prometheus.yml
scrape_configs:
- job_name: 'sie-otel-collector'
static_configs:
- targets: ['sie-sie-cluster-otel-collector.sie.svc:9464']
metrics_path: /metrics
scrape_interval: 5s

For live status without the Grafana stack, SIE has two built-in surfaces:

  • WebSocket stream: the Python sie-server process streams real-time server, GPU, and model status over /ws/status (see WebSocket Status below).
  • Gateway health polling: poll the gateway /health endpoint for aggregate cluster status (worker count, GPUs, loaded models).

The Python sie-server process streams real-time status over WebSocket at /ws/status. Updates push every 200ms. In Kubernetes, the gateway also exposes /ws/cluster-status for aggregate cluster status, while routing health comes from SIE server sidecar NATS heartbeats.

import asyncio
import websockets
import json
async def monitor():
async with websockets.connect("ws://localhost:8080/ws/status") as ws:
async for message in ws:
status = json.loads(message)
print(f"Loaded models: {status['loaded_models']}")
print(f"GPU type: {status['gpu']}")
{
"timestamp": 1703001234.567,
"gpu": "l4",
"loaded_models": ["bge-m3", "e5-base-v2"],
"server": {
"version": "0.1.0",
"uptime_seconds": 3600,
"user": "sie",
"working_dir": "/app",
"pid": 1
},
"gpus": [
{
"device": "cuda:0",
"name": "NVIDIA L4",
"gpu_type": "l4",
"utilization_pct": 45,
"memory_used_bytes": 8589934592,
"memory_total_bytes": 23622320128,
"memory_threshold_pct": 95
}
],
"models": [
{
"name": "bge-m3",
"state": "loaded",
"device": "cuda:0",
"memory_bytes": 2147483648,
"queue_depth": 0,
"queue_pending_items": 0,
"config": {
"hf_id": "BAAI/bge-m3",
"adapter": "bge_m3",
"inputs": ["text"],
"outputs": ["dense", "sparse"]
}
}
],
"counters": {},
"histograms": {}
}
StateDescription
availableConfig loaded, weights not in memory
loadingWeights currently loading to GPU
loadedReady for inference
unloadingWeights being evicted from GPU
failedLast load attempt failed; config still present

SIE includes pre-built Grafana dashboards in the Helm chart at deploy/helm/sie-cluster/files/dashboards/. Grafana’s sidecar provisions them automatically. The collector can route the same OTLP observations to a remote backend without changing application instrumentation.

These example PromQL queries use the collector’s compatibility names and pin a release named sie in namespace sie. Change namespace and collector service for your release; keep endpoint="prometheus".

sum by (operation) (
rate(sie_gateway_requests_total{
namespace="sie",
service="sie-sie-cluster-otel-collector",
endpoint="prometheus",
producer_service="sie-gateway",
outcome="success"
}[5m])
)
histogram_quantile(0.99,
sum by (le, operation) (
rate(sie_gateway_request_duration_seconds_bucket{
namespace="sie",
service="sie-sie-cluster-otel-collector",
endpoint="prometheus",
producer_service="sie-gateway"
}[5m])
)
)
max by (model, profile, backend, lane) (
sie_worker_model_memory_bytes{
namespace="sie",
service="sie-sie-cluster-otel-collector",
endpoint="prometheus",
producer_service="sie-worker"
}
)
max by (pool, machine_profile, bundle) (
sie_gateway_lane_queue_depth{
namespace="sie",
service="sie-sie-cluster-otel-collector",
endpoint="prometheus",
producer_service="sie-gateway"
}
and on (producer_instance, collector_generation, pool, machine_profile, bundle)
(
abs(time() - sie_gateway_lane_queue_snapshot_timestamp_seconds{
namespace="sie",
service="sie-sie-cluster-otel-collector",
endpoint="prometheus",
producer_service="sie-gateway"
}) < 20
)
)
avg by (model, profile) (
sie_worker_batch_fill_ratio{
namespace="sie",
service="sie-sie-cluster-otel-collector",
endpoint="prometheus",
producer_service=~"sie-worker|sie-worker-sidecar"
}
)

The sie-cluster chart can render pre-configured Prometheus alert rules:

AlertSeverityConditionDescription
SIEWorkerDowncriticalSIE server sidecar container not ready for 2 minA worker pod is unavailable
SIENoHealthyWorkerscriticalNo ready SIE server sidecar containers for 1 minAll worker pods are unavailable
SIEWorkerHighQueueDepthwarningFresh lane queue depth > 50 for 5 minThe physical lane may need more capacity
SIEGPUMemoryHighwarningGPU memory > 90% for 5 minRisk of OOM, LRU eviction may be insufficient
SIEGPUTemperatureHighwarningGPU temp > 80°C for 5 minGPU throttling likely, check cooling
SIEGPUECCErrorscriticalDouble-bit ECC errors increase over 1hHardware issue likely
SIEGatewayDowncriticalNo ready gateway containers for 1 minTraffic cannot be routed
SIEHighErrorRatewarningGateway 5xx rate > 5% for 5 minServer or model errors spiking
SIEHighLatencywarningp95 latency > 5s for 5 minRequest latency is above target
SIEGenerationServerErrorSpikewarningGeneration 5xx rate > 0.02 req/s for 5 minGeneration failures are increasing on a machine profile
SIEModelLoadingRetrySpikeinfoModel-load errors or timeouts > 0.05/s for 10 minWorkers are repeatedly failing to load a model
SIEResourceExhaustedSpikeinfoTerminal OOM recovery > 0.1/s for 10 minWorker capacity is constrained
SIEConfigDowncriticalConfig container not ready for 2 minConfig writes are blocked; gateways serve cached state
SIEProvisioningStuckwarningPod Pending for 10 minCheck scheduling events and GPU capacity
SIEScaleUpFailedwarningFailedScheduling event in 10 minLikely insufficient GPU capacity

The bundled kube-prometheus-stack command above installs the alert rules automatically. With an existing Prometheus Operator, enable them explicitly:

helm upgrade --install sie oci://ghcr.io/superlinked/charts/sie-cluster \
--version 0.6.26 \
--namespace sie \
-f helm-values.yaml \
--set alertRules.enabled=true

Add custom alerts to your Prometheus configuration:

# Alert when P99 latency exceeds 5 seconds
- alert: SIEHighLatencyP99
expr: |
histogram_quantile(0.99,
sum by (le, operation) (
rate(sie_gateway_request_duration_seconds_bucket{
namespace="sie",
service="sie-sie-cluster-otel-collector",
endpoint="prometheus",
producer_service="sie-gateway"
}[5m])
)
) > 5
for: 5m
labels:
severity: warning
annotations:
summary: "High P99 latency for {{ $labels.operation }}"

SIE supports both human-readable and structured JSON logging.

Enable verbose logging with --verbose or -v:

sie-server serve --verbose

Enable JSON format for Loki and log aggregation systems:

sie-server serve --json-logs

Or via environment variable:

export SIE_LOG_JSON=true
sie-server serve
{
"timestamp": "2025-12-18T10:30:00.123Z",
"level": "INFO",
"logger": "sie_server.api.encode",
"message": "Inference completed",
"model": "bge-m3",
"request_id": "abc123",
"trace_id": "def456",
"latency_ms": 45.2,
"batch_size": 16,
"gpu_type": "l4"
}

JSON logs include optional fields when available:

FieldDescription
modelModel name for the request
request_idUnique request identifier
trace_idOpenTelemetry trace ID
latency_msRequest latency in milliseconds
batch_sizeNumber of items in the batch
gpu_typeDetected GPU type

Contact us

Tell us about your use case and we'll get back to you shortly.