Skip to content

Monitoring & Observability

Health Endpoints

All health and metrics endpoints are unauthenticated. Gate /metrics at the network level (firewall, security group, or internal-only bind) so it is not reachable from the public internet.

EndpointPurposeAuth
GET /liveLiveness only — no dependency checksNone
GET /readyReadiness with dependency checksNone
GET /healthReadiness (alias for /ready)None
GET /api/v1/readinessReadiness (alias for /ready)None
GET /metricsPrometheus-format metrics (primary scrape target)None (network-gate it)

Liveness

sh
curl http://localhost:8080/live

Returns 200 OK if the HTTP server is running. Use this for container liveness probes — it does not check downstream dependencies, so a wedged database connection will not cause restarts.

Readiness

sh
curl http://localhost:8080/ready

Returns JSON with dependency connectivity (PostgreSQL, Valkey, RabbitMQ). /health and /api/v1/readiness are aliases that return the same response. Use one of these for load balancer health checks and Kubernetes readiness probes.

Metrics

All metrics are exposed in Prometheus format at /metrics (the primary and only metrics endpoint). The endpoint is unauthenticated — restrict access at the network level. Every metric below is exported as a Prometheus gauge (all are expvar.Int under the hood), so counter-style series must be read with rate()/increase() knowing resets happen per process restart.

