Skip to main content
Case Studies
Engineering2026-07-20

Pomai Ecosystem - AI-Driven Observability: How I Built a 1M+ Log Analysis Pipeline on a Budget

Quan Van|Architecture Case Study
View Blueprint Repository

AI-Driven Observability: How I Built a 1M+ Log Analysis Pipeline on a Budget

As the Pomai Ecosystem scaled, I hit a threshold that every engineer eventually fears: Log Blindness.

In the beginning, tailing Docker logs was easy. But as the architecture evolved into a distributed network of microservices, the volume of access logs and service events skyrocketed to over a million per day. Every time a user reported an issue, I found myself manually digging through Portainer, scrolling endlessly through rows of text, searching for that one needle in a haystack of terabytes.

I remember a specific incident where a cascade failure occurred. The frontend reported a 500 error, but the root cause wasn't in the API gateway—it was a silent timeout deep within the database layer, which caused the task service to hang, which eventually caused the gateway to drop the connection. By the time I traced the IDs across three different service logs to identify the error, the downtime had already frustrated dozens of users.

I wasn't just losing time; I was losing the battle against my own infrastructure. That was the moment I realized: I didn't need more logs. I didn't even just need structured logs. I needed intelligence to understand them.

The "Million-Log" Problem & The ELK Illusion

The industry-standard answer to this problem is usually the ELK stack (Elasticsearch, Logstash, Kibana) or expensive cloud-managed solutions like Datadog.

While ELK is fantastic for searching, it lacks context. I could search for the word "Error" and get 10,000 results. I could build beautiful Grafana dashboards to show me when CPU spiked, but it couldn't tell me why it spiked. In a microservices environment, a single user request traverses multiple services, hitting Kong Gateway, auth services, and database layers. Without a way to automatically correlate these events semantically, I was still doing the heavy lifting in my head.

I had a strict constraint: I wanted to prove that enterprise-grade observability could be achieved on standard hardware, without relying on costly cloud-managed services. I decided to engineer an autonomous AI-driven logging pipeline using Retrieval-Augmented Generation (RAG).

The Architectural Breakthrough: Why I Chose This Stack

Building a real-time AI pipeline from scratch requires careful selection of tools. Every component was chosen to balance high throughput with minimal resource consumption.

Here is how the pipeline flows and, more importantly, why I designed it this way:

1. High-Throughput Ingestion: Why Kafka?

My first requirement was zero data loss. During a system crash, log volume spikes massively. If I used a simple REST API or a lightweight queue like Redis Pub/Sub, a sudden surge in traffic could overwhelm the logging server, causing me to lose the exact logs I needed to diagnose the crash. I routed all Kong access logs and service events through Apache Kafka. Kafka acts as a highly durable, distributed buffer. It decouples the speed of log generation from the speed of log processing. Even if my AI engine goes down for maintenance, Kafka safely holds the logs on disk until the consumer is ready.

2. Stream Processing: Why Flink over Spark?

Raw logs are noisy. Before feeding them to an AI, they need to be parsed, filtered, and structured. I could have written a simple Node.js consumer, but it wouldn't scale. I evaluated Apache Spark, but Spark uses "micro-batching," which introduces latency. I needed true real-time, event-driven processing, so I chose Apache Flink. Flink processes the Kafka stream instantly, parsing JSON, dropping irrelevant health-check pings, and structuring the raw text into clean metadata before passing it to the database layer.

3. The "CPU-Only" AI Strategy: Why Llama.cpp?

This was my biggest gamble. Everyone assumes AI requires expensive Nvidia GPUs or expensive API calls to OpenAI. I immediately ruled out cloud LLMs (like GPT-4). Sending millions of system logs—which often contain sensitive metadata, user IDs, and internal IP addresses—to a third-party API is a massive data sovereignty and security risk. Furthermore, the API costs for a million logs a day would bankrupt the project. Instead, I proved that local AI is viable by using Llama.cpp. By utilizing heavily quantized open-source models (like Llama-3 8B), I was able to generate vector embeddings and run LLM inference entirely on standard x86 CPUs. It is incredibly efficient, completely private, and costs exactly $0 in cloud fees.

4. The Knowledge Store: Elasticsearch + Qdrant

To make RAG work, the AI needs to retrieve the right logs before generating an answer. As you can see in the early architectural blueprint (Figure 1), I initially explored Milvus for its massive, enterprise-scale vector storage capabilities. However, as I transitioned to the actual deployment on a resource-constrained, self-hosted server, I pivoted to Qdrant. Written in Rust, Qdrant gave me the perfect balance of blistering speed and a microscopic memory footprint. But I didn't rely on Qdrant alone. I paired it with Elasticsearch. Why both? Because semantic search (Qdrant) is great for finding "logs related to database timeouts," but terrible at finding "logs exactly matching user_id: 12345." By using Elasticsearch for strict lexical filtering and Qdrant for semantic similarity, I ensured the LLM was fed highly accurate, hyper-relevant context.

From "Watching Dashboards" to "Asking Questions"

The transformation was profound. Instead of staring at Grafana charts trying to align time-series data, I can now open my terminal and ask the system a natural language question:

"Why did the payment service spike in latency around 2:00 PM?"

In the background, the system:

  1. Translates my question into a vector embedding using CPU.
  2. Queries Qdrant and Elasticsearch to retrieve the top 50 most relevant logs across the Gateway, Payment, and User services.
  3. Feeds those logs into the local LLM as context.

In seconds, it returns a human-readable Root Cause Analysis (RCA):

"The latency spike was caused by a cascading failure. The external banking API timed out (logged in payment-service), which caused Kong Gateway to queue incoming requests, eventually resulting in 502 Bad Gateway errors for the frontend."

When a memory leak recently occurred in one of my Pomaidraw containers, the system didn't just alert me—it highlighted the exact sequence of repetitive events that led to the crash. I diagnosed it in seconds, a process that used to steal my entire evening.

The Lesson: Observability is a Mindset

This project taught me a vital lesson: Engineering is not just about making things work; it is about making systems that understand themselves.

By combining Kafka's durability, Flink's stream processing, and the magic of CPU-bound RAG, I transformed my monitoring stack from a passive recording tool into an active, intelligent partner. I don't just "monitor" the Pomai Ecosystem anymore—I converse with it.

For those of you feeling the pain of "Log Blindness," remember: you don't always need a massive budget or a cluster of GPUs to build smart systems. You just need the right architecture, a deep understanding of your tools, and the courage to break the status quo.


Curious about the technical blueprints, the Kafka configurations, or how to run Llama.cpp in Docker? You can explore the full implementation in the Pomai Ecosystem GitHub repository.

End of article

Explore the architecture hands-on