local-first · sanitize-before-LLM

netlog-ai

Network logs in. Ranked actions out. A local, sanitize-first, multi-vendor AI log analyzer that turns raw syslog and CLI output into prioritized, copy-pastable root-cause playbooks.

0
tests collected
0
regex patterns
0
log connectors
0
demo devices
0
MCP tools

Overview

Network logs in. Ranked actions out.

netlog-ai is a local-first, multi-vendor network log analyzer. It ingests syslog and CLI output from Junos, Arista EOS, Nokia SR Linux, and FRR, classifies events with a regex knowledge base, and deduplicates them into a severity-ranked action list. A local or cloud LLM then writes a 5-phase root-cause playbook with copy-pastable per-vendor CLI fixes — or, when no model is available, the tool degrades gracefully to a deterministic rule-based knowledge base.

Built for NOC operators and network engineers who need actionable, on-prem AI analysis without shipping data to a SaaS.

🛡️ Defining invariant — sanitize before LLM

Every config and log is scrubbed of secrets and public IPs before any outbound call. Data never leaves the host unredacted.

The pipeline at a glance

1 Ingest from any source → normalize to immutable LogEvents
2 strip_ansi + 55 regexes → severity & category
3 Dedup into ranked ActionItems (sev × count)
🛡 Sanitize gate scrubs secrets & public IPs
4 LLM chain → 5-phase playbook (or rule KB)
5 Health score 0–100 + A–F grade → AnalysisResult

Key Features

What makes it different

Local-first by design, multi-vendor by default, and agent-callable from your editor.

Architecture

One analyzer core, three entrypoints

The Flask UI, the CLI, and the MCP server all wrap a single shared analyzer core — layered into ingest, the always-on sanitize gate, the classifier, the orchestrator, and pluggable intelligence backends.

System Context

How the analyzer core sits between operators, AI agents, log platforms, LLM runtimes, and the network devices. Every outbound LLM call is gated by the sanitizer.

flowchart TB
    OP["NOC Operator - browser and CLI"]
    AGENT["AI Agents - Claude Code and Cursor"]
    NET(["netlog-ai analyzer core"])
    LOGS["Log Platforms - Kibana Splunk Loki LibreNMS syslog"]
    LLM["LLM Runtimes - Ollama DMR Claude"]
    DEV["Network Devices - Junos EOS SR Linux FRR"]

    OP -->|HTTP and JSON| NET
    AGENT -->|MCP stdio| NET
    LOGS -->|fetch logs| NET
    DEV -.->|syslog and configs| LOGS
    DEV -.->|docker logs and config| NET
    NET -->|sanitized prompt| LLM
    LLM -->|5-phase playbook JSON| NET
    NET -->|ranked actions and CLI fixes| OP
    NET -->|tool results| AGENT

    classDef sys fill:#7c3aed,stroke:#c4b5fd,color:#f8fafc,stroke-width:2px
    classDef person fill:#60a5fa,stroke:#bfdbfe,color:#0b1220
    classDef ext fill:#475569,stroke:#94a3b8,color:#f8fafc
    classDef ai fill:#a78bfa,stroke:#ddd6fe,color:#0b1220

    class NET sys
    class OP,AGENT person
    class LOGS,DEV ext
    class LLM ai

Container & Component Map

Three entrypoints all wrap one analyzer core layered into ingest, the always-on sanitize gate, classifier, orchestrator, and pluggable intelligence backends.

flowchart TB
    subgraph ENTRY["Entrypoints"]
        WEB["web/ Flask + vanilla-JS SPA :6060"]
        CLI["cli.py serve analyze containers mcp"]
        MCP["mcp_server/ FastMCP stdio"]
    end
    subgraph INGEST["Ingest"]
        SRC["sources/ kibana splunk loki syslog librenms"]
        ADP["adapters/ frr file network_tool tfsm_auto"]
    end
    subgraph CORE["Analyzer Core"]
        SAN["sanitize.py redact gate"]
        CLS["classifier.py 55 regexes"]
        ANA["analyzer.py orchestrator"]
        SITE["site intel topology optimize copilot"]
    end
    subgraph BRAIN["Intelligence"]
        LLMC["llm.py provider chain"]
        KB["kb.py rule-based fallback"]
    end

    WEB --> ANA
    CLI --> ANA
    MCP --> ANA
    SRC --> ANA
    ADP --> ANA
    ANA --> SAN --> CLS
    ANA --> SITE
    ANA --> LLMC
    LLMC -.fallback.-> KB

    classDef entry fill:#60a5fa,stroke:#bfdbfe,color:#0b1220
    classDef ingest fill:#475569,stroke:#94a3b8,color:#f8fafc
    classDef gate fill:#f43f5e,stroke:#fda4af,color:#0b1220
    classDef core fill:#7c3aed,stroke:#c4b5fd,color:#f8fafc
    classDef brain fill:#a78bfa,stroke:#ddd6fe,color:#0b1220

    class WEB,CLI,MCP entry
    class SRC,ADP ingest
    class SAN gate
    class CLS,ANA,SITE core
    class LLMC,KB brain

