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 errorsEach 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?