Skip to content

Commit cf4c25f

Browse files
Added multi-window selector page
1 parent 351907b commit cf4c25f

File tree

4 files changed

+315
-1
lines changed

4 files changed

+315
-1
lines changed

docs/user-guide/alerts/.pages

+1
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ nav:
33
- Destinations: destinations.md
44
- Templates: templates.md
55
- Import and Export Alerts: import-export-alerts.md
6+
- Multi-window Selector in Scheduled Alerts (SQL Mode): multi-window-selector-scheduled-alerts.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,311 @@
1+
The **Multi-window selector** feature in OpenObserve enables users to **define multiple time windows in a scheduled alert (SQL mode)**, **compare log, metrics, or traces across those time windows**, and **determine whether to send an alert notification based on the comparison results**.
2+
3+
## Access The Multi-window Selector
4+
5+
You can apply the multi-window selector feature to both new and existing scheduled alerts in SQL mode.
6+
7+
#### For new alerts:
8+
9+
1. Select **Alerts**.
10+
2. Select the folder or create a new folder as per requirement.
11+
3. Click **Add Alert**.
12+
4. Select **Scheduled Alerts**.
13+
5. Select **SQL**.
14+
6. Navigate to the **Multi-window Selector** section.
15+
16+
#### For existing alerts:
17+
18+
1. Select the existing alert from the **Alerts** page (the selected alert must be scheduled and created in the SQL mode).
19+
2. Click the edit icon.
20+
3. In the **Update Alert** page, navigate to the **Multi-window Selector** section.
21+
22+
### How to Use Multi-window Selector
23+
24+
> **Use Case**: You want to monitor **purchase events where users had to retry the action (retry count > 0)**. Specifically, you want to check if the number of such purchase events has **increased by more than 5% in the last 30 minutes**, compared to the same 30-minute period yesterday. If yes, you want to receive an **alert by email** that clearly states the percentage increase, so you can take necessary actions.
25+
26+
Follow these steps to configure the **Multi-window Selector** feature in your scheduled alert:
27+
28+
#### Step 1: Write the SQL Query
29+
30+
**Tip**: Use the Logs page to write and test your SQL query.
31+
32+
```sql
33+
34+
SELECT
35+
36+
histogram(_timestamp, '15 minutes') AS time_s,
37+
COUNT(_timestamp) AS cnt
38+
39+
FROM
40+
41+
"openobserve_app_analytics_log_stream"
42+
43+
WHERE
44+
45+
pdata_dr_level1_level2_level3_level4_level5_level6_level7_retry > 0
46+
AND eventtype = 'purchase'
47+
48+
GROUP BY
49+
50+
time_s
51+
```
52+
Explanation of the above SQL query:
53+
54+
- `histogram(_timestamp, '15 minutes')`: Buckets events into 15-minute intervals.
55+
- **Filters**: Only include events of type `purchase` that have retry count greater than zero.
56+
- **Group by**: Each time bucket.
57+
58+
#### Step 2: Define the Period
59+
60+
Specify the time range for which you want to evaluate the data (for example, the last 30 minutes).
61+
62+
#### Step 3: Select Multi-window
63+
64+
In the **Multi-window Selector**, select the historical time window you want to compare against the current time window.
65+
66+
For example, if you want to compare the current 30-minute window with the same window 1 day ago, select **1 day ago**.
67+
68+
At runtime, the alert manager will run **two SQL queries**:
69+
70+
1. One for the **current time window** (for example, 9:30 AM – 10:00 AM).
71+
2. One for the **selected past time window** (for example, 9:30 AM – 10:00 AM, previous day).
72+
73+
**​​Understand SQL Query Output Before Writing VRL**
74+
75+
When **Multi-window Selector** is used, OpenObserve passes the results of your SQL queries to your VRL function as an **array of arrays**.
76+
77+
Example input to your VRL function:
78+
79+
```
80+
[
81+
82+
[ // Current time window result (result[0])
83+
84+
{ "time_s": "10:00", "cnt": 20 },
85+
86+
{ "time_s": "10:15", "cnt": 23 }
87+
88+
],
89+
90+
[ // Past time window result (result[1])
91+
92+
{ "time_s": "10:00", "cnt": 40 },
93+
94+
{ "time_s": "10:15", "cnt": 91 }
95+
96+
]
97+
98+
]
99+
```
100+
Inside the VRL function, you can access:
101+
102+
- `result[0]`: Current time window data
103+
- `result[1]`: Past time window data
104+
105+
#### Step 4: Write the VRL Function
106+
107+
Create a VRL function to process the SQL query results and perform the desired comparison.
108+
109+
**Key points:**
110+
111+
1. Always start your VRL function with `#ResultArray#` when using the **Multi-window Selector**.
112+
This ensures that your VRL function receives a **multi-dimensional array** input, where:
113+
114+
- `result[0]` = current time window data
115+
- `result[1]` = past time window data
116+
Without `#ResultArray#`, the input is a flat array, and it becomes unreliable to distinguish current vs. past data.
117+
118+
2. The **special variable `.` (dot)** holds this input. It contains the entire query result. To make this input easier to work with, we **assign it to a variable called `result`** and ensure it is treated as an array: <br>
119+
`result = array!(.)` <br>
120+
Note that `array!(.)` tells VRL to ensure the input is treated as an array. If the input is not an array, VRL will throw an error to alert you. Always use `array!(.)` for clarity and safety.
121+
122+
**Tip**: Write and test your VRL function using the VRL playground in Logs page or [Vector.dev Playground](https://playground.vrl.dev/).
123+
124+
**VRL function example**:
125+
```
126+
#ResultArray#
127+
128+
# Initialize variables
129+
130+
prev_data = []
131+
132+
curr_data = []
133+
134+
res = []
135+
136+
result = array!(.)
137+
138+
# Process if we have at least 2 windows of data
139+
140+
if length(result) >= 2 {
141+
142+
today_data = result[0]
143+
144+
yesterday_data = result[1]
145+
146+
# Sum counts for both windows
147+
148+
cnt_yesterday = 0.0
149+
150+
cnt_today = 0.0
151+
152+
for_each(array!(yesterday_data)) -> |index, p_value| {
153+
154+
cnt_yesterday, err = cnt_yesterday + p_value.cnt
155+
156+
}
157+
158+
for_each(array!(today_data)) -> |index, p_value| {
159+
160+
cnt_today, err = cnt_today + p_value.cnt
161+
162+
}
163+
164+
# Calculate difference and percentage
165+
166+
if cnt_yesterday > 0.0 {
167+
168+
diff = cnt_today - cnt_yesterday
169+
170+
diff_percentage, err = (diff) * 100.0 / cnt_yesterday
171+
172+
# Alert condition: if increase is more than 5%
173+
174+
if diff_percentage > 5.0 {
175+
176+
diff_data = {
177+
178+
"diff": diff,
179+
180+
"diff_percentage": diff_percentage
181+
182+
}
183+
184+
temp = []
185+
186+
temp = push(temp, diff_data)
187+
188+
res = push(res, temp)
189+
190+
}
191+
192+
}
193+
194+
}
195+
196+
# Set the final result
197+
198+
. = res
199+
200+
.
201+
```
202+
203+
**Understand the VRL Function Output**
204+
205+
The VRL function outputs:
206+
207+
- **Empty array** ([ ]): If the increase is **not** more than 5%.
208+
- **Non-empty array**: If the increase **exceeds** 5%. Example:
209+
210+
```
211+
[
212+
213+
[
214+
215+
{
216+
217+
"diff": 10,
218+
219+
"diff_percentage": 10.0
220+
221+
}
222+
223+
]
224+
225+
]
226+
```
227+
228+
#### Step 5: Define the Threshold
229+
230+
Use the VRL function output to define the threshold.
231+
Set the threshold as:
232+
233+
**Trigger when count of VRL output >= 1. This means:**
234+
235+
- If the VRL output array is **empty** -> count is 0 -> **no alert is sent**.
236+
- If the VRL output has **results** -> count is 1 or more -> **alert is triggered**.
237+
238+
Set the **Threshold** as **>= 1**
239+
240+
#### Step 6: Select Destination
241+
242+
Specify where you want to receive the alert notification- email or webhook.
243+
244+
#### Step 7: Create Row Template
245+
246+
Design the row template to customize the alert content.
247+
248+
For example:
249+
250+
Include fields from your VRL output such as:
251+
252+
- `diff` (difference in counts)
253+
- `diff_percentage` (percentage increase)
254+
255+
This ensures your email notification is informative and actionable.
256+
257+
Example row template:
258+
259+
```
260+
Alert: Purchase events with retries increased by {{ diff_percentage }}%*
261+
Details: Count difference: {{ diff }}
262+
```
263+
264+
#### Step 8: Define the Frequency
265+
266+
Determines how often the alert manager runs the query throughout the day (e.g., every 30 minutes).
267+
268+
**Important:**
269+
270+
- Frequency determines **how often** the alert manager runs your queries.
271+
- Period defines **what time range** is checked at each run.
272+
273+
For instance:
274+
275+
- **Period**: Last 30 minutes
276+
- **Frequency**: Every 30 minutes
277+
- **Multi-window selector**: 1 day ago
278+
279+
At 10:00 AM, OpenObserve alert manager executes SQL for:
280+
281+
- Current window: 9:30 AM – 10:00 AM, today
282+
- Past window: 9:30 AM – 10:00 AM, one day ago
283+
284+
At 10:30 AM, OpenObserve alert manager executes SQL for:
285+
286+
- Current window: 10:00 AM – 10:30 AM, today
287+
- Past window: 10:00 AM – 10:30 AM, one day ago
288+
289+
#### Step 9: Save the Alert
290+
291+
### FAQ
292+
293+
**What happens if I forget to include #ResultArray# in my VRL function?**
294+
295+
If you do not include `#ResultArray#`, your VRL function will receive a flat array:**
296+
297+
```
298+
[
299+
300+
{ "timestamp": "10:00", "cnt": 20 },
301+
302+
{ "timestamp": "10:15", "cnt": 23 },
303+
304+
{ "timestamp": "10:00", "cnt": 40 },
305+
306+
{ "timestamp": "10:15", "cnt": 91 }
307+
308+
]
309+
```
310+
You cannot distinguish current window from past window data from the above array.
311+

docs/user-guide/dashboards/comparison-against-in-dashboards.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Let's say,
3232
- You want to view the error trend for the past 15 mins today (for example, from 3:45 PM - 4:00 PM, today).
3333
- Now, you want to compare the error trend for the same time period (from 3:45 PM - 4:00 PM), 2 days ago.
3434

35-
The following steps provides step-by-step instructions on how to use the **Comparison Against** for this scenario:
35+
The following steps explain how to use the **Comparison Against** feature for this scenario:
3636

3737
1. Go to **Dashboards** > **New Dashboard**.
3838
![dashboards](../../images/dashboards-comparison-against-1.png)

mkdocs.yml

+2
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,5 @@ markdown_extensions:
9595
- pymdownx.inlinehilite
9696
- pymdownx.snippets
9797
- pymdownx.superfences
98+
99+

0 commit comments

Comments
 (0)