How it works

The analysis pipeline, end to end

Raw lines become normalized events, classified findings, then deduped ranked actions. The top items receive deep analysis only after passing the sanitize gate — then a weighted health score is computed and everything is assembled into one JSON result.

Primary Flow — POST /api/analyze

The end-to-end runtime path: classify, rank, sanitize per item, query the LLM (or rule KB fallback), score health, and return assembled JSON to the SPA.

sequenceDiagram
    autonumber
    actor OP as Operator SPA
    participant API as Flask /api/analyze
    participant AN as analyzer.analyze
    participant CL as classifier
    participant SA as sanitize
    participant LK as llm and kb

    OP->>API: POST logs or site bundle
    API->>AN: analyze events and use_llm
    AN->>CL: strip_ansi plus classify 55 regex
    CL-->>AN: ClassifiedEvents plus counts
    AN->>AN: dedup to ranked ActionItems by sev x count
    loop top-N action items
        AN->>SA: scrub secrets and public IPs
        SA-->>AN: sanitized incident context
        AN->>LK: query Ollama to DMR to Claude
        alt LLM available
            LK-->>AN: 5-phase JSON playbook
        else off or failed
            LK-->>AN: kb.lookup deterministic playbook
        end
    end
    AN->>AN: health_score 0-100 plus grade
    AN-->>API: AnalysisResult JSON
    API-->>OP: score actions CLI topology

Data Flow — the analysis pipeline

Data moves strictly left-to-right: raw lines → normalized events → classified findings → deduped ranked actions; top items get deep analysis after the sanitize gate.

flowchart LR
    RAW["Raw lines syslog CLI paste"]
    EV["LogEvent frozen records"]
    CE["ClassifiedEvent sev category"]
    AI["ActionItem ranked sev x count"]
    GATE{{"sanitize gate"}}
    DEEP["Deep analysis 5-phase playbook"]
    SCORE["Health score 0-100 + A-F"]
    OUT["Outputs SPA CLI MCP reports"]

    RAW -->|adapters and connectors| EV
    EV -->|strip_ansi + regex KB| CE
    CE -->|dedup and drop recovery| AI
    AI -->|top-N context| GATE
    GATE -->|LLM or rule KB| DEEP
    AI --> SCORE
    DEEP --> OUT
    SCORE --> OUT

    classDef raw fill:#475569,stroke:#94a3b8,color:#f8fafc
    classDef stage fill:#7c3aed,stroke:#c4b5fd,color:#f8fafc
    classDef gate fill:#f43f5e,stroke:#fda4af,color:#0b1220
    classDef score fill:#60a5fa,stroke:#bfdbfe,color:#0b1220
    classDef out fill:#a78bfa,stroke:#ddd6fe,color:#0b1220

    class RAW,EV raw
    class CE,AI,DEEP stage
    class GATE gate
    class SCORE score
    class OUT out

Tech Stack

Built on a no-build, local-first stack

Python frozen dataclasses and protocols at the core, a vanilla-JS SPA on top, and pluggable LLM runtimes underneath.

Components

Modules & responsibilities

Every module maps to a real path in src/ai_log_analyzer/.

Quickstart

Up and running in minutes

Clone, install, and serve the UI on http://localhost:6060 — or run the CLI and MCP server.

Install & serve
# clone and enter
git clone https://github.com/gesh75/netlog-ai.git
cd netlog-ai

# create venv and install
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
cp .env.example .env

# start the web UI on http://localhost:6060
ai-log-analyzer serve
Analyze · MCP · test
# analyze FRR containers, no LLM, print score
ai-log-analyzer analyze --frr r1 r2 --no-llm | jq .score

# analyze a syslog file
ai-log-analyzer analyze --file /var/log/syslog

# run the MCP stdio server for agents
pip install 'netlog-ai[mcp]' && netlog-ai mcp

# run the test suite with coverage
pytest --cov=src --cov-report=term-missing