Parse and Summarize HTTP Access Logs
Company: Apple
Role: Software Engineer
Category: Software Engineering Fundamentals
Difficulty: easy
Interview Round: Technical Screen
## 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:
```text
<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.
```hint Validate the whole token
Converting the prefix of `500oops` to an integer would incorrectly turn a malformed line into a server error.
```
### 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.
```hint Pick the denominator explicitly
If malformed lines are excluded from `total_requests`, they must also be excluded from the failure percentage denominator.
```
### 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.
```hint Test adjacent status classes
The values immediately around `400` and `500` reveal off-by-one errors in the range checks.
```
### What a Strong Answer Covers
- Separates parsing validity from metric aggregation.
- Uses one documented denominator and handles an empty valid set.
- Rejects partial parses and extra fields consistently.
- Runs in linear time over the input bytes and can aggregate a stream without storing every record.
### Follow-up Questions
1. How would quoted fields or paths containing spaces change the parser?
2. What should happen if timestamps with different valid offsets are accepted?
3. How would you cap invalid-line diagnostics during a malformed-log spike?
4. Which metrics would reveal that an upstream format deployment broke parsing?
Quick Answer: 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.