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
qr//compiles the pattern once;(?<level>...)names each capture.- Matches land in
%+, and a hash slice unpackstime,level, andmsg. push @{ $by_level{$level} }groups messages under their severity.- The report counts each bucket, then replays the
ERRORlines with times.
Keywords and builtins used here
forifkeysmynextprintprintfpushscalarsortsplitunlessuse
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.
Step 3 of 3 in Encore, step 27 of 27 in Language basics.