Katkat

Parse and Summarize HTTP Access Logs

AppleSoftware Engineer · Technical Screen

Last updated

Parse a strict HTTP access-log format and summarize valid requests, client errors, server errors, invalid lines, and failure percentage. The prompt tests full-field validation, precise metric denominators, status boundaries, streaming aggregation, and privacy-safe diagnostics.

Parse and Summarize HTTP Access Logs

Given a list of raw access-log strings, parse valid records and report the number of total requests, client errors, server errors, and the overall failure percentage.

For this exercise, use the concrete format:

<ip_address> <timestamp> <path> <status_code>

Fields are separated by one or more ASCII spaces. timestamp is an RFC 3339 timestamp without spaces, path begins with / and contains no spaces, and status_code is a three-digit integer from 100 through 599. An IP address must be accepted by a standard IPv4 or IPv6 parser. A line is valid only when it has exactly these four fields and every field passes validation.

Constraints & Assumptions

  • Invalid lines are counted separately and excluded from all request and failure denominators.
  • A 4xx status is a client error and a 5xx status is a server error.
  • A failed request is either a client error or server error.
  • failure_percent = 100 * failed_requests / total_requests; return 0 when there are no valid requests.
  • Do not infer missing fields or accept a numeric status prefix followed by extra characters.

Part 1 — Parse and Validate One Record

Describe or implement a parser that returns a typed record or a classified validation error. Explain how it avoids accepting malformed timestamps, IP addresses, paths, or status codes.

What This Part Should Cover

  • Exact field-count validation before indexing fields.
  • Standard-library IP and RFC 3339 parsing where available.
  • Full-string status parsing and range validation.
  • A typed success/error result rather than an unchecked exception.

Part 2 — Aggregate the Metrics

Process all lines and return total_requests, client_errors, server_errors, failed_requests, failure_percent, and invalid_lines.

What This Part Should Cover

  • Incrementing the valid-request denominator exactly once per valid record.
  • Nonoverlapping status-range counters.
  • A defined zero-denominator result.
  • Numeric precision and when percentage rounding, if any, occurs.

Part 3 — Test and Scale the Parser

Give representative tests and explain how the implementation changes when logs arrive as a stream rather than an in-memory list.

What This Part Should Cover

  • Boundary statuses such as 399, 400, 499, 500, and 599.
  • Missing, extra, and malformed fields plus valid IPv4 and IPv6 lines.
  • Streaming aggregation with constant metric state.
  • Observability for invalid-line reasons without logging sensitive request data.

Hints

Hint 1

Validate the whole token: Converting the prefix of `500oops` to an integer would incorrectly turn a malformed line into a server error.

Hint 2

Pick the denominator explicitly: If malformed lines are excluded from `total_requests`, they must also be excluded from the failure percentage denominator.

Hint 3

Test adjacent status classes: The values immediately around `400` and `500` reveal off-by-one errors in the range checks.

Follow-up questions

  • How would quoted fields or paths containing spaces change the parser?
  • What should happen if timestamps with different valid offsets are accepted?
  • How would you cap invalid-line diagnostics during a malformed-log spike?
  • Which metrics would reveal that an upstream format deployment broke parsing?