log_analyzer.cs in C#
Regex, LINQ and a little math turn a raw log into answers.
// log_analyzer: parse request lines, bucket by status, find the slow tail
using System.Text.RegularExpressions;
var log = """
GET /api/users 200 45ms
POST /api/login 401 12ms
GET /api/users 200 38ms
GET /static/app.js 200 5ms
POST /api/orders 500 220ms
GET /api/users 304 9ms
""";
var pattern = new Regex(@"(\w+) (\S+) (\d{3}) (\d+)ms");
var requests = log.Split('\n')
.Select(line => pattern.Match(line))
.Where(m => m.Success)
.Select(m => (Path: m.Groups[2].Value,
Code: int.Parse(m.Groups[3].Value),
Ms: int.Parse(m.Groups[4].Value)))
.ToList();
foreach (var group in requests.GroupBy(r => r.Code / 100))
{
Console.WriteLine($"{group.Key}xx: {group.Count()}");
}
var sorted = requests.Select(r => r.Ms).OrderBy(ms => ms).ToList();
var median = sorted[sorted.Count / 2];
Console.WriteLine($"median {median}ms, slowest {sorted[^1]}ms");
var errors = requests.Where(r => r.Code >= 500).Select(r => r.Path);
Console.WriteLine($"5xx on: {string.Join(",", errors)}");
How it works
- One pattern parses verb, path, status and duration per line.
GroupBy(r => r.Code / 100)buckets into 2xx/4xx/5xx.- Sorting durations yields the median and the slowest request.
Keywords and builtins used here
foreachgroupinintnewstaticusingvar
The run, in numbers
- Lines
- 32
- Characters to type
- 971
- Tokens
- 260
- Three-star pace
- 85 tpm
At the three-star pace of 85 tokens a minute, this run takes about 184 seconds.
Step 1 of 2 in Encore, step 16 of 17 in The .NET library.