If you’ve ever debugged a web application, you’ve probably done this more than you’d like to admit. An error pops up. You scroll through your logs. You find what looks important. You copy a chunk of it. Then you paste it somewhere. Maybe into a chat with a teammate, maybe into a document, or increasingly, into an AI tool to help you make sense of it.
I’ve been in your shoes, and at some point, I felt like this needed to stop. So, I carefully crafted a solution that takes care of this manual log handling.
Crafting an automation system for parsing logs
Letting a script handle manual workflow
Logs are already structured text. With a small script, I could pull out only the important parts, clean them up, and format them into something readable, automatically. The idea was simple: take the exact workflow I was repeating by hand, and turn it into something I could run with a single command. A reusable script.
To test this idea, I used a tiny demo web app that randomly throws errors and writes them to a log file. If you want to follow along, I’ve put the code up on my GitHub. But you don’t need this exact setup. Any application that writes logs to a file will work the same way. The only thing that matters for now is a growing log file with a mix of useful errors and some noise around them.
Instead of manually digging through logs every time, I wrote a small, smart Python script to do the boring part for me. The idea is simple: read the log file, pull out only the error sections, clean them up, and save them into a Markdown file I can use anywhere. Here’s a minimal version of the script:
from datetime import datetime
LOG_FILE = "app.log"
def is_new_log_entry(line):
return any(level in line for level in ["INFO", "WARNING", "DEBUG", "ERROR"])
def extract_errors(lines):
errors = []
current_error = []
capturing = False
for line in lines:
if "ERROR" in line:
if current_error:
errors.append("".join(current_error))
current_error = []
capturing = True
elif capturing and is_new_log_entry(line):
errors.append("".join(current_error))
current_error = []
capturing = False
if capturing:
current_error.append(line)
if current_error:
errors.append("".join(current_error))
return errors
def format_markdown(errors):
formatted = []
for i, error in enumerate(errors, 1):
block = f"### Error {i}\n```\n{error.strip()}\n```"
formatted.append(block)
return "\n".join(formatted)
def save_report(content):
timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M")
filename = f"error_report_{timestamp}.md"
with open(filename, "w") as f:
f.write("# Error Report\n")
f.write(content)
print(f"Saved: {filename}")
def main():
with open(LOG_FILE, "r") as f:
lines = f.readlines()
errors = extract_errors(lines)
if not errors:
print("No errors found.")
return
report = format_markdown(errors)
save_report(report)
if __name__ == "__main__":
main()
There are four small steps happening here:
- Read the log file: The script loads the log file into memory as a list of lines. This makes it easier to process logs one step at a time instead of dealing with one big chunk of text.
- Extract only error logs: Whenever a line contains “ERROR”, the script treats that as the beginning of a new error block. From that point on, it starts collecting every line that belongs to that error, including the full traceback.
- Capture the full error block: Instead of guessing where the error ends, the script keeps collecting lines until it hits the start of a new log entry (like “INFO” or another “ERROR”.) This ensures you get the entire stack trace without cutting anything off.
- Format the output: Each error is wrapped in a clean Markdown block, making it easy to read, share, or paste into other tools.
- Save it with a timestamp: Finally, the script writes everything to a new file with a timestamped name, so you don’t overwrite previous reports:
error_report_2026-04-16_14-32.md
Python in Excel isn’t just for programmers—4 useful things you can do with it right now
Turn Excel into a lightweight data-science tool for cleaning datasets, standardizing dates, visualizing clusters, and analyzing keywords.
The result
What my workflow looks like with the script in action
After hitting the error endpoint a few times, my raw log file (app.log) looked like this:
2026-04-17 19:57:58,880 - INFO - Root endpoint was called
2026-04-17 19:58:17,147 - INFO - Root endpoint was called
2026-04-17 19:58:32,806 - INFO - Root endpoint was called
2026-04-17 19:58:42,878 - INFO - Error endpoint was called
2026-04-17 19:58:42,878 - ERROR - Exception occurred in /error endpoint
Traceback (most recent call last):
File ".../main.py", line 28, in trigger_error
result = 10 / 0
ZeroDivisionError: division by zero
2026-04-17 19:58:56,878 - INFO - Root endpoint was called
2026-04-17 19:58:59,833 - INFO - Root endpoint was called
2026-04-17 19:59:02,997 - INFO - Error endpoint was called
2026-04-17 19:59:02,997 - ERROR - Exception occurred in /error endpoint
Traceback (most recent call last):
File ".../main.py", line 28, in trigger_error
result = 10 / 0
ZeroDivisionError: division by zero
...
It’s a mix of everything: successful requests, repeated noise, and the actual errors buried in between. After running the script, I got a clean Markdown report:
# Error Report
### Error 1
```
2026-04-17 19:58:42,878 - ERROR - Exception occurred in /error endpoint
Traceback (most recent call last):
File "D:\Content Writing\How-To Geek\automate logs\demo-webapp-error\main.py", line 28, in trigger_error
result = 10 / 0
~~~^~~
ZeroDivisionError: division by zero
```
...
Each error is isolated, complete, and already formatted in a way that’s easy to read or share.
Now, you can use this script and take the automation to the next level by integrating Slack, an LLM, or any other service where you’d want to copy and paste this log. That way, the logs will automatically reach where you want them to be.
18 Bash string tricks that fix common scripting headaches
Unlock the power of Bash strings with these clever techniques.
Automation saves the day
This was a fun experiment, but it has changed my outlook towards scripting and automation. With such a simple but useful Python script, I was able to save hours of headache and manual work.
- Brand
-
Apple
- Operating System
-
macOS



