I Built an AI Agent That Reads My Error Logs
Learn to build a Python AI agent that watches error logs, classifies issues, and suggests fixes using OpenAI's API.
The problem: drowning in log files
Every developer knows the feeling: your app is in production, users are reporting issues, and you have gigabytes of logs but no idea where to start. Grepping for 'ERROR' gives you a wall of text. You spend hours correlating timestamps, stack traces, and service names before you even understand what broke.
I built a small AI agent that watches my error logs, classifies each error, and suggests a fix. It doesn't replace debugging, but it turns a firehose into a triage list. In this post, I'll show you how to build the same thing, step by step, with Python and the OpenAI API.
Before you start
You need Python 3.10 or later, an OpenAI API key, and a log file to test with. If you don't have a real log file, I'll provide a sample generator so you can follow along.
Install the required packages:
pip install openai python-dotenv- Set your OpenAI API key as an environment variable OPENAI_API_KEY.
- Create a directory for the project and a logs folder inside it.
- Make sure your log file is in plain text (e.g., app.log).
Step 1: Generate sample error logs
If you don't have a real log file, use this script to create a realistic one. It writes a mix of INFO, WARNING, and ERROR lines with timestamps and stack traces.
import random
import datetime
def generate_log_line():
now = datetime.datetime.now().isoformat()
level = random.choices(['INFO', 'WARNING', 'ERROR'], weights=[0.7, 0.2, 0.1])[0]
if level == 'ERROR':
msg = random.choice([
'Connection refused to database at 10.0.0.5:5432',
'Timeout waiting for response from payment service',
'Invalid JSON payload in request body: expected property "user_id"',
'Disk quota exceeded for user 12345',
'Unhandled exception: KeyError: "session_id"'
])
return f"{now} ERROR {msg}\nTraceback (most recent call last):\n File \"/app/main.py\", line 42, in handle_request\n user = db.get_user(request.user_id)\n File \"/app/db.py\", line 18, in get_user\n raise KeyError('session_id')\n"
elif level == 'WARNING':
msg = random.choice([
'Slow query detected: SELECT * FROM orders WHERE user_id = 12345 took 1.2s',
'Cache miss rate above 10% for endpoint /api/v1/products'
])
return f"{now} WARNING {msg}\n"
else:
msg = random.choice([
'Health check passed',
'User 12345 logged in',
'Request completed in 0.23s'
])
return f"{now} INFO {msg}\n"
with open('logs/app.log', 'w') as f:
for _ in range(1000):
f.write(generate_log_line())
print('Generated logs/app.log')- Run this script once to create a test log file.
- Adjust the weights to get more or fewer errors.
Step 2: Define the agent's tools
Our agent needs two tools: one to read the latest error lines from the log, and one to search the log for a pattern. We'll define these as Python functions and then give them to the OpenAI API as function schemas.
import json
import re
def read_errors(max_lines=10):
"""Read the last max_lines error lines from the log."""
errors = []
with open('logs/app.log', 'r') as f:
lines = f.readlines()
for line in lines:
if 'ERROR' in line:
errors.append(line.strip())
return json.dumps(errors[-max_lines:])
def search_log(pattern, max_lines=5):
"""Search the log for lines matching the regex pattern."""
matches = []
with open('logs/app.log', 'r') as f:
lines = f.readlines()
for line in lines:
if re.search(pattern, line, re.IGNORECASE):
matches.append(line.strip())
return json.dumps(matches[-max_lines:])
# Tool schemas for the OpenAI API
TOOLS = [
{
"type": "function",
"function": {
"name": "read_errors",
"description": "Read the most recent error lines from the application log.",
"parameters": {
"type": "object",
"properties": {
"max_lines": {"type": "integer", "description": "Number of error lines to read"}
},
"required": []
}
}
},
{
"type": "function",
"function": {
"name": "search_log",
"description": "Search the log for lines matching a regex pattern.",
"parameters": {
"type": "object",
"properties": {
"pattern": {"type": "string", "description": "Regex pattern to search"},
"max_lines": {"type": "integer", "description": "Maximum number of matches to return"}
},
"required": ["pattern"]
}
}
}
]Step 3: Build the agent loop
The agent loop sends a user prompt to the OpenAI chat completions API. If the model decides to call a tool, we execute the function and send the result back. We repeat until the model gives a final answer.
from openai import OpenAI
import os
client = OpenAI(api_key=os.environ['OPENAI_API_KEY'])
def run_agent(prompt):
messages = [{"role": "user", "content": prompt}]
for _ in range(5): # max 5 tool call rounds
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
tools=TOOLS,
tool_choice="auto"
)
msg = response.choices[0].message
if msg.tool_calls:
messages.append(msg)
for call in msg.tool_calls:
if call.function.name == "read_errors":
args = json.loads(call.function.arguments)
result = read_errors(args.get("max_lines", 10))
elif call.function.name == "search_log":
args = json.loads(call.function.arguments)
result = search_log(args["pattern"], args.get("max_lines", 5))
else:
result = "Unknown tool"
messages.append({
"role": "tool",
"tool_call_id": call.id,
"content": result
})
else:
return msg.content
return "Agent did not converge"
if __name__ == "__main__":
result = run_agent("Read the latest errors and classify them by type. Suggest a fix for each.")
print(result)Step 4: Run the agent
Run the script and see what the agent produces. It should read the log, identify patterns, and give you a categorized report.
python agent.py- The output will be a markdown-like summary with error categories and suggestions.
- If you get an authentication error, check that OPENAI_API_KEY is set correctly.
- You can change the prompt to ask for specific things, like 'Find all database connection errors and suggest a fix'.
Step 5: Add a watchdog loop
To make this truly useful, run the agent periodically. This simple watchdog script checks for new errors every minute and calls the agent when it finds new ones.
import time
def get_last_processed_line():
try:
with open('logs/processed_offset.txt', 'r') as f:
return int(f.read().strip())
except FileNotFoundError:
return 0
def set_last_processed_line(offset):
with open('logs/processed_offset.txt', 'w') as f:
f.write(str(offset))
def watch_log(interval=60):
offset = get_last_processed_line()
while True:
with open('logs/app.log', 'r') as f:
f.seek(offset)
new_lines = f.readlines()
offset = f.tell()
if new_lines:
set_last_processed_line(offset)
errors = [l for l in new_lines if 'ERROR' in l]
if errors:
print(f"Found {len(errors)} new errors, running agent...")
result = run_agent("Here are new errors: " + "\n".join(errors) + "\nClassify and suggest fixes.")
print(result)
time.sleep(interval)
if __name__ == "__main__":
watch_log()What I would do: recommended setup
For a real deployment, I would wrap this in a Docker container and run it as a sidecar to the main application. Store the OpenAI API key in a secret manager, not in the code. Use a more robust log source, like reading from stdout or a log aggregation service.
Here is a minimal Dockerfile to containerize the agent:
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "watchdog.py"]- Create a requirements.txt with openai and python-dotenv.
- Mount your log directory as a volume so the agent can read it.
- Use a process manager like supervisord if you need multiple workers.
Troubleshooting
If you run into issues, here are common problems and fixes.
- OpenAI API error: check your API key and that you have credits.
- Tool call fails: make sure the function name matches exactly and the arguments are valid JSON.
- Agent output is too verbose: limit the number of errors you pass in the prompt.
- Log file not found: verify the path and that the file exists.
FAQ
Here are answers to questions you might have.
- Q: Can I use a different model? A: Yes, any model that supports function calling, like gpt-4 or gpt-3.5-turbo.
- Q: How much does this cost? A: It depends on the number of errors and the model. With gpt-4o-mini and a few errors per minute, it's pennies a day.
- Q: What if I have structured logs (JSON)? A: Adjust the tools to parse JSON lines and extract the error field.
- Q: Can I run this locally without OpenAI? A: You could use a local LLM like Llama 3, but you'd need to adapt the API calls.
Next step
Now that you have a working agent, try it on your own logs. The next action is to copy the agent.py script, set your OPENAI_API_KEY, and run it against a real error log. You'll quickly see which errors matter most.
Key takeaways
- Apply one concrete change from this post before collecting more reading.
- Prefer browser-side tools when the work involves secrets, tokens, or PII.
- Document the why next to the how so the next reviewer inherits context.
FAQ
- Who is this guide on ai-agent for?
- Working developers who need a practical take on i built an ai agent that reads my error logs — not a marketing overview. Skim the sections, apply one tip, then come back when you hit an edge case.
- Do I need an account to use the related tools?
- No. code.live tools run in your browser with no signup. Nothing you paste is uploaded to a server for the client-side utilities linked from this post.
- How often is this article updated?
- This post was published October 2, 2026. Fundamentals stay stable; check linked tool pages and official docs when version-specific behavior matters.