<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: infraopsx</title>
    <description>The latest articles on DEV Community by infraopsx (@infraopsx).</description>
    <link>https://dev.to/infraopsx</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4195196%2F5700b594-f9a7-4044-847c-9b3b815231fc.png</url>
      <title>DEV Community: infraopsx</title>
      <link>https://dev.to/infraopsx</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/infraopsx"/>
    <language>en</language>
    <item>
      <title>QuietOps: Local Gemma Turns 240 Docker Log Lines Into Five Signals 🦥</title>
      <dc:creator>infraopsx</dc:creator>
      <pubDate>Tue, 20 Oct 2026 02:49:34 +0000</pubDate>
      <link>https://dev.to/infraopsx/quietops-local-gemma-turns-240-docker-log-lines-into-five-signals-lep</link>
      <guid>https://dev.to/infraopsx/quietops-local-gemma-turns-240-docker-log-lines-into-five-signals-lep</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week3-2026-10-19"&gt;Hacktoberfest Open-Source AI Challenge, Week 3: Slow and Steady&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

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

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

&lt;p&gt;The workflow is intentionally simple:&lt;/p&gt;

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

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

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://infraopsx.github.io/quietops/" rel="noopener noreferrer"&gt;Open the live QuietOps report&lt;/a&gt;&lt;/strong&gt; · &lt;strong&gt;&lt;a href="https://github.com/infraopsx/quietops" rel="noopener noreferrer"&gt;Source code&lt;/a&gt;&lt;/strong&gt; · &lt;strong&gt;&lt;a href="https://github.com/infraopsx/quietops/actions/workflows/live-gemma.yml" rel="noopener noreferrer"&gt;Real-Gemma CI and deployment runs&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The browser demo is a &lt;strong&gt;static HTML report produced by real Gemma 3 1B inference&lt;/strong&gt; 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 &lt;a href="https://infraopsx.github.io/quietops/handoff.json" rel="noopener noreferrer"&gt;generated JSON&lt;/a&gt; and &lt;a href="https://infraopsx.github.io/quietops/handoff.md" rel="noopener noreferrer"&gt;Markdown&lt;/a&gt; without creating an account. The app does not accept log uploads on this public page.&lt;/p&gt;

&lt;p&gt;I also kept a separate &lt;a href="https://github.com/infraopsx/quietops/blob/main/demo/handoff.md" rel="noopener noreferrer"&gt;deterministic, no-model preview&lt;/a&gt;, explicitly labeled &lt;strong&gt;AI not run&lt;/strong&gt;. It is not the live Gemma demonstration.&lt;/p&gt;

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

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Event&lt;/th&gt;
&lt;th&gt;What the excerpt actually shows&lt;/th&gt;
&lt;th&gt;Occurrences&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;E01&lt;/td&gt;
&lt;td&gt;API logs a PostgreSQL connection URL (not proof that the URL is wrong)&lt;/td&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;E02&lt;/td&gt;
&lt;td&gt;Worker retries queue delivery after a timeout (&lt;strong&gt;WARNING&lt;/strong&gt;)&lt;/td&gt;
&lt;td&gt;27&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;E03&lt;/td&gt;
&lt;td&gt;API database query timeout&lt;/td&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;E04&lt;/td&gt;
&lt;td&gt;Nginx upstream connection refused&lt;/td&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;E05&lt;/td&gt;
&lt;td&gt;PostgreSQL password authentication failure for the app user&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;p&gt;To run the deterministic grouping without any model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 examples/make_demo.py
python3 &lt;span class="nt"&gt;-m&lt;/span&gt; quietops preview examples/docker-incident.log &lt;span class="nt"&gt;--output-dir&lt;/span&gt; out/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To reproduce actual AI-assisted output locally after installing Ollama:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ollama pull gemma3:1b
&lt;span class="c"&gt;# Make sure the local Ollama service is running.&lt;/span&gt;
python3 &lt;span class="nt"&gt;-m&lt;/span&gt; quietops scan examples/docker-incident.log &lt;span class="nt"&gt;--model&lt;/span&gt; gemma3:1b &lt;span class="nt"&gt;--output-dir&lt;/span&gt; out/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;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:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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 &lt;strong&gt;actual Gemma weights&lt;/strong&gt; and verifies a real model-generated artifact. These are deliberately separate levels of evidence; green tests do not prove a diagnosis is correct.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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; &lt;strong&gt;8,000 is an engineering limit, not a measured Gemma quality threshold&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;My first tests used a fake Ollama HTTP server. They passed, but the &lt;strong&gt;first actual Gemma run failed&lt;/strong&gt; because the response wasn't valid JSON. Requiring Ollama JSON Schema structured output fixed the integration, as confirmed by this &lt;a href="https://github.com/infraopsx/quietops/actions/runs/39359492617" rel="noopener noreferrer"&gt;real-model CI run&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A subtler failure showed up once the browser demo was public. Gemma sometimes attached a &lt;em&gt;real&lt;/em&gt; 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.&lt;/p&gt;

&lt;p&gt;That led to three concrete changes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Explicit log levels take precedence over severity keywords such as "timeout".&lt;/li&gt;
&lt;li&gt;The visible &lt;strong&gt;observed-log overview comes from deterministic counts and service labels&lt;/strong&gt;, not unchecked model prose.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These checks are intentionally modest. They &lt;strong&gt;do not verify causal reasoning&lt;/strong&gt;. 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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One rare-but-critical failure test changed the selection logic.&lt;/strong&gt; In a reproducible synthetic fixture containing 15 distinct, frequently repeated WARNING signatures and one single &lt;code&gt;FATAL database corruption detected&lt;/code&gt; event, a pure top-12-by-frequency baseline &lt;strong&gt;omitted the FATAL&lt;/strong&gt;. QuietOps now reserves one of the 12 slots for an observed FATAL/CRITICAL/PANIC/OOM/corruption signature when none would otherwise appear. The same test &lt;strong&gt;retains the FATAL&lt;/strong&gt;. See the &lt;a href="https://github.com/infraopsx/quietops/blob/main/tests/test_rare_critical.py" rel="noopener noreferrer"&gt;benchmark regression test&lt;/a&gt; and &lt;a href="https://github.com/infraopsx/quietops/actions/runs/39532579838" rel="noopener noreferrer"&gt;passing CI&lt;/a&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Synthetic case (16 distinct signatures)&lt;/th&gt;
&lt;th&gt;Rare FATAL included in 12 shown?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Frequency-only baseline&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;QuietOps with critical-signal reservation&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This comparison measures &lt;strong&gt;deterministic event selection only&lt;/strong&gt;, not Gemma diagnosis accuracy, precision/recall over production incidents, or human time saved. One slot is reserved, not every rare failure; the tool remains a first-pass handoff rather than full incident analysis.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;The other benefit is &lt;strong&gt;control&lt;/strong&gt;. 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.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  The Lazy Payoff
&lt;/h2&gt;

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

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

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Gemma&lt;/strong&gt; — actual Gemma 3 1B inference is demonstrated in the successful GitHub Actions run linked above.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Development disclosure:&lt;/strong&gt; 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.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>opensource</category>
      <category>python</category>
    </item>
  </channel>
</rss>
