A log summary is useful only if you know which records were counted and which were rejected. Start with a documented input format and a small synthetic sample before trying to parse production logs. Counter makes aggregation straightforward, but it cannot decide whether your parsing assumptions are correct.
For this example, every non-empty line contains an event label and an HTTP status separated by one space. Real access logs often contain quoted values, spaces and optional fields; a naive split is not a general parser for those formats. Prefer structured logs when you control the application.
from collections import Counter
sample = ["GET / 200", "GET /courses 200", "GET /missing 404", "broken"]
counts = Counter()
rejected = 0
for line in sample:
try:
event, raw_status = line.rsplit(" ", 1)
status = int(raw_status)
if not event or not 100 <= status <= 599:
raise ValueError("invalid record")
except ValueError:
rejected += 1
else:
counts[status] += 1
assert counts[200] == 2
assert counts[404] == 1
assert rejected == 1An error percentage needs a denominator. If malformed records are excluded, show that count alongside accepted records; otherwise an improvement in error rate might merely reflect a broken parser. State whether you count all requests, only completed requests or a filtered subset.
The sample has no timestamps and therefore cannot answer when errors occurred. For a time-window summary, parse timestamps with explicit time zones and define inclusive and exclusive boundaries. Compare windows with similar traffic patterns rather than assuming two raw totals describe a trend.
A 404 does not by itself prove a bug or an attack, and a 200 does not prove a business operation succeeded. Grouping by status is a starting point for investigation. Retain the ability to trace a suspicious aggregate back to the relevant sanitized records, while avoiding unnecessary retention of personal data.
Add totals for 2xx, 4xx and 5xx classes, plus accepted and rejected records. Test 99, 600 and an empty line. Write a sentence explaining what your summary cannot tell a reader about the health of the application.
Explore the related Code Hacker course syllabus for structured learning. Then read Normalize Time Zones Before Building a Forensic Timeline to connect this exercise to the next skill.
Python collections.Counter provides the underlying API or technical guidance. Check the documentation for the version you use; examples here are small learning exercises rather than complete production implementations.
Found an issue with this guide? Send a correction with the article URL and your example. About our learning material.
Subscribe to Code Hacker and get hands-on access to 40+ premium courses — Ethical Hacking, Kali Linux, Metasploit, Network Hacking, Bug Bounty & more!