DEV Community

infraopsx
infraopsx

Posted on

QuietOps: Local Gemma Turns 240 Docker Log Lines Into Five Signals 🦥

Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady Submission 🦥

This is a submission for the Hacktoberfest Open-Source AI Challenge, Week 3: Slow and Steady.

What I Built

The least glamorous part of debugging a container incident is often the first five minutes: staring at a log stream and reading the same error dozens of times. I wanted the next operator to receive a small, readable handoff instead.

QuietOps is a local-first Python CLI that turns a bounded Docker/Linux log file into grouped symptoms and a cautious briefing generated by Gemma 3 1B running locally through Ollama.

The workflow is intentionally simple:

  1. Scan the file for errors and warnings, with explicit limits on input size and line count.
  2. Remove common secrets, IP addresses and email addresses on a best-effort basis; group repetitive messages and assign evidence IDs such as E01–E05.
  3. Send only a small set of redacted examples to a loopback-only Ollama endpoint.
  4. Ask the local model for potential explanations and read-only checks, while keeping the visible factual overview separate from model prose.
  5. Validate JSON, reject non-existent IDs and some obviously unrelated event-to-claim citations. These conservative checks do not prove a suggestion correct.
  6. Create Markdown, JSON and a standalone HTML handoff that distinguishes observations from hypotheses.

This is not an auto-remediation agent. It cannot connect to a production server, execute shell commands, edit configuration or restart containers. The human operator remains in control.

Demo

Open the live QuietOps report · Source code · Real-Gemma CI and deployment runs

The browser demo is a static HTML report produced by real Gemma 3 1B inference in GitHub Actions, not a mockup or a public model API. The Actions runner starts local Ollama, downloads Gemma's actual weights, analyzes the repository's synthetic fixture and publishes the resulting handoff. Visitors can inspect the generated JSON and Markdown without creating an account. The app does not accept log uploads on this public page.

I also kept a separate deterministic, no-model preview, explicitly labeled AI not run. It is not the live Gemma demonstration.

The synthetic fixture contains 240 Docker-style lines. QuietOps finds 110 warning/error lines and groups them into these five signatures:

Event What the excerpt actually shows Occurrences
E01 API logs a PostgreSQL connection URL (not proof that the URL is wrong) 32
E02 Worker retries queue delivery after a timeout (WARNING) 27
E03 API database query timeout 19
E04 Nginx upstream connection refused 17
E05 PostgreSQL password authentication failure for the app user 15

Five initial review items instead of 240 log lines is a 97.9% reduction in items to scan, not a measured 97.9% saving of an operator's time. Nor does it establish an accurate root-cause diagnosis.

To run the deterministic grouping without any model:

python3 examples/make_demo.py
python3 -m quietops preview examples/docker-incident.log --output-dir out/
~~~{% endraw %}

To reproduce actual AI-assisted output locally after installing Ollama:{% raw %}

~~~bash
ollama pull gemma3:1b
# Make sure the local Ollama service is running.
python3 -m quietops scan examples/docker-incident.log --model gemma3:1b --output-dir out/
~~~{% endraw %}

## Code

The project uses only Python's standard library, and keeps Ollama as a separately installed local inference server. The core is broken into small inspectable stages:{% raw %}

~~~text
input log
  → byte/line limits
  → best-effort secret redaction
  → error/warning filtering
  → repeated-signature grouping
  → E01–E05 evidence IDs
  → Ollama API on 127.0.0.1
  → Gemma 3 1B JSON response
  → schema + conservative event-reference checks
  → deterministic factual overview + unverified Gemma suggestions
  → self-contained HTML + Markdown + JSON
~~~

There is no signup, managed cloud database, background collector, hosted model or remote log upload. The network request is restricted to localhost, with HTTP proxies disabled for it. The parser checks the size before reading the entire file and does not process unbounded streams.

The project includes automated regression tests: a simulated local Ollama server, secret redaction, explicit WARNING handling, invented evidence IDs, and claims that cite unrelated log events. A separate GitHub Actions workflow downloads the **actual Gemma weights** and verifies a real model-generated artifact. These are deliberately separate levels of evidence; green tests do not prove a diagnosis is correct.

## How I Built It

I started with a mundane handoff problem: the same few errors flood an incident log, but the next shift still has to scroll through every repetition.

I used the Python standard library for bounded parsing, normalization, grouping, redaction and report generation. The model gets a small set of redacted event excerpts over Ollama on 127.0.0.1, not the unfiltered log stream. The default first pass examines up to 8,000 lines or 2 MB and sends at most 12 event groups with two excerpts each; **8,000 is an engineering limit, not a measured Gemma quality threshold**.

