Skip to main content

LogClaw Architecture — End-to-End Data Flow

Overview

LogClaw is an AI-powered observability platform that ingests OTLP logs, detects anomalies using ML-boosted scoring, automatically creates incidents, and dispatches alerts with root cause analysis.

Service Map


Step-by-Step: 10 Logs Through the Pipeline

Step 1: Ingestion (Auth Proxy → OTel Collector)

Customer sends OTLP logs via HTTP POST:
Auth Proxy (Node.js, apps/logclaw-auth-proxy/):
  1. Extracts x-api-key header
  2. Queries PostgreSQL (logclaw_enterprise DB) to validate the key
  3. Looks up the tenant ID associated with that API key
  4. Injects tenant_id as a resource attribute into the OTLP payload
  5. Forwards the modified payload to OTel Collector on port 4318
OTel Collector (charts/logclaw-otel-collector/):
  1. Receives OTLP HTTP on port 4318
  2. Applies batch processor (groups logs for efficiency)
  3. Exports to Kafka topic raw-logs via the kafkaexporter

Step 2: Kafka (Message Bus)

Kafka stores logs in topics with configurable retention:
Each consumer (Flink job or Bridge thread) has its own consumer group with tracked offsets. If a service restarts, it resumes from the last committed offset — no data loss. What it does: Converts the deeply nested OTLP format into a flat, searchable JSON record. Input (from raw-logs topic — nested OTLP):
Output (to enriched-logs topic — flat JSON):
What ETL does (that’s all):
  1. Unwrap the 3-level OTLP nesting → flat record
  2. Generate deterministic log_id (UUID5 from trace+span+timestamp) for OpenSearch idempotency
  3. Normalize severity (CRITICALFATAL)
  4. Flatten attribute keys (service.nameservice_name) — dots cause nested objects in OpenSearch
  5. If unparseable → send to dead-letter-queue
Source: apps/flink-jobs/logclaw-etl/ (Java) or apps/bridge/ Thread 1 (Python) What it does: Reads flat JSON from enriched-logs, queries Feast for ML features, writes back with added fields. Before:
After (4 ML features added):
These features let the Anomaly Scorer make better decisions — “this service already has a 12% error rate and 3 past anomalies.” Source: apps/flink-jobs/logclaw-enrichment/ (Java) or Bridge Thread 1 (Python) Scoring Algorithm:
Example: 10 Logs
Result: 10 logs → 5 anomalies (Logs 6 and 9 only passed because of ML enrichment) Source: apps/flink-jobs/logclaw-anomaly-scorer/ (Java) or Bridge Thread 2 (Python)

Step 6: Bridge Thread 3 (Index + Incidents)

Flink stops at writing to anomaly-events. Bridge Thread 3 picks up:
  1. Index all enriched logslogclaw-logs-{tenant} in OpenSearch
  2. Index anomaly eventslogclaw-anomalies-{tenant} in OpenSearch
  3. Group anomalies by service + 5-min window → if >= 3 → create Incident
Source: apps/bridge/ (Python, also embedded in charts/logclaw-bridge/templates/configmap-app.yaml)

Step 7: Ticketing Agent (Root Cause + Alerts)

Polls OpenSearch for status=open incidents:
Source: apps/ticketing-agent/ (Python, also in configmap)

Airflow, Feast & Redis: The ML Feature Pipeline

Airflow’s sole purpose in LogClaw is to run periodic feature computation DAGs. It does not orchestrate any other services or ETL — that’s Flink/Bridge’s job.

How Features Get Into Redis

The Full Feature Cycle

Why Redis and Not OpenSearch Directly?

  • Redis: Sub-millisecond per key lookup (0.1ms). Perfect for per-log real-time enrichment.
  • OpenSearch: 10-50ms per query. Too slow when enriching thousands of logs per second.
  • Feast is the abstraction layer — defines the feature schema, handles Redis read/write, and provides a clean API for the Flink job to call.

What Airflow Runs

That’s the only DAG. Airflow is intentionally lightweight here — one scheduler pod, one webserver pod, no workers (uses KubernetesExecutor for DAG runs).
Bridge always runs — it handles indexing + incident creation that Flink doesn’t do. When Flink is also enabled, Bridge Threads 1+2 duplicate Flink’s work but output is idempotent (same log_id → OpenSearch overwrites).
Flink is a stream processing engine (not batch like Spring Batch). Jobs run continuously.

Kubernetes & Helm

Chart Structure

How helm upgrade Works

  1. Helm diffs rendered templates vs cluster state
  2. Deployments: Rolling update (new ReplicaSet up, old down, zero downtime)
  3. StatefulSets: Pods updated one at a time (ordered)
  4. ConfigMaps: Updated in-place; pods restart if Deployment has checksum annotation
  5. CRDs (Kafka, OpenSearch): Operator reconciles (Strimzi rolls brokers one by one)
  6. Success: Release revision stored as K8s Secret
  7. Failure: helm rollback logclaw <revision> restores previous state

ConfigMap = Deployment Artifact

For Python services, source code is embedded in ConfigMap:
Both apps/ source AND the configmap must be kept in sync on every change.

Values Per Environment


External Dependencies


Summary: 10 Logs → 1 Email Alert