Skip to content

Instantly share code, notes, and snippets.

@matti
Created May 27, 2025 15:46
Show Gist options
  • Save matti/ae25d081027122067eca70e4aa29a1c5 to your computer and use it in GitHub Desktop.
Save matti/ae25d081027122067eca70e4aa29a1c5 to your computer and use it in GitHub Desktop.
#!/bin/sh
# Usage check
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <prefix>"
exit 1
fi
prefix="$1"
# Generate a random float between min and max
random_in_range() {
min=$1
max=$2
awk -v min="$min" -v max="$max" -v seed="$RANDOM" 'BEGIN {
srand(seed);
print rand() * (max - min) + min
}'
}
# Generate a varying value around a base
generate_varying_value() {
base=$1
variance=$2
neg_variance=$(awk -v v="$variance" 'BEGIN { print -v }')
offset=$(random_in_range "$neg_variance" "$variance")
awk -v b="$base" -v o="$offset" 'BEGIN { print b + o }'
}
# Occasionally spike a value
maybe_spike() {
value=$1
spike_min=$2
spike_max=$3
probability=$4 # e.g. 10 = 1-in-10 chance
if [ $((RANDOM % $probability)) -eq 0 ]; then
random_spike=$(random_in_range "$spike_min" "$spike_max")
echo "$(awk -v v="$random_spike" 'BEGIN { print int(v) }')"
else
echo "$value"
fi
}
generate_metrics() {
# Normal base values
base_dns=$(maybe_spike 3 15 60 15) # 1 in 15 chance DNS spikes to 15-60ms
base_connect=$(maybe_spike 35 80 180 18) # 1 in 18 chance connect spikes to 80-180ms
base_tls=$(maybe_spike 45 60 130 20) # 1 in 20 chance tls spikes to 60-130ms
base_ttfb=$(maybe_spike 200 400 800 15) # 1 in 15 chance ttfb spikes to 400-800ms
base_ttlb=$(maybe_spike 210 410 950 17) # 1 in 17 chance ttlb spikes to 410-950ms
# Generate TTFB with offset
ttfb_offset=$(random_in_range -30 50)
ttfb_value=$(awk -v b="$base_ttfb" -v o="$ttfb_offset" 'BEGIN { print b + o }')
# TTLB is TTFB plus a small offset
ttlb_offset=$(random_in_range 5 15)
ttlb_value=$(awk -v t="$ttfb_value" -v o="$ttlb_offset" 'BEGIN { print t + o }')
# Generate buckets for TTFB and TTLB
ttfb_b1=$(generate_varying_value 40 15 | awk '{ print int($1) }')
ttfb_b2=$(generate_varying_value 75 10 | awk '{ print int($1) }')
ttfb_b3=$(generate_varying_value 95 3 | awk '{ print int($1) }')
ttlb_b1_base=$(generate_varying_value 35 15 | awk '{ print int($1) }')
ttlb_b2_base=$(generate_varying_value 70 10 | awk '{ print int($1) }')
ttlb_b3_base=$(generate_varying_value 90 3 | awk '{ print int($1) }')
ttlb_b1=$(awk -v t="$ttfb_b1" -v b="$ttlb_b1_base" 'BEGIN { v = t - 5; print (b < v) ? b : v }')
ttlb_b2=$(awk -v t="$ttfb_b2" -v b="$ttlb_b2_base" 'BEGIN { v = t - 5; print (b < v) ? b : v }')
ttlb_b3=$(awk -v t="$ttfb_b3" -v b="$ttlb_b3_base" 'BEGIN { v = t - 5; print (b < v) ? b : v }')
# Calculate sum values in seconds
dns_sum=$(awk -v d="$base_dns" 'BEGIN { printf "%.3f", d / 1000 }')
connect_offset=$(random_in_range -15 25)
connect_sum=$(awk -v c="$base_connect" -v o="$connect_offset" 'BEGIN { printf "%.3f", (c + o) / 1000 }')
tls_offset=$(random_in_range -5 10)
tls_sum=$(awk -v t="$base_tls" -v o="$tls_offset" 'BEGIN { printf "%.3f", (t + o) / 1000 }')
ttfb_sum=$(awk -v t="$ttfb_value" 'BEGIN { printf "%.3f", t / 1000 }')
ttlb_sum=$(awk -v t="$ttlb_value" 'BEGIN { printf "%.3f", t / 1000 }')
# Output metrics (with prefix)
cat << EOF
# HELP ${prefix}_http_timing_seconds HTTP request timing in seconds
# TYPE ${prefix}_http_timing_seconds histogram
${prefix}_http_timing_seconds_bucket{stage="dns",le="0.005"} $(generate_varying_value 85 10 | awk '{ print int($1) }')
${prefix}_http_timing_seconds_bucket{stage="dns",le="0.01"} $(generate_varying_value 95 3 | awk '{ print int($1) }')
${prefix}_http_timing_seconds_bucket{stage="dns",le="0.02"} $(generate_varying_value 98 1 | awk '{ print int($1) }')
${prefix}_http_timing_seconds_bucket{stage="dns",le="+Inf"} 100
${prefix}_http_timing_seconds_sum{stage="dns"} $dns_sum
${prefix}_http_timing_seconds_count{stage="dns"} 100
${prefix}_http_timing_seconds_bucket{stage="connect",le="0.02"} $(generate_varying_value 70 15 | awk '{ print int($1) }')
${prefix}_http_timing_seconds_bucket{stage="connect",le="0.05"} $(generate_varying_value 90 5 | awk '{ print int($1) }')
${prefix}_http_timing_seconds_bucket{stage="connect",le="0.1"} $(generate_varying_value 98 1 | awk '{ print int($1) }')
${prefix}_http_timing_seconds_bucket{stage="connect",le="+Inf"} 100
${prefix}_http_timing_seconds_sum{stage="connect"} $connect_sum
${prefix}_http_timing_seconds_count{stage="connect"} 100
${prefix}_http_timing_seconds_bucket{stage="tls",le="0.04"} $(generate_varying_value 75 10 | awk '{ print int($1) }')
${prefix}_http_timing_seconds_bucket{stage="tls",le="0.05"} $(generate_varying_value 95 3 | awk '{ print int($1) }')
${prefix}_http_timing_seconds_bucket{stage="tls",le="0.06"} $(generate_varying_value 98 1 | awk '{ print int($1) }')
${prefix}_http_timing_seconds_bucket{stage="tls",le="+Inf"} 100
${prefix}_http_timing_seconds_sum{stage="tls"} $tls_sum
${prefix}_http_timing_seconds_count{stage="tls"} 100
${prefix}_http_timing_seconds_bucket{stage="ttfb",le="0.15"} $ttfb_b1
${prefix}_http_timing_seconds_bucket{stage="ttfb",le="0.25"} $ttfb_b2
${prefix}_http_timing_seconds_bucket{stage="ttfb",le="0.35"} $ttfb_b3
${prefix}_http_timing_seconds_bucket{stage="ttfb",le="+Inf"} 100
${prefix}_http_timing_seconds_sum{stage="ttfb"} $ttfb_sum
${prefix}_http_timing_seconds_count{stage="ttfb"} 100
${prefix}_http_timing_seconds_bucket{stage="ttlb",le="0.16"} $ttlb_b1
${prefix}_http_timing_seconds_bucket{stage="ttlb",le="0.26"} $ttlb_b2
${prefix}_http_timing_seconds_bucket{stage="ttlb",le="0.36"} $ttlb_b3
${prefix}_http_timing_seconds_bucket{stage="ttlb",le="+Inf"} 100
${prefix}_http_timing_seconds_sum{stage="ttlb"} $ttlb_sum
${prefix}_http_timing_seconds_count{stage="ttlb"} 100
# HELP ${prefix}_http_errors_total Total number of HTTP errors
# TYPE ${prefix}_http_errors_total counter
${prefix}_http_errors_total{status_code="500"} 2
${prefix}_http_errors_total{status_code="404"} 1
EOF
}
# Main
generate_metrics
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment