Skip to content

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
path         (4 values):
  value         count
  /admin            1
  /api/reports      1
  /api/upload       1
  /wp-admin         1

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)'
slowest      (3 items):
  item          score
  /api/posts     1000
  /api/search  914.09
  /api/users   913.71

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
browser      (4 values):
  value    count
  Chrome     492
  Safari     248
  other      231
  Firefox    229

Internal versus external clients

kelora examples/web_access.log -m \
  -e 'track_freq("origin", if e.ip.is_private_ip() { "internal" } else { "external" })'
origin       (2 values):
  value     count
  internal     14
  external      6