feat: unknown-pattern template mining + custom rules; close sanitize/auth gaps#12
Merged
Merged
Conversation
…auth gaps Product analysis pass — market research (Drain3/DeCorus/IncidentFox-style pipelines) + full codebase audit, then: Added - patterns.py: dependency-free Drain-lite streaming template miner over every line the regex KB can't match (variables masked, similar shapes wildcard-merged, LRU-bounded). Surfaced as unknown_patterns in /api/analyze, MCP analyze_logs, and a new Unknown Patterns UI panel. - Custom classification rules: AI_LOG_ANALYZER_CUSTOM_RULES JSON file + GET/POST /api/rules; custom rules take precedence over the built-in KB. Security - deep_analyze() now sanitizes sample log lines + descriptions before any LLM call (config paths were scrubbed; the log path was not). - /api/sources/<id>/test and /fetch now require the API token. - Authorization: Bearer accepted alongside X-API-Token (README documented Bearer; code only accepted the custom header). Fixed - MCP server resolves packaged data/sites (list_sites was empty on pip installs). - /api/optimize/site uses the shared site loader — per-device platform kept on mixed-vendor sites. - Syslog connector fetch() no longer drains the ring buffer (idempotent). - Default Ollama model gemma4:latest -> qwen2.5-coder:latest (gemma4 does not exist; it is the default provider). - Env source loader no longer leaks verify_tls/timeout_seconds into extra. - .env.example/README document the real security env vars + ollama provider. Tests 294 -> 308 (miner, custom rules, sanitize gate, auth regressions). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015XM7j9iDXYwSvjnxZYjzaq
…available The tfsm_templates.db download from the upstream GitHub repo now 404s (upstream restructured/removed the file), which failed 3 tests on every CI matrix job. The adapter itself already degrades to no-match by design; the tests now skip with a clear message instead of failing on an external outage. TFSM_DB_URL env override added so a mirror can re-enable them. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015XM7j9iDXYwSvjnxZYjzaq
…gaps Review of the repo's full development history (PRs #1-#12) surfaced the remaining gaps; this closes them: - Cross-run template memory (AI_LOG_ANALYZER_TEMPLATE_STORE): the miner persists every template shape to a FIFO-bounded JSON store and flags shapes never seen in any prior run (is_new / new_template_count / 🆕 in the UI) — the 'first time this shape has ever appeared' early-warning. Atomic writes; corrupt or unwritable stores never break an analysis. - Coverage for the modules every prior phase left untested: reports.py, runbook.py, topology.py, and web routes /api/report, /api/runbook, /api/topology + validation paths of /api/diff and /api/copilot. Suite 308 -> 325. - llm.py docstring said 'three providers' while listing four. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015XM7j9iDXYwSvjnxZYjzaq
gesh75
marked this pull request as ready for review
July 13, 2026 15:26
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
A deep product-analysis pass: market research on how production AIOps pipelines handle network syslog (Drain3 / IBM DeCorus / IncidentFox-class tools), plus a full audit of the repo's development history (PRs #1–#11). The single biggest analytical gap: any log line the 55-pattern regex KB can't match silently becomes
info/otherand disappears — while the strongest early-warning signal in the field is precisely "a message shape never seen before just appeared."Added
patterns.py, zero dependencies) — every unmatched line is masked (<ip>/<mac>/<hex>/<if>/<n>/<ts>) and clustered with a Drain-style fixed-depth miner (similar shapes merge into<*>wildcards, LRU-bounded memory so the streaming pipeline stays flat at any input size). Results surface asunknown_patternsin/api/analyze, the MCPanalyze_logstool, and a new Unknown Patterns UI panel — error-smelling templates ranked first.AI_LOG_ANALYZER_TEMPLATE_STOREand the miner remembers every shape across runs (FIFO-bounded JSON store, atomic writes, corrupt-file tolerant). Shapes never seen in any prior run are flaggedis_new/new_template_count/ 🆕 in the UI — the classic AIOps early-warning.AI_LOG_ANALYZER_CUSTOM_RULES) plus a runtime API (GET/POST /api/rules). Custom rules run before the built-in KB, so operators can demote known noise or promote site-specific failures.Security (audit findings)
deep_analyze()sent raw sample log lines (and severity-promoted raw descriptions) to the LLM unsanitized; config paths were always scrubbed but logs were not — contradicting the project's core sanitize-before-LLM guarantee./api/sources/<id>/testand/fetchnow require the API token — the only POST data routes missing the gate (data egress + probe surface).Authorization: Beareraccepted alongsideX-API-Token— the README documented Bearer while the code only accepted the custom header, locking out users who followed the docs.Fixed
data/sites—list_sites/analyze_sitereturned empty on anypip install netlog-ai[mcp]wheel (repo-root-only lookup)./api/optimize/sitenow uses the shared site loader — per-deviceplatformpreserved on mixed-vendor sites (was stamping every device with e.g.multi (Nokia SRL + Arista cEOS + FRR)).fetch()is idempotent — it drained the ring buffer, so correlate → triage on the same source saw zero events on the second call.gemma4:latest→qwen2.5-coder:latest(gemma4 doesn't exist and ollama is the default provider — out-of-box LLM calls failed silently).TFSM_DB_URLoverride added for mirrors.verify_tls/timeout_secondsintoextra..env.example/README now document the real security env vars (AI_LOG_ANALYZER_API_TOKEN,AI_LOG_ANALYZER_CORS_ORIGINS,ANALYZER_HOST,AI_LOG_ANALYZER_FILE_ROOTS), theollamaprovider, and correct defaults (LLM_TIMEOUT=120).Tests
294 → 325 passed (2 skipped), ruff clean. New coverage: miner masking/clustering/eviction/integration, template-store persistence, custom rules (engine + API + precedence), sanitize-gate regressions, auth regressions, syslog idempotency, plus a coverage wave for the modules earlier phases left untested —
reports.py,runbook.py,topology.py, and web routes/api/report,/api/runbook,/api/topology,/api/diff,/api/copilot.Suggested next features (researched, not in this PR)
netlog-ai[parse]has no DB source for fresh installs.🤖 Generated with Claude Code
https://claude.ai/code/session_015XM7j9iDXYwSvjnxZYjzaq