Regular expressions & Counter
Count status codes in a log
Lesson 15 of 20 · 11 min · Module 5: Logs and evidence
Web server logs record every request. Counting status codes shows at a glance whether users are getting pages (2xx), mistakes (4xx), or failures (5xx).
Start this lesson →Free. No installation: you write and run the code in your browser, and it is checked automatically.
By the end, you’ll be able to…
- Match structured text with a regular expression
- Count values with Counter
- Turn counts into a rate safely
The idea
A regular expression describes the shape of a line. re.search(r'" (\d{3}) ', line) finds a three-digit code after the closing quote of the request. collections.Counter counts things for you.
import re
line = '192.168.1.20 - - [18/Oct/2026:08:00:01] "GET / HTTP/1.1" 200 512'
print(re.search(r'" (\d{3}) ', line).group(1))
01Anchor the pattern
\d{3} alone would also match parts of the date or the byte count. Requiring a quote and a space before the code, and a space after it, targets exactly the status field.
02Counter counts
Counter()[key] += 1 starts every new key at 0, so you never have to check whether the key exists. dict(counter) turns it back into a plain dictionary.
from collections import Counter
c = Counter(["200", "404", "200"])
print(c.most_common(1))[('200', 2)]03Rates need a guard
An empty log has 0 requests. Dividing by zero raises ZeroDivisionError, so handle that case first and return 0.0.
Your turn
status_counts(log_text) that returns a dict mapping each status code (as an int) to the number of requests with it. Skip lines that do not match. Write error_share(log_text) that returns the share of requests with a 4xx or 5xx code, rounded to 2 decimals (0.0 for an empty log).What the checks look for
- Counts each status code
- Skips malformed lines
- Calculates the error share
- Returns 0.0 for an empty log
Take this with you
A precise pattern plus Counter turns a raw log into numbers you can act on.
Go a little further
Return the three most requested paths using a second regular expression and Counter.most_common(3).