Problem · Array

Incident Monitor

Learn this problem
HardStripe logoStripeFULLTIMEOA
See Stripe hiring insights

Problem statement

Background & Definitions

At Stripe, we monitor millions of transactions hourly to ensure API health. Your goal is to analyze a list of transaction logs, detect error spikes, and trigger alerts when an incident is likely in progress.

Task

Implement the detect_incidents(logs) function. It analyzes a list of transactions (that can be successful or erroneous), and emit alert trigger/resolve events if certain conditions are met.

Sliding Window

For every entry in the transaction log, evaluate whether an alert needs to be triggered or resolved. All evaluations use a 30-second sliding window.

For example, for a log at timestamp T, the window includes all logs with timestamps in the range [T-29, T] (inclusive on both ends).

The evaluation criteria will be described below.

Alert

Each alert is tied to a specific (merchant_id, status_code) pair (details about these fields can be found below, in the Input Format section).

A merchant may therefore have multiple active alerts at once, one per distinct error status code.

De-duplication

If an alert has been triggered for a particular (merchant_id, status_code) pair and is still active (has not been resolved in the meantime), do not trigger a duplicate alert, even if the conditions for the alert continue to manifest.

Input Format

The input (the logs parameter) represents the list of transactions to analyze. It is an array of strings, where each entry has the format: timestamp,merchant_id,status_code,count.

  • timestamp: An integer that represents seconds.
  • merchant_id: The id of the merchant these transactions belong to.
  • status_code: HTTP Status Code. Always one of the following:
    • 200: Represents successful transactions.
    • 4xx (e.g., 400, 404, 429): Represents client errors.
    • 5xx (e.g., 500, 503): Represents server errors.
  • count: An integer representing how many times that outcome was observed for that merchant in that second.

Assumptions:

  • The input is always valid, and corresponds to the format described above.
  • Logs are guaranteed to be sorted by timestamp.
  • The input dataset contains no duplicate (timestamp, merchant_id, status_code) entries.

Output Format

The function will return all the alert events that result from the given list of transactions.

The output format is an array of strings, where each string is a record in the format: timestamp,event_type,merchant_id,status_code, representing:

  • timestamp: the timestamp (second) when the alert event was triggered/resolved.
  • event_type: one of the following:
    • TRIGGER: Emitted when error conditions are first met for a merchant_id/status_code pair.
    • RESOLVE: Emitted when a previously triggered alert's conditions are no longer met.
  • merchant_id: The id of the merchant associated with the current alert.
  • status_code: The error status code associated with the current alert.

Important: The output must be sorted by (timestamp ASC, merchant_id ASC, status_code ASC, event_type ASC). For event_type, alphabetical order means RESOLVE comes before TRIGGER.

Part 1: Basic Incident Detection

Let's build a basic incident detection mechanism first.

Alerts should be triggered if there are at least 5 failures with the exact same error code for the same merchant within the last 30 seconds.

Note: After finishing part 1, test cases 0 - 3 should pass.

Part 1 Sample Test Case

Input:

10,merchant1,500,2
10,merchant2,500,1
15,merchant1,500,2
20,merchant1,500,1
20,merchant2,500,4

Output:

20,TRIGGER,merchant1,500
20,TRIGGER,merchant2,500

Part 2: Impact Rate Filtering (The 1% Rule)

Large merchants naturally have more errors due to high volume. To reduce noise, we only want to alert when the error rate is significant relative to the merchant's successful transaction volume.

Update your logic to include an Impact Threshold. An alert is now only TRIGGERED if, within the last 30 seconds, BOTH criteria are met for a specific error code:

  1. Volume: At least 5 failures for a specific error code.
  2. Impact: Those specific failures represent more than 1% of the merchant's successful transaction volume (the total count of transactions with status code 200 for that merchant) in that same window.

Note: After finishing part 2, test cases 0 - 8 should pass.

Part 2 Sample Test Case

Input:

10,merchant1,200,600
12,merchant1,500,6
15,merchant2,200,599
16,merchant2,500,6

Output:

16,TRIGGER,merchant2,500

Explanation:

  • At timestamp 12, merchant1 has 6 errors, but they are exactly 1% of the merchant's successful volume (600), not more than that.
  • At timestamp 16, merchant2 has 6 errors, which is > 1% of its success volume (599). So, an alert is triggered for merchant2.

Part 3: Incident Resolution

An incident monitor is only useful if it knows when a problem has stopped. Let's now implement RESOLVED events.

An active alert for a (merchant_id, status_code) pair transitions to RESOLVED when a log arrives and the previous 30 seconds of logs no longer meet the TRIGGER criteria.

The TRIGGER conditions from Part 2 (volume ≥ 5 AND impact > 1%) still apply.

Rules

  • Resolution Criteria: An alert is resolved at timestamp T if a log arrives for that merchant at T, and the 30-second window ending at T no longer meets the Trigger conditions (from Part 2).

FastPrep Implementation Clarification

In this workspace, implement detectIncidents(logs), which corresponds to the source function detect_incidents(logs).

  • Process the entries in their given order. After each entry at timestamp T, evaluate the relevant alert states for that entry's merchant using the inclusive window [T-29, T].
  • Emit RESOLVE only when an alert is currently active and the Part 2 conditions become false.
  • After a RESOLVE event, that alert becomes inactive. It may emit TRIGGER again only if the Part 2 conditions are met again later.

Function

detectIncidents(logs: String[]) → String[]

Examples

Example 1

logs = ["10,merchant1,500,2","10,merchant2,500,1","15,merchant1,500,2","20,merchant1,500,1","20,merchant2,500,4"]return = ["20,TRIGGER,merchant1,500","20,TRIGGER,merchant2,500"]

Example 2

logs = ["10,merchant1,200,600","12,merchant1,500,6","15,merchant2,200,599","16,merchant2,500,6"]return = ["16,TRIGGER,merchant2,500"]

At timestamp 12, merchant1 has 6 errors, but they are exactly 1% of the merchant's successful volume (600), not more than that.

At timestamp 16, merchant2 has 6 errors, which is > 1% of its success volume (599). So, an alert is triggered for merchant2.

More Stripe problems

drafts saved locally
public String[] detectIncidents(String[] logs) {
  // Write your code here.
}
logs["10,merchant1,500,2","10,merchant2,500,1","15,merchant1,500,2","20,merchant1,500,1","20,merchant2,500,4"]
expected["20", "TRIGGER", "merchant1", "500", "20", "TRIGGER", "merchant2", "500"]
checking account