Automated log analysis agent that monitors Docker container logs and PFsense syslog, uses an LLM to identify issues worth acting on, and pushes alerts to Gotify with severity-based priority.
PFsense ──── UDP :1514 ─────┐
├──► Vector ──► /data/logs/*.jsonl
Docker containers ── socket ┘ │
▼
Sniper Agent
│
┌──────────┼──────────┐
│ │ │
reads logs reads context sends alerts
│ │ │
▼ ▼ ▼
LLM analysis context.md Gotify
- Vector collects logs from Docker (via socket) and PFsense (via UDP syslog on port 1514), tags the source, and writes daily JSONL files to
/data/logs/ - Sniper runs on a configurable interval (default 12 hours), reads new log entries since the last scan, and sends them to an LLM for analysis
- The LLM classifies any issues by severity and returns structured JSON
- Each issue triggers a Gotify notification with priority mapped to severity
| Severity | Gotify Priority | Meaning |
|---|---|---|
| info | 1 | Informational, no action needed |
| low | 3 | Minor, can wait |
| medium | 5 | Moderate, address soon |
| high | 8 | Significant, needs prompt attention |
| urgent | 10 | Critical, immediate action required |
./data/context.md is a plain markdown file you edit manually to control the agent's behavior. It has two sections:
- Ignore — list issues you don't want notified about (e.g. known false positives)
- Notes — environment details so the LLM knows what's normal
The file is mounted from the persistent data volume, so edits persist across container restarts. Example:
# Sniper Context
## Ignore
- certbot renewal failures on port 80 are expected during off-hours
- pfsense gateway alarm on WAN1 is a known ISP issue
## Notes
- Home lab runs on TrueNAS Scale
- Docker host is the same machine as the log collector
- PFsense is the edge firewall/gatewayEvery issue the LLM identifies is logged to /data/notif_history.md (configurable via NOTIF_HISTORY_FILE), including ones filtered out by MIN_SEVERITY. Each entry shows whether it was SENT to Gotify or FILTERED, along with the severity, source, description, and log excerpt. This gives you a full audit trail of everything the agent detected, even if you only want high-severity Gotify pushes.
The agent exposes a FastMCP server internally on 127.0.0.1:8080 (not exposed to the host):
analyze_logs— manually trigger a log scanread_context— read the current context.md
- Docker + Docker Compose
- A Gotify instance with an app token
- An LLM API key (uses synthetic.new by default)
- Copy
.env.exampleto.envand fill in your values:
cp .env.example .env- Create the data directory and seed the context file:
mkdir -p data/logs
cp context.md data/context.md- Start the stack:
docker compose up -d- Point your PFsense syslog at
<host>:1514/UDP
| Variable | Default | Description |
|---|---|---|
LLM_BASE_URL |
https://api.synthetic.new/openai/v1 |
LLM API base URL |
LLM_API_KEY |
(required) | API key for the LLM provider |
LLM_MODEL |
syn:small:text |
Model name to use |
GOTIFY_URL |
(required) | Gotify server URL |
GOTIFY_TOKEN |
(required) | Gotify app token |
SCAN_INTERVAL |
6h |
Time between scans (e.g. 6h, 1d12h, 30m, or seconds as bare number) |
LOG_DIR |
/data/logs |
Path to JSONL log files |
CONTEXT_FILE |
/data/context.md |
Path to context markdown |
LAST_SCAN_FILE |
/data/.last_scan |
Timestamp of last scan |
NOTIF_HISTORY_FILE |
/data/notif_history.md |
Path to notification history log (all issues, including filtered) |
MIN_SEVERITY |
info |
Minimum severity to log to Gotify (info/low/medium/high/urgent) |
Pushes to main automatically build and push dungfu/sniper-agent-logging:latest to DockerHub via GitHub Actions. Set these repository secrets:
DOCKERHUB_USERNAMEDOCKERHUB_TOKEN
├── .github/workflows/docker.yml CI/CD pipeline
├── .env.example Environment template
├── context.md Default context file (seed into data/)
├── docker-compose.yml Vector + Sniper
├── Dockerfile Python 3.14, fastmcp/openai/httpx
├── pyproject.toml Project metadata & dependencies
├── vector/
│ └── vector.yaml Vector config: Docker + PFsense -> JSONL
└── src/sniper/
├── __init__.py
├── main.py Entry point: scheduler + MCP server
├── agent.py FastMCP tools, LLM analysis, notification logic
├── config.py Environment-based configuration
├── context.py Reads context.md
└── notifier.py Gotify push with severity->priority mapping