Analyzing logs with AI: from thousands of lines to a clear cause of failure
Do not send gigabytes of logs to a model. Filter, group by templates, ask for hypotheses tied to lines and verify them. Code and price estimate inside.
4 min · · автоматизация · development
AI for log analysis finds patterns in noise well, but it has two weaknesses: huge volumes and a tendency to produce a plausible story instead of a verified one. The fix is the same for both: put a filter and compression before the model, and a hypothesis check after it. Below is a working scheme: how to reduce a million lines to a few thousand tokens, what to ask the model, how to check the answer and what it costs. The same approach fits other large texts: exports, correspondence, reports.
Why you cannot just send the whole file
Logs are heavy. As a rough guide take a 100-character line as 30 tokens (the number differs for different logs and languages; the exact value comes from token counting). Then a million lines is 30M tokens: more than the context of any model in the catalog (most have 1M, Grok 256K, GLM 128K). And even if it fit, you would pay for input on all the repeating lines. Besides, with very long contexts models may notice details in the middle less well: test this on your data.
So we work in four steps.
Step 1. Narrow by time and level
An incident almost always has a window: from the first alert to recovery. Take it with a margin and drop the DEBUG and INFO levels unless you suspect the cause is in them.
awk '$1 >= "2026-10-18T09:40" && $1 <= "2026-10-18T10:20"' app.log \
| grep -E 'WARN|ERROR|FATAL' > window.log
wc -l window.logThe command takes lines within the incident window, WARN level and above. The time format in awk depends on your log, so adjust it.
Step 2. Fold by templates
Thousands of identical errors differ only in numbers, identifiers and addresses. We replace the variable parts with markers and count how many times each template occurs.
import re
from collections import Counter
PATTERNS = [
(re.compile(r"\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b"), "<UUID>"),
(re.compile(r"\b\d{1,3}(?:\.\d{1,3}){3}\b"), "<IP>"),
(re.compile(r"\b0x[0-9a-fA-F]+\b"), "<HEX>"),
(re.compile(r"\b\d+\b"), "<N>"),
]
def template(line: str) -> str:
for rx, mark in PATTERNS:
line = rx.sub(mark, line)
return lineThe output is a list of a few dozen templates with repeat counts and the number of the first line. This is the main part of the future request. Chronology matters as much as frequency, so we keep the first line number: the template that appeared first is often the cause, and the flood of later ones is the effect.
Step 3. Add context around the first error
Templates lose detail. Add a small raw fragment around the earliest error, for example 30 lines before and 10 after, plus the stack trace if there is one. Scrub secrets (tokens, passwords, customer addresses) before sending.
Step 4. The request: hypotheses with evidence
Do not ask "find the cause"; ask for a structured answer where each hypothesis is tied to lines.
from openai import OpenAI
client = OpenAI(base_url="https://api.zukko.pro/v1", api_key="fetch_your_key")
templates = open("templates.txt", encoding="utf-8").read()
raw = open("first_error_context.txt", encoding="utf-8").read()
prompt = f"""Below is a summary of the logs for the incident window and a raw fragment at the first error.
Summary: line template, repeat count, number of the first line.
SUMMARY:
{templates}
FRAGMENT:The requirement "which command to run to verify" turns the answer from a story into a verification plan. Client documentation: Python SDK.
Verifying hypotheses
The model's answer is a set of hypotheses, not a diagnosis. For each one, run the check from the answer: look at metrics and deploys in the same window, find in the original logs the lines the model refers to, reproduce the error on a stand. If the model names a line number or a function name, find them yourself: invented details happen. Only after that change the system. For hard cases you can continue the dialogue, showing the results of the checks, and ask it to update the hypotheses.
What it costs
Suppose the window has 200,000 lines, and after folding and context 15,000 input tokens remain; the model's answer is 1,500 tokens. Formula without cache: input × input price + output × output price. Prices as of October 18, 2026, $ per 1M tokens:
claude-sonnet-5-5(0.4 / 2): 0.015 × 0.4 + 0.0015 × 2 = 0.006 + 0.003 = $0.009.claude-opus-5-5(0.8 / 4): 0.015 × 0.8 + 0.0015 × 4 = 0.012 + 0.006 = $0.018.deepseek-v4.1-flash(0.013 / 0.038): 0.015 × 0.013 + 0.0015 × 0.038 = 0.000195 + 0.000057 = $0.000252.
For comparison, 200,000 lines without folding (at an assumed 30 tokens per line that is 6M tokens) would not fit in the context of any model in the catalog, and at the Sonnet 5.5 input price would cost 6 × 0.4 = $2.4 per request, without the output. Folding makes the analysis both possible and cheap. Current prices: GET https://api.zukko.pro/v1/models; you can check the request size in advance via POST /v1/messages/count_tokens.
If there are very many logs, you can use a two-stage scheme: a cheap model labels blocks, a strong one analyses the selected ones. The topic is covered in detail in the article on summarizing long documents.
Connecting
The scripts above work with any OpenAI-compatible client: create a key in the dashboard and set the base URL https://api.zukko.pro/v1. You can top up the balance via SBP, a MasterCard card or cryptocurrency. If you do not use Python, see the Chat Completions page.
FAQ
Can I send production logs to a model?
Only after scrubbing secrets and personal data and in line with your company's policy. Scrub tokens, e-mails and phone numbers automatically, and review the final request by hand.
Will AI for analyzing large texts understand any log format?
For typical formats (text lines, JSON lines), yes. For an exotic format, give one or two sample lines in the request with an explanation of what each field means.
Why did the model name a cause that turned out to be wrong?
A model gives the most plausible explanation from the data you showed it. If the data is thin, the story can be wrong. That is why you ask for hypotheses with verification and a statement of missing data.
Which model should I take?
A cheap one is enough for folding and first-pass labelling; for analysing a hard failure try a stronger one. Compare on a past incident whose cause you already know.
zukko
Pay 25×
less
for Claude Code & ChatGPT
One fetch_* key and base URL api.zukko.pro — for Cursor, Claude Code, Codex, and any SDK.
Related articles
- Translating subtitles with a neural network: SRT without broken timecodesThe main risk when translating SRT with a neural network is a broken file structure. A scheme where timecodes never reach the model, and a Python script with validation.
- Editing texts with a neural network: proofreading, style and cuttingDifferent kinds of editing need different prompts. Wording for proofreading, style and cutting, how to get edits with explanations and how not to lose the author's voice.
- A neural network for writing scripts: Bash, PowerShell and PythonA model writes scripts for routine fast, but running them blindly is risky. How to state the task, demand a safe dry-run mode and check the result before launch.
- Dify in Docker: installation, first-run setup and connecting modelsInstall Dify with Docker Compose, create the admin account and connect Claude, GPT and DeepSeek models on one key. Plus what to do when containers will not start.