Programming from zero

Analyze a log file and count entries by level

mediumMini scripts — put it all together

Problem statement

This mini script reads a log file and counts how many lines each level has. It uses file reading, string splitting and a dictionary used as a counter.

Every log line starts with its level, then a space, then the message. Splitting the line on spaces makes the level the first piece.

  • Read the file one line at a time.
  • Split the line and take the first piece.
  • Add one to that level's count in a dictionary.

Common mistake: adding to a count that does not exist yet.

TEXT
Wrong:
counts[level] += 1
KeyError: 'INFO' (first time this level is seen)

The first time a level appears it has no entry. Start from 0 when the key is missing: counts.get(level, 0) + 1.

Your task: app.log has six lines (the code below creates it). Count the lines per level and print <level>: <count>, sorted by level name.

Expected output

TEXT
ERROR: 2
INFO: 3
WARN: 1

Approach

Split each line, count the first word, then print the levels in sorted order:

  • Python: line.split()[0] is the level. counts.get(level, 0) + 1 handles a missing key. sorted(counts) gives the names in order.
  • Java: line.split(" ")[0] is the level. counts.getOrDefault(level, 0) + 1 handles a missing key. A TreeMap keeps its keys sorted.
  • C++: stream >> level reads the first word. counts[level]++ starts a missing key at 0. std::map keeps its keys sorted.

Note on order: all three print in sorted order of the level name, so the output matches.

# Setup: create a small sample log
with open("app.log", "w") as f:
    f.write("INFO server started\nINFO request ok\nERROR db timeout\nWARN cpu high\nINFO request ok\nERROR disk full\n")

counts = {}
with open("app.log") as f:
    for line in f:
        level = line.split()[0]
        counts[level] = counts.get(level, 0) + 1

for level in sorted(counts):
    print(f"{level}: {counts[level]}")