typestar

log_parser.pl in Perl

Buckets log lines by severity with one named-capture regex.

use strict;
use warnings;

# log_parser: bucket log lines by level with a named-capture regex

my $log = <<'LOG';
2026-08-02 09:14:02 INFO  server started on port 8080
2026-08-02 09:14:05 INFO  connected to database
2026-08-02 09:15:11 WARN  slow query took 1200 ms
2026-08-02 09:16:40 ERROR connection reset by peer
2026-08-02 09:16:41 INFO  retrying in 2 s
2026-08-02 09:17:03 WARN  cache miss rate above 20 pct
2026-08-02 09:18:22 ERROR disk usage at 95 pct
LOG

my $pat = qr/^\S+ (?<time>\S+) (?<level>INFO|WARN|ERROR)\s+(?<msg>.+)$/;

my %by_level;
my @errors;

for my $line (split /\n/, $log) {
    next unless $line =~ $pat;
    my ($time, $level, $msg) = @+{qw(time level msg)};
    push @{ $by_level{$level} }, $msg;
    push @errors, "$time  $msg" if $level eq "ERROR";
}

print "lines by level:\n";
for my $level (sort keys %by_level) {
    printf "  %-5s %d\n", $level, scalar @{ $by_level{$level} };
}

print "errors:\n";
print "  $_\n" for @errors;

How it works

  1. qr// compiles the pattern once; (?<level>...) names each capture.
  2. Matches land in %+, and a hash slice unpacks time, level, and msg.
  3. push @{ $by_level{$level} } groups messages under their severity.
  4. The report counts each bucket, then replays the ERROR lines with times.

Keywords and builtins used here

The run, in numbers

Lines
34
Characters to type
942
Tokens
144
Three-star pace
85 tpm

At the three-star pace of 85 tokens a minute, this run takes about 102 seconds.

Type this snippet

Step 3 of 3 in Encore, step 27 of 27 in Language basics.

← Previous