···1313 * Randomized path (`RANDOMIZE=true`)
1414 * Randomized User-Agent
15151616-Additionally, the bash script [`bench.sh`](/bench.sh) can be used to orchestrate the load call, monitor the crowdsec process, and create a .png plot of CPU/memory using [`psrecord`](https://github.com/astrofrog/psrecord), if it installed.
1616+Additionally, the bash script [`bench.sh`](/bench.sh) can be used to orchestrate the load call, monitor the crowdsec process, and create a .png plot of CPU using [`goeffel`](https://github.com/jgehrcke/goeffel), if it installed.
17171818# Usage
1919···30303131### Using `bench.sh`
32323333-Install [`psrecord`](https://github.com/astrofrog/psrecord), if not present:
3333+Install latest development [`goeffel`](hhttps://github.com/jgehrcke/goeffel) version:
34343535```shell
3636-pipx install psrecord[plot]
3636+pipx install git+https://github.com/jgehrcke/goeffel
3737```
38383939-Run `bench.sh` from the project directory, providing the duration the load will be run:
3939+Run `bench.sh` from the project directory. It requires `sudo` to collect metrics.
40404141```shell
4242-# DURATION=12 from .env then...
4343-./bench.sh 12
4242+sudo ./bench.sh
4443```
45444646-After the run has finished an image `plot_[unix_timestamp].png` will be generated in the project directory.
4545+After the run has finished an image `[date]_crowdsec-web-traffic-load-[unix_timestamp].png` will be generated in the project directory.
4646+4747+Additional graphs can be plotted from the generated `hdf5` file using [`goeffel-analysis`](https://github.com/jgehrcke/goeffel?tab=readme-ov-file#goeffel-analysis-data-inspection-and-visualization).
47484849### Manually
4950
+57-8
bench.sh
···11#!/bin/bash
22-set -x
22+33+## https://askubuntu.com/a/970898
44+if ! [ $(id -u) = 0 ]; then
55+ echo "The script need to be run as root." >&2
66+ exit 1
77+fi
88+99+if [ $SUDO_USER ]; then
1010+ real_user=$SUDO_USER
1111+else
1212+ real_user=$(whoami)
1313+fi
1414+1515+trap 'exit 0;' SIGHUP SIGINT SIGKILL
1616+1717+printf 'Starting traefik and echo...\n'
1818+sudo -u $real_user docker compose up traefik echo -d
1919+2020+printf 'Starting crowdsec container...\n'
2121+sudo -u $real_user docker compose up crowdsec -d
2222+2323+CS_PID=$(pgrep crowdsec --newest | head -n 1)
2424+while [ -z "$CS_PID" ]
2525+do
2626+ printf 'Waiting for crowdsec to finish starting up...\n'
2727+ sleep 1
2828+ CS_PID=$(pgrep crowdsec --newest | head -n 1)
2929+done
3030+printf 'Crowdsec started! Waiting a few seconds for CPU to settle...\n'
3131+sleep 2
3232+3333+printf 'Starting goeffel capture of crowdsec PID %s \n' "$CS_PID"
3434+goeffel --pid $CS_PID --no-system-metrics --label crowdsec &
3535+G_PID=$!
33644-DURATION=${1}
3737+printf 'Starting k6\n'
3838+sudo -u $real_user docker compose up k6 -d
53966-docker compose up traefik crowdsec echo -d
4040+#printf 'Waiting for k6 to finish...\n'
4141+docker compose wait k6
4242+printf 'k6 container exited!\n'
74388-CSPID=$(pgrep crowdsec)
4444+printf 'Stopping crowdsec\n'
4545+sudo -u $real_user docker compose down crowdsec
9461010-docker compose up k6 -d
4747+while test -d /proc/$G_PID; do
4848+ printf 'Waiting for goeffel to finish...\n'
4949+ sleep 1
5050+done
5151+5252+DATA=$(ls -t1 *.hdf5 | head -n 1)
11531254timestamp=$(date +%s)
13551414-psrecord $CSPID --plot plot_$timestamp.png --interval 0.1 --duration $DURATION
5656+printf 'Generating plot for %s\n' "$DATA"
15571616-#./topplot/capture.sh $CSPID & sleep $DURATION;kill $!
1717-#./topplot/plot-usage.gp top.dat top.png5858+sudo -u $real_user goeffel-analysis flexplot \
5959+--series $DATA host \
6060+--column proc_cpu_util_percent_total \
6161+'CPU util (total) / %' \
6262+"Crowdsec Web Traffic Load $timestamp" 5 \
6363+--subtitle '50 concurrent requests, measured with Goeffel' \
6464+--legend-loc 'upper right' \
6565+--mean-style solid \
6666+--custom-y-limit 0 100
-14
topplot/capture.sh
···11-#!/bin/sh
22-## https://theholyjava.wordpress.com/2018/10/17/monitoring-process-memory-cpu-usage-with-top-and-plotting-it-with-gnuplot/
33-##
44-## BEWARE: Check with your impl. of top what exactly it returns, it migth differ from mine
55-##
66-# Usage: ./monitor-usage.sh <PID of the process>
77-# Output: top.dat with lines such as `1539689171 305m 2.0`, i.e. unix time - memory with m suffix - CPU load in %
88-# To plot the output, see https://gist.github.com/holyjak/1b58dedae3207b4a56c9abcde5f3fdb5
99-export PID=$1
1010-rm top.dat
1111-while true; do top -p $PID -bn 1 -em | grep -E '^ *[0-9]+' | awk -v now=$(date +%s.%N) '{print now,$6,$9}' >> top.dat; done
1212-# top: -p <pid> target process, -b batch mode, -n 1 run once; -em display mem in MB
1313-# egrep extracts the line starting with the pid, with the metrics
1414-# awk prepends a date and extracts columns 6 (RES = residential memory, ie RAM) and 9, which should be the memory and cpu load
-42
topplot/plot-usage.gp
···11-#!/usr/bin/env -S gnuplot --persist -c
22-# Plot memory and CPU usage over time. Usage:
33-# usage-plot.gp <input file> [<output .png file>]
44-# where the input file has the columns `<unix time> <memory, with m/g suffix> <% cpu>`
55-# To create the input file, see https://gist.github.com/jakubholynet/931a3441982c833f5f8fcdcf54d05c91
66-77-# Arguments:
88-infile=ARG1
99-outfile=ARG2
1010-set term x11
1111-set title 'Memory, CPU usage from' . infile
1212-set xdata time
1313-set timefmt "%s"
1414-set xlabel "Time [[hh:]mm:ss]"
1515-set ylabel "Memory usage"
1616-set format y '%.1s%cB'
1717-1818-set y2label 'CPU usage'
1919-set format y2 '%.0s%%'
2020-set y2tics nomirror
2121-set tics out
2222-set autoscale y
2323-set autoscale y2
2424-2525-# Credit: Christoph @ https://stackoverflow.com/a/52822256/204205
2626-resolveUnit(s)=(pos=strstrt("kmgtp",s[strlen(s):*]), real(s)*(1024**pos))
2727-2828-if (exists("outfile") && strlen(outfile) > 0) {
2929- print "Outputting to the file ", outfile
3030- set term png # 640,480
3131- set output outfile
3232-}
3333-3434-# Styling
3535-set style line 1 linewidth 1 linecolor 'light-blue'
3636-set style line 2 linecolor 'dark-green'
3737-#set xtics font ", 10"
3838-set tics font ", 10"
3939-set xtics rotate 60 # put label every 60s, make vertical so they don't clash in .png if too many
4040-4141-plot infile u 1:3 with lp axes x1y2 title "cpu" linestyle 2, \
4242- infile using 1:(resolveUnit(stringcolumn(2))) with linespoints title "memory" linestyle 1