Web and API Traffic¶
Status codes over time¶
kelora examples/web_access_large.log.gz -e 'track_freq("class", e.status / 100 * 100)' \
--span 30m --span-summary
2025-10-04T08:00:00Z events=287 class.100=16 class.200=65 class.300=41 class.400=101 class.500=64
2025-10-04T08:30:00Z events=279 class.100=20 class.200=62 class.300=38 class.400=78 class.500=81
2025-10-04T09:00:00Z events=304 class.100=15 class.200=60 class.300=49 class.400=103 class.500=77
2025-10-04T09:30:00Z events=326 class.100=10 class.200=86 class.300=40 class.400=105 class.500=85
2025-10-04T10:00:00Z events=4 class.400=1 class.500=3
Which endpoints fail?¶
Strip query strings first, so /products/42?utm_source=… counts as /products/42:
kelora examples/web_access.log -e 'e.path = e.path.split("?")[0]' --filter 'e.status >= 400' --freq path
The slowest endpoints¶
Rank endpoints by their worst response time:
kelora examples/api_latency_incident.jsonl -m \
-e 'track_top_by("slowest", e.endpoint, e.response_time_ms, 3)'
Latency percentiles per endpoint¶
Name the metric after the group to get one set of statistics per value:
kelora examples/api_latency_incident.jsonl -m \
-e 'track_percentiles("ms " + e.endpoint, e.response_time_ms, [0.5, 0.99])'
ms /api/posts_p50 = 99.9901
ms /api/posts_p99 = 880.159
ms /api/search_p50 = 58.6271
ms /api/search_p99 = 888.357
ms /api/users_p50 = 94.7381
ms /api/users_p99 = 796.484
To rank by one percentile, pipe the TSV through sort:
… | grep _p99 | sort -t$'\t' -k3 -rn. Access logs parsed as combined call
the fields path, status, bytes, and (nginx) request_time.
Browsers and operating systems¶
kelora examples/web_access_large.log.gz \
-e 'let ua = e.user_agent.parse_user_agent(); e.browser = ua.get("agent_family") ?? "other"' \
--freq browser