The catalog is regenerated from the registrations in apps/backend/metrics/*.go: 48 metrics total, including 21 scheduler gauges.

Correlator Metrics

MetricDescription
alga_correlator_alerts_totalAlerts entering correlation
alga_correlator_merged_totalAlerts merged into existing windows
alga_correlator_published_totalInvestigations published after correlation
alga_correlator_dropped_totalAlerts dropped
alga_correlator_window_open_totalNew correlation windows opened
alga_correlator_window_depthCurrently open correlation windows
alga_correlator_flush_totalWindows flushed (expired)
alga_correlator_fail_closed_totalFail-closed events

Scheduler Metrics

MetricDescription
alga_scheduler_pendingPending investigation queue depth
alga_scheduler_scheduled_totalSuccessful investigation binds
alga_scheduler_bind_failed_totalAtomic claim or forward failures
alga_scheduler_no_candidate_totalPending with no eligible agent
alga_scheduler_skip_active_backoff_totalSkips due to per-agent failure backoff
alga_scheduler_tick_duration_msLast tick duration
alga_scheduler_tick_totalTotal scheduler ticks
alga_scheduler_agent_capacity_usedAggregate used capacity
alga_scheduler_agent_capacity_totalAggregate total capacity
alga_scheduler_is_leader1 on leader replica, 0 elsewhere
alga_scheduler_online_agentsAgents currently online (all replicas)
alga_scheduler_nudge_totalScheduler nudge (wake-up) events
alga_scheduler_stale_alerts_sweptUninvestigated alerts found per sweep
alga_scheduler_stale_investigations_createdInvestigations created from stale alerts
alga_scheduler_stale_sweep_tick_totalTotal stale-alert sweep ticks
alga_scheduler_incident_sweep_tick_totalTotal incident sweep ticks
alga_scheduler_summary_sweep_totalIncident-summary sweeps run
alga_scheduler_summary_dispatched_totalSummaries dispatched by the sweep
alga_scheduler_summary_skipped_totalSummary dispatches skipped
alga_scheduler_dispatch_latency_msBind-to-agent-dispatch latency
alga_scheduler_dlq_totalMessages routed to the scheduler DLQ

Webhook Metrics

MetricDescription
alga_webhook_alert_publish_queued_totalWebhook alerts queued for publishing
alga_webhook_alert_publish_sync_fallback_totalWebhook alerts published via sync fallback
alga_webhook_alert_publish_sync_processed_totalWebhook alerts processed synchronously

Escalation / SLA Metrics

MetricDescription
alga_escalations_fired_totalTotal escalations fired
alga_sla_breach_response_totalSLA response time breaches
alga_sla_breach_resolve_totalSLA resolution time breaches
alga_stuck_investigations_escalated_totalStuck investigations escalated
alga_voice_calls_placed_totalVoice escalation calls placed
alga_voice_calls_suppressed_totalVoice escalation calls suppressed

Incident Metrics

MetricDescription
alga_incidents_created_totalTotal incidents created
alga_incidents_activeCurrently active incidents
alga_incidents_resolved_totalTotal incidents resolved
alga_incidents_mitigated_totalTotal incidents mitigated
alga_incidents_closed_totalTotal incidents closed
alga_incidents_cancelled_totalTotal incidents cancelled
alga_incidents_reopened_totalTotal incidents reopened

Worker Metrics

MetricDescription
alga_investigate_worker_create_latency_msInvestigation record creation latency
alga_worker_dlq_totalMessages routed to the worker DLQ

Summary Metrics

MetricDescription
alga_summary_posted_totalIncident summaries posted

Prometheus Integration

Scrape the /metrics endpoint with Prometheus:

yaml
scrape_configs:
  - job_name: "alga"
    static_configs:
      - targets: ["alga:8080"]
    metrics_path: "/metrics"
    scrape_interval: 15s

Grafana Dashboard

Import deploy/grafana/alga-dashboard.json into Grafana for a pre-built monitoring dashboard with panels for:

  • Alert ingestion rate
  • Correlation window activity
  • Scheduler bind rate and latency
  • Agent online count and capacity
  • Investigation lifecycle (pending → complete → failed)
  • SLA breach rate

OpenTelemetry Tracing

Distributed tracing is implemented but off by default — with no tracing configuration Alga installs a no-op tracer provider, so no spans are created or exported and the overhead is effectively zero. Trace export is opt-in: set ALGA_OTEL_ENABLED=true or configure an OTLP endpoint (OTEL_EXPORTER_OTLP_ENDPOINT, or OTEL_EXPORTER_OTLP_TRACES_ENDPOINT for the traces signal specifically) to enable OTLP/HTTP export.

VariableDescription
ALGA_OTEL_ENABLEDSet to true to enable trace export
OTEL_EXPORTER_OTLP_ENDPOINTOTLP collector endpoint (a gRPC :4317 endpoint is rewritten to :4318 for HTTP export)
OTEL_EXPORTER_OTLP_TRACES_ENDPOINTPer-signal override for the traces endpoint
ALGA_OTEL_SAMPLE_RATIOSampling ratio for the ParentBased(TraceIDRatioBased) sampler (0.0–1.0)

Cross-Broker Trace Propagation

Trace context propagates across the RabbitMQ broker boundary using W3C traceparent/tracestate headers injected into AMQP message headers (rabbitmq/trace_carrier.go). This means a trace started at the webhook or API layer continues through correlation, scheduling, and investigation workers as a single distributed trace.

Request ID Correlation

Every HTTP request passes through a request ID middleware that:

  • Reads an incoming X-Request-ID header (or generates one if absent)
  • Echoes it back in the response X-Request-ID header
  • Attaches it to the structured logger context so all log lines for that request share the same ID

Use the request ID to correlate client-side errors with backend log entries.

Logging

Configuration

sh
LOG_LEVEL=info                      # debug, info, warn, error, fatal
LOG_FORMAT=json                     # text (default) or json
LOG_FILE=/var/log/alga/app.log      # Optional file output

The Docker Compose deployment sets LOG_FORMAT=json for structured log ingestion.

Log Levels

LevelUse Case
debugDevelopment, troubleshooting
infoNormal operations (default)
warnRecoverable issues
errorFailures requiring attention
fatalUnrecoverable, process exits

Viewing Logs

sh
# Docker Compose
docker compose logs -f backend

# Direct
LOG_LEVEL=debug ./alga

The log level can also be changed at runtime without a restart via the System Configuration API (PUT /api/v1/system/config with log_level).

Alerting on Alga Itself

Monitor these indicators to detect Alga issues:

IndicatorThresholdAlert
alga_scheduler_bind_failed_total increasing> 0 sustainedAgent dispatch failing
alga_correlator_dropped_total increasing> 0Alerts being dropped
Readiness endpoint returns errorsAnyBackend unhealthy
alga_scheduler_pending growingSustained growthInvestigations backing up
alga_scheduler_no_candidate_total growing> 0No agents online

See Also

Released under the MIT License.