My first tests used a fake Ollama HTTP server. They passed, but the **first actual Gemma run failed** because the response wasn't valid JSON. Requiring Ollama JSON Schema structured output fixed the integration, as confirmed by this [real-model CI run](https://github.com/infraopsx/quietops/actions/runs/39359492617).

A subtler failure showed up once the browser demo was public. Gemma sometimes attached a *real* evidence ID to a statement the underlying log did not support. For example, a worker queue retry was treated as evidence of a database outage. I also discovered that keyword detection was labeling a WARNING about a timeout as ERROR.

That led to three concrete changes:

1. Explicit log levels take precedence over severity keywords such as "timeout".
2. The visible **observed-log overview comes from deterministic counts and service labels**, not unchecked model prose.
3. Model-generated hypotheses and read-only checks must cite existing events and pass conservative, event-by-event topical checks. Unrelated-service suggestions can be dropped.

These checks are intentionally modest. They **do not verify causal reasoning**. A note citing E05 for a suspected credential mismatch is a hypothesis worth checking, not a proven diagnosis. A model can still be wrong, even if every event ID exists.

There is a further trade-off I haven't benchmarked yet: choosing the 12 most frequent signatures might omit a rare but critical failure. I would rather document that limitation than pretend a first-pass handoff is full incident analysis.

## Why Does Open Innovation Matter?

Operational logs may contain internal hostnames, usernames, network details and credentials. Running inference on-device means the analysis does not require shipping those logs to a third-party API. This was my primary reason for using a locally runnable open-weight model.

The other benefit is **control**. I can inspect the preprocessing rules, change the prompt, replace the model and reproduce the test environment without paying per-token API fees. Once the model weights are downloaded, local inference can run without an external model service.

QuietOps's own code is MIT-licensed. **Gemma model weights have their own Google Gemma terms** and are not redistributed with the project. Secret redaction is best-effort, so users must still inspect logs before processing or sharing them.

## The Lazy Payoff

Instead of requiring a tired operator to scroll 240 synthetic lines to find five recurring patterns, QuietOps turns the first pass into **five reviewable groups**, with optional local-Gemma suggestions clearly separated from observations.

It is a small, reproducible convenience, not an AI that claims to fix outages. The best possible result is that the next person can **start asking better questions sooner**—and can see exactly where the model might be wrong.

## Prize Categories

- **Best Use of Gemma** — actual Gemma 3 1B inference is demonstrated in the successful GitHub Actions run linked above.

---

**Development disclosure:** AI-assisted coding and English drafting were used in this project. The synthetic examples, CI outcomes and limitations are described as they actually occurred. No paid customers, real production diagnoses, measured human time savings or contest winnings are claimed.
Enter fullscreen mode Exit fullscreen mode

Top comments (3)

Collapse
 
officialmailkr profile image
오피셜메일 •

근거 ID가 실제로 존재하는지와 그 근거가 원인 설명을 지지하는지를 구분해 적어주신 점이 좋습니다. 인계 화면에서도 각 가설 옆에 해당 로그의 짧은 인용을 붙이면, 다음 담당자가 ID만 보고 추론까지 검증됐다고 받아들이는 일을 줄일 수 있겠네요. 가짜 서버 테스트와 실제 모델 테스트를 따로 보여준 것도 판단에 도움이 됩니다.

Collapse
 
skepagent profile image
SkepAgent •

先脱敏再喂给本地模型这个顺序很对,日志里的 API key 和内网 IP 直接进云端 LLM 是我见过最常见的泄漏姿势。第 5 步校验 JSON、丢弃引用了不存在 evidence ID 的结论也很务实,1B 小模型编造编号的概率不低。好奇问下,输入行数这个上限是试出来的吗?想知道 Gemma 3 1B 在多少行之后总结质量会明显掉下来。

Collapse
 
infraopsx profile image
infraopsx •

目前还没有测出一个明确的质量拐点,输入行数限制主要是工程上的保守设置。
QuietOps 会先在本地脱敏、聚类,再把筛选后的事件信息交给 Gemma,而不是直接把所有原始日志塞进模型。
目前用 240 行合成日志验证了整个流程,但还没有系统测试不同日志规模下的摘要质量。
你这个问题倒是让我意识到另一个风险:如果某个严重错误只出现一次,会不会因为频率太低,被 Top 12 筛选遗漏?
后面值得把这两种情况一起测试一下。谢谢提醒!