A backend system that ingests logs, processes them asynchronously, and detects incidents in real time.
⸻
1. A client sends a log to the ingestion API
2. The ingestion API validates and publishes the log to RabbitMQ
3. The processor worker consumes the message
4. The worker:
* stores the log in Postgres
* updates Redis counters
* runs incident detection logic
5. If a rule is triggered → an incident is created/updated
6. The query API allows fetching logs and incidents
Client → ingestion-api → RabbitMQ → processor-worker → Postgres
Client → query-api → Postgres
Worker → Redis (ephemeral detection state)
⸻
* ingestion-api
* Accepts logs via HTTP
* Publishes messages to RabbitMQ
* processor-worker
* Consumes messages
* Stores logs in Postgres
* Runs incident detection
* query-api
* Fetch logs with filters
* Fetch incidents
* Manage incident lifecycle (ack/resolve)
* Postgres → durable storage
* Redis → counters + short-lived state
* RabbitMQ → async queue
⸻
* Accept structured logs via HTTP
* Async processing (non-blocking ingestion)
* service_name
* level
* time range
* Pagination (limit/offset)
* Detect error spikes per service
* Uses Redis counters with time buckets
* List incidents
* Acknowledge incidents
* Resolve incidents
⸻
* Docker
* Docker Compose
docker compose up --build
* ingestion-api → http://localhost:8080
* query-api → http://localhost:8081
* RabbitMQ UI → http://localhost:15672 (guest/guest)
⸻
⸻
POST /api/v1/logs
curl -X POST http://localhost:8080/api/v1/logs \
-H "Content-Type: application/json" \
-d '{
"source": "payment-service",
"service_name": "payments",
"environment": "dev",
"level": "ERROR",
"message": "database timeout",
"timestamp": "2026-03-25T12:00:00Z",
"metadata": {
"user_id": "123",
"route": "/charge"
}
}
{
"status": "accepted",
"log_id": "uuid"
}
⸻
GET /api/v1/logs
curl http://localhost:8081/api/v1/logs
curl "http://localhost:8081/api/v1/logs?service_name=payments"
curl "http://localhost:8081/api/v1/logs?level=ERROR"
curl "http://localhost:8081/api/v1/logs?start=2026-03-25T12:00:00Z&end=2026-03-25T13:00:00Z"
curl "http://localhost:8081/api/v1/logs?service_name=payments&level=ERROR&limit=10"
⸻
GET /api/v1/logs/{id}
curl http://localhost:8081/api/v1/logs/<LOG_ID>
⸻
GET /api/v1/incidents
curl http://localhost:8081/api/v1/incidents
curl "http://localhost:8081/api/v1/incidents?status=open"
curl "http://localhost:8081/api/v1/incidents?service_name=payments"
⸻
GET /api/v1/incidents/{id}
curl http://localhost:8081/api/v1/incidents/<INCIDENT_ID>
⸻
POST /api/v1/incidents/{id}/ack
curl -X POST http://localhost:8081/api/v1/incidents/<ID>/ack
⸻
POST /api/v1/incidents/{id}/resolve
curl -X POST http://localhost:8081/api/v1/incidents/<ID>/resolve
⸻
* async processing with queues
* distributed system design
* incident detection logic
* service separation and scalability
⸻
License
MIT