Error minutes
MediumOnline Assessment
Find the minutes in which an API gateway was struggling, from its request log.
Each log entry is a string "ts id path status" with single spaces between the four fields: ts is the time of the request in whole seconds since midnight, id identifies the request, path is the requested path and status is the HTTP status code that was returned. Entries are not necessarily in time order.
Build the picture of each minute like this, in this order:
- Ignore every entry whose
pathstarts with/health. - A client may retry a request, which creates several entries with the same
id. Only the last attempt counts, the entry with the greatestts(if two attempts share thatts, the one that appears later in the list). The earlier attempts are ignored entirely, even if they fall in a different minute. - Drop the remaining entries with status
429. They are rejections by the rate limiter and say nothing about the service. - Each remaining entry belongs to minute
ts // 60(minute 0 covers seconds 0 to 59, minute 1 covers 60 to 119, and so on). It is an error if its status is 500 or higher.
A minute is degraded if it has at least 5 remaining entries and strictly more than 20% of them are errors.
Input: entries, a list of strings in the format above.
Output: the degraded minutes in ascending order, each written as its start time "HH:MM" (24-hour, zero padded), as a list of strings. If no minute is degraded, return [].
Example 1
- Input:
- [["0 q0 /api/items 200","10 q1 /api/items 500","20 q2 /api/items 200","30 q3 /api/items 200","59 q4 /api/items 200","60 q5 /api/items 500","61 q6 /api/items 500","62 q7 /api/items 200","63 q8 /api/items 200","64 q9 /api/items 200"]]
- Output:
- ["00:01"]
- Explanation
- Seconds 0 to 59 are minute 0: five entries with one error is exactly 20%, which is not more than 20%, so 00:00 is fine. Seconds 60 to 64 are minute 1: two errors out of five is 40%, so 00:01 is degraded.
Example 2
- Input:
- [["36000 q10 /api/items 200","36001 q11 /api/items 200","36002 q12 /api/items 200","36003 q13 /api/items 200","36004 q14 /api/items 200","36005 q15 /health/db 500","36006 q16 /health/db 500","36007 q17 /health/db 500","36008 q18 /health/db 500","36060 q19 /api/items 500","36061 q20 /api/items 500","36062 q21 /api/items 500","36063 q22 /api/items 500","36064 q23 /api/items 429","36065 q24 /api/items 429","36066 q25 /api/items 429","36120 q26 /api/items 500","36121 q27 /api/items 200","36122 q28 /api/items 429","36123 q29 /api/items 500","36124 q30 /api/items 200","36125 q31 /api/items 200","36126 q32 /api/items 429"]]
- Output:
- ["10:02"]
- Explanation
- Entries under /health are ignored first (the four 500s in minute 600 vanish). In minute 601 the three 429s are dropped, leaving only four entries, below the minimum of 5. Minute 602 has five entries after dropping its 429s and two errors out of them, so 10:02 is degraded.
Example 3
- Input:
- [["119 a /api/items 500","70 b /api/items 500","75 c /api/items 200","80 d /api/items 200","85 e /api/items 200","121 a /api/items 200","130 g /api/items 500","131 h /api/items 500","140 i /api/items 200","150 j /api/items 200"]]
- Output:
- ["00:02"]
- Explanation
- Request a first failed at second 119 (minute 1) and was retried successfully at second 121 (minute 2). Only the retry counts, so minute 1 is left with four entries and is not degraded, while minute 2 has five entries with two errors: 00:02.
Constraints
0 <= entries.length <= 4000 <= ts <= 86399; ids and paths contain no spaces;100 <= status <= 599