A Python tool for analyzing CI/CD pipeline logs and generating actionable reports. Detects common failure patterns — proxy errors, DNS failures, disk space exhaustion, Docker daemon problems, authentication errors, timeouts, compilation errors, and test failures — via fast regex rules or a cloud LLM.
The tool is built around three protocol + registry layers that compose cleanly regardless of the input source, analysis engine, or output sink chosen:
LogSource AnalysisEngine Reporter / Sink
────────── ────────────── ───────────────
LocalFileSource ─┐ ┌─ TextReporter → stdout / file
JenkinsSource ─┤─► RegexEngine ───►├─ JsonReporter → stdout / file
GitHubActions ─┤─► AgenticAI ───►└─ HtmlReporter → file
InlineLogSource ─┘ (LangChain)
Web UI (ui.py)
───────────────
GET /ui → analyze form
POST /ui/analyze → result page
GET /ui/history → memory browser
sources/— each source owns its own I/O and exposesfetch() → str/describe() → strengines/— each engine receives plain text and returns anAnalysisResultreporting/— each reporter receives anAnalysisResultand renders or posts itmemory/— optional Chroma vector store; past findings are embedded after each run and retrieved as context for the AI engineapi.py— FastAPI JSON API that reuses the same source / engine / reporter registriesui.py— FastAPI HTML router; server-rendered Jinja2 pages mounted on the same app
python -m venv .venv
source .venv/bin/activate
# Core (regex mode, local files, text/JSON/HTML output)
pip install -e .
# With AI analysis — cloud providers (LangChain, OpenAI, Anthropic)
pip install -e .[ai]
# With AI analysis — local LLM via Ollama (no API key required)
pip install -e .[local]
# With memory store (Chroma vector DB)
pip install -e .[memory]
# With REST API and Web UI (FastAPI, uvicorn, Jinja2, python-multipart)
pip install -e .[api]
# Everything
pip install -e .[ai,local,memory,api]# Regex analysis — fast, deterministic, no dependencies beyond core
python -m cicd_log_analyzer.cli sample_logs/jenkins_failed.log
# HTML report written to file
python -m cicd_log_analyzer.cli sample_logs/jenkins_failed.log --format html --output reports/report.html
# Fail the CI step when high-severity findings are present (exit 2)
python -m cicd_log_analyzer.cli build.log --fail-on-highPull logs directly from CI systems instead of passing a local file.
python -m cicd_log_analyzer.cli \
--source jenkins \
--jenkins-url http://jenkins.example.com \
--jenkins-job my-pipeline \
--jenkins-build 42 \
--jenkins-username admin \ # or set JENKINS_USERNAME
--jenkins-token <api-token> # or set JENKINS_API_TOKENpython -m cicd_log_analyzer.cli \
--source github \
--github-repo owner/repo \
--github-run-id 12345678 \
--github-token <pat> # or set GITHUB_TOKEN--source-timeout <seconds> (default 30) applies to all remote sources.
Requires pip install -e .[ai] and a valid API key.
export OPENAI_API_KEY="sk-..."
# or
export ANTHROPIC_API_KEY="sk-ant-..."
# OpenAI
python -m cicd_log_analyzer.cli build.log \
--mode ai --ai-provider openai --ai-model gpt-4.1-mini
# Anthropic
python -m cicd_log_analyzer.cli build.log \
--mode ai --ai-provider anthropic --ai-model claude-sonnet-4-6
# Remote source + AI
python -m cicd_log_analyzer.cli \
--source github --github-repo owner/repo --github-run-id 42 \
--mode ai --ai-provider openaiRuns fully offline — no API key, no data leaving the machine. Ideal when logs contain sensitive internal hostnames, IPs, or tokens.
Requires pip install -e .[local] and Ollama running locally.
# 1. Install and start Ollama
ollama pull qwen2.5:7b # ~4 GB, best structured-output quality in class
ollama serve # starts on http://localhost:11434
# 2. Analyze
python -m cicd_log_analyzer.cli build.log \
--mode ai --ai-provider ollama
# Custom model or remote Ollama server
python -m cicd_log_analyzer.cli build.log \
--mode ai --ai-provider ollama \
--ai-model llama3.1:8b \
--ollama-base-url http://my-ollama-server:11434Recommended models (best → most lightweight):
| Model | Size | Notes |
|---|---|---|
qwen2.5:7b |
~4 GB | Default — best structured output in class |
llama3.1:8b |
~5 GB | Strong general reasoning |
mistral:7b |
~4 GB | Fast, widely used |
phi3.5:mini |
~2 GB | Smallest viable option |
AI flags:
| Flag | Default | Description |
|---|---|---|
--ai-provider |
openai |
openai, anthropic, or ollama |
--ai-model |
(auto) | Model name; defaults to gpt-4.1-mini (cloud) or qwen2.5:7b (ollama) |
--ai-timeout |
30 |
Request timeout in seconds |
--ai-max-input-chars |
40000 |
Log characters sent to the provider |
--ai-api-key |
(env var) | Override env-var key lookup (not used for Ollama) |
--ollama-base-url |
http://localhost:11434 |
Ollama server URL |
The AI engine uses LangChain with with_structured_output() — no hand-rolled JSON parsing. Past findings stored in the memory vector store are retrieved and passed as context to improve recommendations.
Requires pip install -e .[memory] (Chroma).
After each analysis the findings are embedded and stored locally. Subsequent AI runs retrieve similar past failures as context.
# Default store location: ~/.cicd_log_analyzer/memory
python -m cicd_log_analyzer.cli build.log --mode ai --ai-provider openai
# Custom store path
python -m cicd_log_analyzer.cli build.log --mode ai \
--memory-path /var/cicd/memory
# Disable memory for a single run (skip both retrieval and ingestion)
python -m cicd_log_analyzer.cli build.log --no-memoryMemory is silently skipped when chromadb is not installed; a warning is printed to stderr.
Requires pip install -e .[api].
uvicorn cicd_log_analyzer.api:app --host 0.0.0.0 --port 8000Endpoints:
| Method | Path | Description |
|---|---|---|
GET |
/health |
Liveness probe — returns {"status": "ok", "version": "1.0.0"} |
POST |
/analyze |
Full analysis — accepts JSON body, returns AnalyzeResponse |
Minimal request (inline log text, regex mode):
POST /analyze
{
"log_text": "docker: Error response from daemon: No space left on device\n"
}Jenkins source, AI mode:
POST /analyze
{
"source": "jenkins",
"jenkins_url": "http://jenkins.example.com",
"jenkins_job": "my-pipeline",
"jenkins_build": 42,
"mode": "ai",
"ai_provider": "openai"
}The API reuses the same SOURCES, ENGINES, and REPORTERS registries as the CLI.
Requires pip install -e .[api]. The UI is served by the same uvicorn process as the JSON API — no separate server needed.
uvicorn cicd_log_analyzer.api:app --host 0.0.0.0 --port 8000
# open http://localhost:8000/ui| Route | Description |
|---|---|
GET /ui |
Analyze form — choose source (paste / Jenkins / GitHub Actions), mode (regex / AI), and optional advanced settings |
POST /ui/analyze |
Submits the form, runs the full pipeline, renders a color-coded findings page |
GET /ui/history |
Reads all stored findings from the Chroma memory store and displays them in a table sorted by severity |
All pages are server-rendered Jinja2 — no JavaScript framework, no build step. The dark-themed UI uses severity badges (high / medium / low), a status banner (PASSED / FAILED), and a summary-by-category table on the result page.
When the memory store is empty or chromadb is not installed, the history page shows a friendly empty state rather than an error.
# Build
docker build -t cicd-log-analyzer .
# Run — JSON API + Web UI on port 8000, memory store persisted to a named volume
docker run -p 8000:8000 \
-v cicd-memory:/data/memory \
-e OPENAI_API_KEY=sk-... \
cicd-log-analyzer
# JSON API: http://localhost:8000/analyze
# Web UI: http://localhost:8000/ui
# API docs: http://localhost:8000/docs# 1. Fill in base64-encoded secrets
kubectl apply -f k8s/secret.yaml
# 2. Create PVC for the Chroma memory store
kubectl apply -f k8s/pvc.yaml
# 3. Deploy (2 replicas, resource limits, liveness + readiness probes)
kubectl apply -f k8s/deployment.yaml
# 4. Expose via ClusterIP service (port 80 → 8000)
kubectl apply -f k8s/service.yamlThe Deployment reads API keys from the cicd-analyzer-secrets Secret (all keys are optional: true so the pod starts without them). The Chroma memory store is mounted from the PVC at /data/memory.
| Code | Meaning |
|---|---|
0 |
Success |
1 |
Runtime error (file not found, source fetch failed, AI provider error) |
2 |
Success but high-severity findings present — only when --fail-on-high is set |
In AI mode the log content is sent to the configured cloud provider. If your logs contain credentials, private IP addresses, internal hostnames, or proprietary build output, either redact them first or use regex mode (fully offline).
- API keys and tokens are read from environment variables and never written to disk by this tool.
- Logs are not cached by the tool; provider data retention policies apply in AI mode.
pytest -qOptional-dependency tests (test_api.py, two pydantic-schema tests in test_ai_engine.py) are skipped automatically when the relevant extras are not installed.