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.

PerlintermediatedevopsAI generated

Apache Access Analyzer

Build a Perl tool that reads Apache web server access logs and turns them into useful reports: requests per hour, the share of each status code (how many 200s, 404s and 500s), the busiest pages, the slowest ones, and the addresses causing the most errors. The totals are saved to an SQLite database with DBI, so logs can be imported every day and reports can cover weeks, and a log file already imported is never counted twice. The tool can also post a daily summary to a chat webhook with LWP::UserAgent. You'll learn parsing log lines with regular expressions, aggregating data with hashes, using DBI with transactions, making tools safe to re-run, and testing with Test::More.

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

CPAN · DBI · LWP::UserAgent

Project roadmap

  1. 01

    Define inputs, outputs and storage

    ~1.5h

    Write README.md: the input is Apache logs in combined format (plain or .gz), the reports (hourly traffic, status codes, top pages, slowest pages if the log has a response time field, top error sources), and the SQLite tables (hourly totals per path and status, plus the imported files with their size and checksum). Set up a cpanfile with DBI, DBD::SQLite and LWP::UserAgent. Done when: README.md shows example input and output.

  2. 02

    Parse log lines

    ~2h

    Write a parser module with a regular expression for the combined format that extracts the IP, time, method, path, status, size, referrer and user agent. Convert the time to UTC and truncate it to the hour. Remove query strings from paths so /page?id=1 and /page?id=2 count as one. Count lines that don't match instead of failing, and show a few examples. Done when: a sample log parses with the right fields, and malformed lines are counted.

  3. 03

    Aggregate and store with DBI

    ~2.5h

    Aggregate in memory by hour, path and status (count, bytes, total response time), then write the totals to SQLite with prepared statements inside one transaction per file. Record the file's checksum in the imported files table in the same transaction, and skip any file already imported, so running the import twice counts nothing twice. Done when: importing the same log twice leaves the totals unchanged.

  4. 04

    Produce reports

    ~2h

    Add a report command with --from and --to dates that runs SQL queries on the stored totals and prints: requests per hour as a simple text bar chart, status codes with percentages, the 10 busiest paths, the slowest paths by average time, and the top IPs producing errors. Add --format json. Done when: the reports match counts made by hand on a small log.

  5. 05

    Post a summary with LWP

    ~1h

    Add --webhook URL, which posts a short daily summary (total requests, error rate, busiest page) as JSON using LWP::UserAgent with a timeout, retrying once on a network error. A failed post prints a warning but never loses the imported data. Done when: the summary reaches a test webhook, and an unreachable URL only causes a warning.

  6. 06

    Test it

    ~2h

    Write tests in t/ with Test::More: parsing valid and malformed lines, removing query strings, hour grouping across midnight, importing twice (the second import is skipped), and report numbers on a small fixture log with a temporary SQLite database. Done when: prove -l t/ passes.

Ready to build this?

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

~11h · 6 steps

Tech stack

CPANDBILWP::UserAgent