🎓 A1Learner
🔍
0 of 50 lessons completed

Haskell Project: Log Analyzer

A log analyzer is a program that reads a log file and counts what it finds. It turns raw lines into a short summary a reader can check.

A log is written and read in one program

This program writes three log lines and reads them back. The printed count is the number of lines.

main :: IO ()
main = do
  writeFile "log-a.txt" "INFO start\nERROR disk full\nINFO done\n"
  content <- readFile "log-a.txt"
  print (length (lines content))

Error lines are counted and listed

This log holds two error lines among four lines. The count and the error lines are printed.

import Data.List (isPrefixOf)
main :: IO ()
main = do
  writeFile "log-b.txt" "INFO start\nERROR disk full\nERROR out of memory\nINFO done\n"
  content <- readFile "log-b.txt"
  let errors = filter (isPrefixOf "ERROR") (lines content)
  print (length errors)
  print errors

Each kind of line gets its own count

This summary counts each kind separately. The four numbers are the total, the information count, the warning count, and the error count.

import Data.List (isPrefixOf)
main :: IO ()
main = do
  writeFile "log-c.txt" "INFO start\nWARN slow disk\nERROR disk full\nINFO done\nWARN retry\n"
  content <- readFile "log-c.txt"
  let ls = lines content
  print (length ls)
  print (length (filter (isPrefixOf "INFO") ls))
  print (length (filter (isPrefixOf "WARN") ls))
  print (length (filter (isPrefixOf "ERROR") ls))

Example

import Data.List (isPrefixOf)
main :: IO ()
main = do
  writeFile "log-main.txt" "INFO start\nINFO user login\nERROR disk full\nWARN slow disk\nERROR out of memory\nINFO done\n"
  content <- readFile "log-main.txt"
  let ls = lines content
  print (length ls)
  print (length (filter (isPrefixOf "ERROR") ls))
  print (length (filter (isPrefixOf "INFO") ls))
  print (filter (isPrefixOf "ERROR") ls)

Key points

  • Log line: one line of text recording one event, such as an error or an information message.
  • Use writeFile to create the log inside the same program that reads it.
  • Use lines to split the file text into separate log lines.
  • Use filter with a prefix test to count only the lines of one kind.
  • Use length on a filtered list to get the count for that kind.

In this example, the program writes a six-line log and reads it back. It prints the total line count, then the error count, then the information count, then the error lines themselves.

Note

readFile gives the file text lazily, so the program measures or prints it before writing the same path again.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Haskell Playground

Exercise

A log holds INFO start, ERROR disk full, and INFO done. How many error lines does the analyzer count?