Skip to main content

Incident Classification

LogClaw uses a signal-based composite scoring system to classify whether an error log should trigger an incident. Not every error log is incident-worthy — the system distinguishes actionable production failures (OOM, database deadlocks, cascading failures) from expected noise (validation errors, 404s, client mistakes).

Why Not Simple Error Counting?

A plain error-rate spike detector has three critical failure modes: The signal-based system solves all three.

Three-Stage Pipeline

Every error log record flows through three stages inside the Bridge’s anomaly detector (Thread 2):

Stage 1: Signal Extraction

Eight language-agnostic pattern groups scan the combined text of exception_type, exception_message, and message. A single record can match multiple patterns simultaneously (multi-signal). Key property: patterns are regex-based and language-agnostic. Java, Python, Go, Node.js, Rust — any runtime’s exceptions are classified without hardcoded language-specific rules. Unknown exception types are still scored via severity level, HTTP status, and stacktrace depth.

Additional signals extracted per record


Stage 2: Scoring

Composite Score Formula

Signals are grouped into six categories. The maximum weight within each category is taken (no double-counting), then multiplied by the category’s weight: Score → Severity: Events below compositeScoreThreshold (default 0.4) are not emitted.

Contextual signals (windowed)

Three additional signals are computed from the sliding window (last 300 seconds, 10-second buckets): Blast Radius — how many services are simultaneously erroring per tenant: Velocity — error acceleration vs. historical average: Recurrence — novelty boost for error templates never seen before:

Z-score (fixed)

The z-score is preserved as a statistical signal but is no longer the sole decision maker:
  • z ≥ threshold → zscore:spike = min(z / 5.0, 1.0) (contributes to 25% statistical bucket)
  • std = 0 (constant error rate) → no longer silently dropped:
    • mean ≥ 50% error rate → zscore:sustained_failure signal (sustained production failure)
    • mean ≥ 10% error rate → zscore:elevated_baseline signal

Stage 3: Decision Engine

Two detection paths operate in parallel:

Immediate Path

Fires without waiting for a time window when critical signals are present. Used for failures that can kill a process before 30 seconds elapse. Triggers when any of the following are true:
  • pattern:oom, pattern:crash, or pattern:resource matches with weight ≥ 0.80
  • Log level is FATAL or CRITICAL and any pattern matches with weight ≥ 0.50
  • Blast radius ≥ 0.60 (3+ services simultaneously failing)
Critical immediate patterns (oom, crash, resource) guarantee a minimum composite score of 0.65 (high severity) regardless of missing statistical context — ensuring they always exceed the ticketing agent’s default threshold. Rate-limited to one emission per (tenant, service, dominant_pattern) per immediateDeduplicationSeconds (default 60s) to prevent alert storms.

Windowed Path

Standard path using the sliding window. Fires when composite score ≥ threshold after statistical signals are available (minimum 3 buckets = 30 seconds of data).

Example Scores

* Minimum score enforced for critical immediate patterns.

Anomaly Event Schema

When an incident signal fires, the Bridge or Flink Anomaly Scorer emits an event to the anomaly-events Kafka topic. The full contract is defined in schemas/anomaly-event.v1.schema.json.

Required fields

Signal detection metadata

Every anomaly event includes two fields that describe how and why the detection fired: detection_mode — Which detection path triggered: signal_weights — Breakdown of individual signal contributions to the composite score:

Example: Windowed detection (Bridge z-score)


Detection Reliability

The signal-based approach achieves 99.8% incident detection for critical production failures. Unlike pure bucket-based detection, the multi-layer architecture ensures incidents are not missed due to timing, window boundaries, or pod restarts.

Detection rates by incident type

Why incidents are not missed

The system uses three independent detection layers that operate in parallel. A failure caught by any layer triggers an incident:
  1. Pattern-based — Fires immediately (< 100ms) on known failure signatures. No time window required. Catches OOM, crashes, timeouts, auth failures, deadlocks regardless of bucket timing.
  2. Severity-based — Every FATAL log (+0.5) and every ERROR log (+0.4) contributes to the composite score. A single FATAL + pattern match always exceeds the threshold.
  3. Statistical (z-score) — Detects rate changes, baseline shifts, and cascading failures that patterns alone may miss. Adaptive baseline learning prevents false negatives from sustained elevated error rates.
Additionally, the Ticketing Agent applies 3-layer deduplication that doubles as a safety net:
  • Layer 1: In-memory registry (< 1ms lookup)
  • Layer 2: Dedup key tracker (cross-window)
  • Layer 3: OpenSearch persistence query (survives pod restarts)
If an anomaly somehow bypasses all detection layers on the first occurrence, it is guaranteed to be caught on recurrence via the OpenSearch persistence layer.

Response times


Configuration

Environment Variables

Runtime Config (PATCH /config)

All thresholds can be adjusted without restarting:

Metrics


Image Naming Convention

All LogClaw service images follow the pattern:
Note: Older images published as ghcr.io/logclaw/bridge and ghcr.io/logclaw/ticketing-agent (without the logclaw- prefix) are legacy. New builds should always use the logclaw-{servicename} prefix.