Endpoint p95 board
EasyOnline Assessment
Build a slowest-endpoints board from a web server's access log, using the nearest-rank 95th percentile of each endpoint's response times.
Each log line is a string "METHOD TARGET STATUS MS": the HTTP method, the requested target, the response status code, and the response time in milliseconds, separated by single spaces. The endpoint of a line is its method plus the target's path, where the path is the target with everything from the first ? onwards removed. So GET /cart?id=7 and GET /cart are the same endpoint, but POST /cart is a different one. Paths are case-sensitive.
Two kinds of lines are ignored entirely, as if they were not in the log:
- lines whose status is
500or higher (the server failed, so the time says nothing about normal work); - lines whose time is more than 10,000 ms (a time of exactly 10,000 ms is kept).
After that, an endpoint is reported only if it has at least 5 remaining lines. For a reported endpoint with n remaining times, sort them ascending; its 95th percentile is the time at rank ceil(0.95 * n) (rank 1 is the smallest). No interpolation: the answer is always one of the recorded times. For example, with n = 20 the rank is 19, and with n = 21 it is 20.
Input: lines, a list of strings in the format above.
Output: a list of strings "METHOD PATH P95", one per reported endpoint, ordered by 95th percentile descending; endpoints with equal percentiles are ordered by their "METHOD PATH" text in ascending lexicographic order. If no endpoint qualifies, return [].
Example 1
- Input:
- [["GET /cart 200 120","GET /cart?id=7 200 90","GET /cart 200 80","GET /cart 503 9000","GET /cart 200 95","POST /cart 201 300","GET /search 200 40","GET /search 200 60","GET /search 200 35","GET /search 404 50","GET /search 200 45","GET /cart 200 110","GET /cart 304 200","GET /search 200 50"]]
- Output:
- ["GET /cart 200","GET /search 60"]
- Explanation
GET /carthas six usable lines: 120, 90 (the?id=7target is the same endpoint), 80, 95, 110 and 200; the503line is ignored. Sorted they are 80, 90, 95, 110, 120, 200, and rank ceil(0.95 * 6) = 6 is 200.GET /searchhas exactly five lines, so it is reported, and rank 5 is its largest time, 60.POST /carthas a single line and is left out. Ordered by percentile:GET /cart 200, thenGET /search 60.
Example 2
- Input:
- [["GET /feed 200 10","GET /feed 200 20","GET /feed 200 30","GET /feed 200 40","GET /feed 200 50","GET /feed 200 60","GET /feed 200 70","GET /feed 200 80","GET /feed 200 90","GET /feed 200 100","GET /feed 200 110","GET /feed 200 120","GET /feed 200 130","GET /feed 200 140","GET /feed 200 150","GET /feed 200 160","GET /feed 200 170","GET /feed 200 180","GET /feed 200 190","GET /feed 200 200","GET /feed 200 10000","GET /feed 200 10001","GET /ping 200 12","GET /pong 200 12","GET /pong 200 12","GET /ping 200 12","GET /ping 200 12","GET /pong 200 12","GET /ping 200 12","GET /pong 200 12","GET /pong 200 12","GET /ping 200 12"]]
- Output:
- ["GET /feed 200","GET /ping 12","GET /pong 12"]
- Explanation
GET /feedhas times 10, 20, ..., 200 plus 10000, which is kept because only times above 10,000 are ignored (the 10001 line is dropped). That is n = 21, rank ceil(19.95) = 20, which is the 20th smallest time: 200.GET /pingandGET /pongboth have five times and a percentile of 12; the tie is broken by name, ping first.
Example 3
- Input:
- [["PUT /a 200 5","PUT /a 200 6","PUT /a 500 7","PUT /a 200 8","PUT /a 200 9","GET /b 200 1","GET /b 200 2","GET /b?x=1 200 3","GET /b 200 4"]]
- Output:
- []
- Explanation
PUT /ahas five lines but one has status 500, which leaves four;GET /bhas only four lines. Neither reaches five usable lines, so nothing is reported.
Constraints
0 <= lines.length <= 2,000- Every line is
"METHOD TARGET STATUS MS"with no spaces inside the target;STATUSis 100 to 599 andMSis an integer from 0 to 60,000 - Methods are upper-case words such as
GETorPOST; targets start with/