Help us measure site usage?

With your permission, we use self-hosted analytics to understand page usage. It is optional and does not affect the Service. Learn more.

ScalabeginnercliAI generated

Log Severity Counter

Build a Scala command-line tool that scans log files and counts entries by severity (DEBUG, INFO, WARN, ERROR and FATAL) and by hour, printing a table that shows at a glance when errors spiked. It reads local files, or a log file available at a URL through the http4s client, streams them line by line so large files are fine, and reports lines it can't understand. It's written as a Cats Effect application, keeping reading files and the network separate from the pure counting logic, which is easy to test. You'll learn parsing text with regular expressions, case classes and maps, working with dates using java.time, Cats Effect basics (IO, resources and IOApp), fs2 streams for reading files, and testing with munit.

Estimate
~7h
Steps
6
Completed by
0
Proposed by
codeseed.app

Cats Effect · http4s

Project roadmap

  1. 01

    Define the input and output

    ~1h

    Write README.md: the supported line format (for example 2026-03-15 10:22:01 ERROR payment: timeout, with an option for a custom regular expression), the command (logcount FILE_OR_URL..., with --from and --to times), and the output: counts per severity, a table of hours by severities, and the number of unparsed lines. Create an sbt project with Cats Effect, fs2, the http4s Ember client and munit. Done when: README.md describes the input, options and output.

  2. 02

    Parse lines

    ~1.5h

    Write a pure function that parses a line with a regular expression into a case class LogEntry (timestamp as LocalDateTime, severity as an enum, and message), returning an Option (None for lines that don't match). Accept severity names in any case and common aliases (WARNING for WARN). Done when: unit tests parse valid lines and reject invalid ones.

  3. 03

    Count by severity and hour

    ~1h

    Write a pure function that folds entries into counts: a Map from severity to count, and a Map from hour (the timestamp truncated to the hour) to counts per severity, plus the unparsed count. Apply the --from and --to filter. Done when: counts for a small list of entries match what you expect.

  4. 04

    Read files and URLs

    ~1.5h

    In an IOApp, stream each local file line by line with fs2's Files API, and each http(s) URL through the http4s client (as a Resource with a timeout), decode the lines, parse them and fold them into the counts. Report missing files and failed downloads clearly and continue with the rest. Done when: the tool counts entries from a local file and from a URL served locally.

  5. 05

    Print the report

    ~1h

    Print the totals per severity with percentages, then a table with one row per hour and a column per severity, with the busiest error hour highlighted, and the number of unparsed lines. Exit with a non-zero code when nothing could be read. Done when: the report is aligned and correct for a sample log.

  6. 06

    Test it

    ~1h

    Write munit tests for parsing and counting, and munit-cats-effect tests reading a temporary file and a fake HTTP response. Done when: sbt test passes.

Ready to build this?

Get a GitHub repo and start building. Your AI reviewer checks each step as you go.

~7h · 6 steps

Tech stack

Cats Effecthttp4s