Skip to content

Observability ​

Metrics and logs for an MSSP running SocTalk. Two consumers in mind: capacity-planning dashboards and per-tenant cost dashboards.

Prometheus endpoint ​

GET /metrics on the soctalk-system-api Service exposes the install's metrics in Prometheus exposition format. Unauthenticated by design; scope it via NetworkPolicy or an Ingress with auth-basic/IP allowlist if you don't want it world-readable.

V1 instrumentation status ​

The metrics catalog below describes the defined metric surface (in src/soctalk/core/observability/metrics.py). In V1 only soctalk_tenant_adapter_heartbeat_age_seconds is visibly updated by code (in the adapter heartbeat handler). The other metrics are defined but not yet instrumented at call sites: they will export as zero/empty. Treat the table as the design target until the runtime hooks land.

Per-tenant counters (defined surface) ​

All labeled with tenant_id. Cardinality is bounded by the number of tenants in the install.

MetricTypeMeaningV1 instrumented?
soctalk_tenant_events_ingested_totalcounterAlerts received from the tenant's Wazuh adapternot yet
soctalk_tenant_investigations_opened_totalcounterInvestigations openednot yet
soctalk_tenant_investigations_closed_total{disposition}counterClosed by dispositionnot yet
soctalk_tenant_pending_reviewsgaugeReviews waiting on a human gatenot yet
soctalk_tenant_llm_tokens_total{direction}counterLLM tokens in/out, the cost drivernot yet
soctalk_tenant_adapter_heartbeat_age_secondsgaugeSeconds since the adapter's last heartbeatyes (updated by /api/internal/adapter/heartbeat). Auto-degraded transition is not implemented; use this as your own alerting input

Install-level counters (defined surface) ​

MetricTypeMeaningV1 instrumented?
soctalk_install_tenants_total{state}gaugeTenant count by statenot yet
soctalk_api_request_duration_seconds{method,path_template,status}histogramAPI latency by template pathnot yet
soctalk_helm_op_duration_seconds{op,outcome}histogramHelm operation durationsnot yet

path_template would be the FastAPI route template (e.g. /api/mssp/tenants/{id}), so cardinality stays bounded.

Suggested Grafana dashboards ​

MSSP control plane health ​

  • Pod readiness (Wazuh-style: green/yellow/red tiles per Deployment)
  • soctalk_api_request_duration_seconds p50/p95/p99 by path_template
  • soctalk_install_tenants_total stacked by state, at-a-glance fleet health
  • Per-tenant soctalk_tenant_adapter_heartbeat_age_seconds heatmap, spot a degrading customer before they call

Per-tenant cost ​

  • rate(soctalk_tenant_llm_tokens_total[1h]) stacked by tenant, top spenders this hour
  • Daily total tokens × your provider's $/Mtok = cost projection
  • Burn-down vs the per-run token budget (case_runs.tokens_budget, model default 200,000; SOCTALK_CASE_RUN_TOKEN_BUDGET env fallback default 15,000 only applies when the row has no value): how often does a single run blow the budget?

Service-level ​

  • rate(soctalk_tenant_investigations_opened_total[5m]): ingress rate
  • rate(soctalk_tenant_investigations_closed_total{disposition="escalate"}[1h]): escalation rate (this also lives on the Analytics page)
  • soctalk_tenant_pending_reviews: humans behind / ahead of the queue

Logs ​

JSON to stderr by default, via structlog. The API and orchestrator are configurable via:

Env varDefaultEffect
SOCTALK_LOG_LEVELINFODEBUG, INFO, WARNING, ERROR
SOCTALK_LOG_FILEunsetIf set, mirror stderr to file
SOCTALK_LOG_FORMATjsonjson or console (human-readable for dev)

Every log line includes tenant_id and case_id if applicable, so a single SocTalk pod's stderr is splittable by tenant downstream.

Worker pods (per-tenant runs-worker) emit the same shape. Aggregate them in your usual log pipeline (Loki, Elasticsearch, CloudWatch).

Tracing ​

OpenTelemetry instrumentation is not wired in this release. Spans for API request handling, LangGraph node execution, and LLM calls are tracked as a planned feature; today the only "why did this case take 90 seconds" surface is structured logs + the Prometheus histograms above.

Alerting examples ​

PromQL snippets for common alerts:

Tenant degraded too long ​

promql
soctalk_tenant_adapter_heartbeat_age_seconds > 1800

Alert: tenant has been silent for over 30 min. Page on-call.

API errors spike ​

promql
sum by (path_template) (
  rate(soctalk_api_request_duration_seconds_count{status=~"5.."}[5m])
) > 0.5

LLM budget burn ​

promql
sum by (tenant_id) (
  rate(soctalk_tenant_llm_tokens_total[1h])
) > 5000000

Adjust the threshold to your install's expected normal rate. A spike usually means a model is looping on needs_more_info.

What's not in here ​

  • Distributed traces of HIL decisions: humans aren't in OTel traces; the audit log is the source of truth for who decided what.
  • End-to-end SLOs by customer: Analytics does this in the UI; PromQL for them is on the roadmap as canonical dashboards (today they're install-defined).
  • Synthetic monitoring: out of scope for SocTalk itself. Use your usual external probe service against the customer SOC URL.

Released under the Apache 2.0 License.