AI agent that investigates production issues by querying Grafana/Loki logs. Describe a problem in natural language — the agent clarifies your intent, searches logs iteratively, and produces structured findings.
- Enter a query describing the problem (e.g., "why did payment ORD-12345 fail yesterday")
- The agent may ask clarifying questions about time range, entities, or context
- It autonomously builds and refines LogQL queries against your Grafana/Loki instance
- Findings are printed to stdout and saved as JSON to
completed_investigations/
- Go 1.25+
- Grafana instance with Loki datasource
- LLM API key (any Anthropic-compatible endpoint)
go build -o agent ./cmd/agent/All settings are environment variables with prefix LOGS_ANALYZER_. Create a dev.env file at project root — it is loaded automatically.
cp env.example dev.envSee env.example for all available variables with descriptions.
The agent uses an Anthropic-compatible API endpoint. Point it at your LiteLLM proxy — create a separate API key in LiteLLM to track usage independently from other tools (e.g., Claude Code):
LOGS_ANALYZER_LLM_BASE_URL— LiteLLM proxy URLLOGS_ANALYZER_LLM_API_KEY— dedicated key created for this agent
Model names should match what your LiteLLM instance exposes (e.g., claude-sonnet-4-6, claude-haiku-4-5).
The agent authenticates to Grafana via browser session cookies:
- Log in to Grafana in your browser
- DevTools → Application → Cookies
- Copy
grafana_sessionandgrafana_session_expiryvalues - Save to
grafana-session.txt(seegrafana-session.example.txtfor format):
grafana_session=abc123...; grafana_session_expiry=xyz789...
Sessions are short-lived — refresh manually when expired.
Two IDs for your Loki datasource:
LOGS_ANALYZER_GRAFANA_DATASOURCE_UID— Grafana → Connections → Data Sources → your Loki. UID is in the URL:.../datasources/edit/<UID>LOGS_ANALYZER_GRAFANA_DATASOURCE_NUMERIC_ID— Open DevTools → Network, run any query in Explore, find request to/api/ds/query— numeric ID is in the payload (datasourceIdfield)
LOGS_ANALYZER_SEARCH_LOG_STREAM_SELECTOR is the base LogQL stream selector prepended to every query. Scopes all searches to your target services:
{namespace="production", service_name=~"my-service-.*"}
Use the same selector you'd use in Grafana Explore.
./agentType your query and press Enter twice to submit. The agent handles the rest.
Every investigation is saved as a JSON file in completed_investigations/:
completed_investigations/investigation_2026-04-29_09-52-49.json
Each file contains:
| Field | Description |
|---|---|
Findings |
List of discoveries, each with description, evidence, and confidence (0–1) |
StepSummaries |
One-sentence summary of what each search step found |
StepCount |
Total number of search iterations used |
HitStepLimit |
Whether the agent exhausted max steps before finishing |
History |
Full LLM message history (useful for debugging agent behavior) |
{
"description": "No merchant currency events were received from processing in the last 24 hours",
"evidence": "Three search strategies all returned zero results for ProcessingMerchantCurrencyEventConsumer over 2026-04-28 to 2026-04-29",
"confidence": 0.95
}Edit prompts/business_knowledge.md to teach the agent about your system — entity definitions, identifier formats, service names, and log structure. This knowledge is injected into both parsing and search stages.
# Unit tests
go test -short ./internal/...
# Grafana integration tests (requires valid session)
go test -v ./tests/grafana/...