Capstone: Server Log Analyzer
Lesson 5 of 5 · View course roadmap
Learn the idea
The capstone. Real servers write logs like:
2026-07-19 12:01:33 GET /api/courses 200
2026-07-19 12:01:35 GET /api/missing 404
Ops engineers get paid to answer: how many requests? how many errors? which endpoint is hottest? You now have every tool required:
splitlines()+split()to parse each line- Conditions to classify status codes
Counterto rank endpoints- f-strings to report
This exact pattern — parse, filter, aggregate, report — is the backbone of data engineering. Nail this and you're ready for real-world scripting work.
Where you'll use this
This is a junior DevOps/data task verbatim: 'how many 5xx errors since the deploy?' Splunk, Datadog and the ELK stack are this loop at planetary scale — you just built the core of an observability product.
Common mistakes
- Assuming every line is well-formed — production logs contain partial lines and garbage; guard with a length check or try/except per line.
- Reading a huge file into one string — iterate line by line and it streams in constant memory (works on files bigger than RAM).
- Counting with nested ifs when Counter does it declaratively — less code, fewer bugs.
Pro tip
Add argparse and your script becomes a real CLI tool: python analyze.py access.log --since 12:00. That jump — from script to tool a teammate can run — is what gets automation adopted.
Try it yourself
The lesson example is loaded and ready — press Run, then change something and run it again. Breaking it is part of learning. Want a clean slate? Tap “New blank”.
Output appears here…
Pass the challenge +60 XP
Analyze the log in the starter. Print: total number of requests, number of error responses (status ≥ 400), and the most-requested path.
6 2 /api/courses
Split each line with .split(); status is int(parts[4]); Counter the paths and use most_common(1).
from collections import Counter
log = """2026-07-19 12:01:33 GET /api/courses 200
2026-07-19 12:01:35 GET /api/missing 404
2026-07-19 12:02:01 POST /api/login 200
2026-07-19 12:02:20 GET /api/courses 200
2026-07-19 12:03:00 GET /api/courses 500
2026-07-19 12:03:41 GET /api/lessons 200"""
lines = log.splitlines()
paths = Counter()
errors = 0
for line in lines:
parts = line.split()
paths[parts[3]] += 1
if int(parts[4]) >= 400:
errors += 1
print(len(lines))
print(errors)
print(paths.most_common(1)[0][0])
Run your code to check it…
Check your understanding
Your notes (saved on this device)
Tip: use ← and → to move between lessons, ⌘K to search everything.