Skip to content

Commit 5c0e8fe

Browse files
add alerts to demo
1 parent a7387c1 commit 5c0e8fe

File tree

2 files changed

+210
-1
lines changed

2 files changed

+210
-1
lines changed

resources/alerts_demo_data.sh

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
#!/usr/bin/env bash
2+
3+
# Configuration
4+
P_URL=${P_URL:-"http://localhost:8000"}
5+
P_USERNAME=${P_USERNAME:-"admin"}
6+
P_PASSWORD=${P_PASSWORD:-"admin"}
7+
P_STREAM=${P_STREAM:-"demodata"}
8+
9+
# Pre-compute auth header
10+
AUTH_HEADER="Authorization: Basic $(echo -n "$P_USERNAME:$P_PASSWORD" | base64)"
11+
12+
# Common curl function with retry logic
13+
curl_with_retry() {
14+
local url="$1"
15+
local method="$2"
16+
local data="$3"
17+
local content_type="${4:-application/json}"
18+
local max_retries="${5:-3}"
19+
local retry_count=0
20+
local data_file="$7"
21+
22+
# Create temp file if data is provided (either as string or file)
23+
if [[ -n "$data_file" ]]; then
24+
temp_file="$data_file"
25+
elif [[ -n "$data" ]]; then
26+
temp_file=$(mktemp)
27+
if [[ $? -ne 0 ]]; then
28+
return 1
29+
fi
30+
printf "%s" "$data" > "$temp_file"
31+
fi
32+
33+
while [[ $retry_count -lt $max_retries ]]; do
34+
local max_time=$((10 + (retry_count * 10)))
35+
local connect_timeout=5
36+
37+
local curl_cmd="curl -s -w \"\n%{http_code}\" --max-time $max_time --connect-timeout $connect_timeout"
38+
39+
# Add headers
40+
curl_cmd+=" -H \"Content-Type: $content_type\""
41+
curl_cmd+=" -H \"$AUTH_HEADER\""
42+
43+
# Add method and data
44+
if [[ "$method" == "POST" ]]; then
45+
curl_cmd+=" -X POST"
46+
if [[ -n "$temp_file" ]]; then
47+
curl_cmd+=" --data-binary \"@$temp_file\""
48+
elif [[ -n "$data" ]]; then
49+
curl_cmd+=" -d \"$data\""
50+
fi
51+
fi
52+
53+
# Add URL
54+
curl_cmd+=" \"$url\""
55+
56+
# Execute curl
57+
local response
58+
response=$(eval "$curl_cmd" 2>&1)
59+
local curl_exit_code=$?
60+
61+
# Check curl exit code
62+
if [[ $curl_exit_code -eq 0 ]]; then
63+
local status_code
64+
if [[ -n "$response" ]]; then
65+
status_code=$(echo "$response" | tail -n1)
66+
local response_body=$(echo "$response" | sed '$d')
67+
68+
# Clean up temp file (only if we created it)
69+
if [[ -n "$temp_file" && -z "$data_file" ]]; then
70+
rm -f "$temp_file"
71+
fi
72+
73+
if [[ "$status_code" == "200" || "$status_code" == "201" ]]; then
74+
echo "$response_body"
75+
return 0
76+
else
77+
return 1
78+
fi
79+
else
80+
return 1
81+
fi
82+
elif [[ $curl_exit_code -eq 28 ]]; then
83+
# Timeout - retry
84+
retry_count=$((retry_count + 1))
85+
sleep 1
86+
else
87+
break
88+
fi
89+
done
90+
91+
# Clean up temp file on failure (only if we created it)
92+
if [[ -n "$temp_file" && -z "$data_file" ]]; then
93+
rm -f "$temp_file"
94+
fi
95+
96+
return 1
97+
}
98+
99+
# Create webhook target
100+
create_target() {
101+
response=$(curl -s -H "Content-Type: application/json" -H "$AUTH_HEADER" -X POST "$P_URL/api/v1/targets" -d @- << EOF
102+
{"type":"webhook","endpoint":"https://webhook.site/8e1f26bd-2f5b-47a2-9d0b-3b3dabb30710","name":"Test Webhook","auth":{"username":"","password":""},"skipTlsCheck":false,"notificationConfig":{"interval":1,"times":1}}
103+
EOF
104+
)
105+
106+
curl_exit_code=$?
107+
108+
if [[ $curl_exit_code -eq 0 && -n "$response" ]]; then
109+
# Extract target ID from response
110+
target_id=$(echo "$response" | grep -o '"id":"[^"]*"' | cut -d'"' -f4)
111+
if [[ -n "$target_id" ]]; then
112+
echo "Target created successfully with ID: $target_id" >&2
113+
echo "$target_id"
114+
return 0
115+
else
116+
echo "Failed to extract target ID from response" >&2
117+
echo "Response: $response" >&2
118+
return 1
119+
fi
120+
else
121+
echo "Failed to create target" >&2
122+
echo "Curl exit code: $curl_exit_code" >&2
123+
echo "Response: $response" >&2
124+
return 1
125+
fi
126+
}
127+
128+
# Create JSON file to avoid control character issues
129+
create_json_file() {
130+
local filename="$1"
131+
local content="$2"
132+
133+
# Create temporary file with proper JSON content
134+
temp_json=$(mktemp)
135+
printf "%s" "$content" > "$temp_json"
136+
echo "$temp_json"
137+
}
138+
139+
# Create alerts
140+
create_alerts() {
141+
local target_id="$1"
142+
143+
if [[ -z "$target_id" ]]; then
144+
echo "Target ID is required to create alerts"
145+
return 1
146+
fi
147+
148+
# Alert 1: Error Count (severity_number = 18)
149+
alert1_template='{"severity":"high","title":"error count","stream":"STREAM_PLACEHOLDER","alertType":"threshold","aggregates":{"aggregateConfig":[{"aggregateFunction":"count","conditions":{"operator":null,"conditionConfig":[{"column":"severity_number","operator":"=","value":"18"}]},"column":"severity_number","operator":">","value":1000}]},"evalConfig":{"rollingWindow":{"evalStart":"5h","evalEnd":"now","evalFrequency":1}},"targets":["TARGET_PLACEHOLDER"]}'
150+
151+
alert1_json=$(echo "$alert1_template" | sed "s|STREAM_PLACEHOLDER|$P_STREAM|g" | sed "s|TARGET_PLACEHOLDER|$target_id|g")
152+
response1=$(curl -s -H "Content-Type: application/json" -H "$AUTH_HEADER" -X POST -d "$alert1_json" "$P_URL/api/v1/alerts")
153+
if [[ $? -eq 0 && -n "$response1" ]]; then
154+
echo "Alert 1 created successfully"
155+
else
156+
echo "Failed to create Alert 1"
157+
echo "Response: $response1"
158+
fi
159+
160+
# Alert 2: 400 Errors
161+
162+
alert2_template='{"severity":"critical","title":"400 Errors","stream":"STREAM_PLACEHOLDER","alertType":"threshold","aggregates":{"aggregateConfig":[{"aggregateFunction":"count","conditions":{"operator":null,"conditionConfig":[{"column":"body","operator":"contains","value":"400"}]},"column":"body","operator":">","value":10}]},"evalConfig":{"rollingWindow":{"evalStart":"5h","evalEnd":"now","evalFrequency":1}},"targets":["TARGET_PLACEHOLDER"]}'
163+
164+
alert2_json=$(echo "$alert2_template" | sed "s|STREAM_PLACEHOLDER|$P_STREAM|g" | sed "s|TARGET_PLACEHOLDER|$target_id|g")
165+
166+
response2=$(curl -s -H "Content-Type: application/json" -H "$AUTH_HEADER" -X POST -d "$alert2_json" "$P_URL/api/v1/alerts")
167+
if [[ $? -eq 0 && -n "$response2" ]]; then
168+
echo "Alert 2 created successfully"
169+
else
170+
echo "Failed to create Alert 2"
171+
echo "Response: $response2"
172+
fi
173+
174+
# Alert 3: Trace ID or Span ID null
175+
176+
alert3_template='{"severity":"high","title":"Trace ID or Span ID null","stream":"STREAM_PLACEHOLDER","alertType":"threshold","aggregates":{"aggregateConfig":[{"aggregateFunction":"count","conditions":{"operator":null,"conditionConfig":[{"column":"trace_id","operator":"is null","value":""}]},"column":"trace_id","operator":">","value":0}]},"evalConfig":{"rollingWindow":{"evalStart":"5h","evalEnd":"now","evalFrequency":1}},"targets":["TARGET_PLACEHOLDER"]}'
177+
178+
alert3_json=$(echo "$alert3_template" | sed "s|STREAM_PLACEHOLDER|$P_STREAM|g" | sed "s|TARGET_PLACEHOLDER|$target_id|g")
179+
180+
response3=$(curl -s -H "Content-Type: application/json" -H "$AUTH_HEADER" -X POST -d "$alert3_json" "$P_URL/api/v1/alerts")
181+
if [[ $? -eq 0 && -n "$response3" ]]; then
182+
echo "Alert 3 created successfully"
183+
else
184+
echo "Failed to create Alert 3"
185+
echo "Response: $response3"
186+
fi
187+
188+
sleep 1
189+
}
190+
191+
# Main execution
192+
# Create target and get ID
193+
target_id=$(create_target)
194+
195+
if [[ $? -eq 0 && -n "$target_id" ]]; then
196+
echo "Target creation successful, proceeding with alerts..."
197+
sleep 2
198+
199+
# Create alerts using the target ID
200+
create_alerts "$target_id"
201+
else
202+
echo "Failed to create target, cannot proceed with alerts"
203+
exit 1
204+
fi
205+
206+
exit 0

src/handlers/http/demo_data.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ use std::os::unix::fs::PermissionsExt;
3030
// Embed the scripts at compile time
3131
const INGEST_SCRIPT: &str = include_str!("../../../resources/ingest_demo_data.sh");
3232
const FILTER_SCRIPT: &str = include_str!("../../../resources/filters_demo_data.sh");
33+
const ALERT_SCRIPT: &str = include_str!("../../../resources/alerts_demo_data.sh");
34+
3335
pub async fn get_demo_data(req: HttpRequest) -> Result<HttpResponse, PostError> {
3436
let query_map = web::Query::<HashMap<String, String>>::from_query(req.query_string())
3537
.map_err(|_| PostError::InvalidQueryParameter)?;
@@ -75,7 +77,7 @@ pub async fn get_demo_data(req: HttpRequest) -> Result<HttpResponse, PostError>
7577
"Demo data is not available in this mode"
7678
))),
7779
},
78-
"filters" => {
80+
"filters" | "alerts" => {
7981
// Fire the script execution asynchronously
8082
tokio::spawn(async move {
8183
if let Err(e) = execute_demo_script(&action, &url, username, password).await {
@@ -103,6 +105,7 @@ async fn execute_demo_script(
103105
let script_content = match action {
104106
"ingest" => INGEST_SCRIPT,
105107
"filters" => FILTER_SCRIPT,
108+
"alerts" => ALERT_SCRIPT,
106109
_ => return Err(anyhow::anyhow!("Unsupported action: {}", action)),
107110
};
108111
// Write the script content to the temporary file

0 commit comments

Comments
 (0)