Benchmark: Add real-life configuration file and benchmark wrapper

Performance on this real-life configuration:

Before last commit:
Service runtime: 2min 22.669s
CPU time consumed: 3min 44.299s
Memory peak: 50.7M (swap: 0B)

With last commit:
Service runtime: 7.569s
CPU time consumed: 21.998s
Memory peak: 105.6M (swap: 0B)
This commit is contained in:
ppom 2025-06-23 12:00:00 +02:00
commit 283d1867b8
No known key found for this signature in database
4 changed files with 157 additions and 11 deletions

24
bench/bench.sh Executable file
View file

@ -0,0 +1,24 @@
set -e
if test "$(realpath "$PWD")" != "$(realpath "$(dirname "$0")/..")"
then
echo "You must be in reaction root directory"
exit 1
fi
if test ! -f "$1"
then
# shellcheck disable=SC2016
echo '$1 must be a configuration file (most probably in ./bench)'
exit 1
fi
rm -f reaction.db
cargo build --release
sudo systemd-run --wait \
-p User="$(id -nu)" \
-p MemoryAccounting=yes \
-p IOAccounting=yes \
-p WorkingDirectory="$(pwd)" \
-p Environment=PATH=/run/current-system/sw/bin/ \
sh -c "for i in 1 2; do ./target/release/reaction start -c '$1' -l ERROR -s ./reaction.sock; done"

View file

@ -1,11 +0,0 @@
set -e
rm -f reaction.db
cargo build --release
sudo systemd-run --wait \
-p User="$(id -nu)" \
-p MemoryAccounting=yes \
-p IOAccounting=yes \
-p WorkingDirectory="$(pwd)" \
-p Environment=PATH=/run/current-system/sw/bin/ \
sh -c "for i in 1 2; do ./target/release/reaction start -c ./bench/heavy-load.yml -l ERROR -s ./reaction.sock; done"

View file

@ -1,6 +1,9 @@
---
# This configuration permits to test reaction's performance
# under a very high load
#
# It keeps regexes super simple, to avoid benchmarking the `regex` crate,
# and benchmark reaction's internals instead.
concurrency: 32
patterns:

130
bench/nginx.yml Normal file
View file

@ -0,0 +1,130 @@
# This is an extract of a real life configuration
#
# It reads an nginx's access.log in the following format:
# log_format '$remote_addr - $remote_user [$time_local] '
# '$host '
# '"$request" $status $bytes_sent '
# '"$http_referer" "$http_user_agent"';
#
# I can't make my access.log public for obvious privacy reasons.
#
# On the opposite of heavy-load.yml, this test is closer to real-life regex complexity.
#
# It has been created to test the performance improvements of
# the previous commit: ad6b0faa30c1af84360f66074a917b4bf6cda10a
#
# On this test, most lines don't match anything, so most time is spent matching regexes.
concurrency: 0
patterns:
ip:
ignore:
- 192.168.1.253
- 10.1.1.1
- 10.1.1.5
- 10.1.1.4
- 127.0.0.1
- ::1
regex: (?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}|(?:(?:[0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,7}:|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:(?:(?::[0-9a-fA-F]{1,4}){1,6})|:(?:(?::[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(?::[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(?:ffff(?::0{1,4}){0,1}:){0,1}(?:(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])|(?:[0-9a-fA-F]{1,4}:){1,4}:(?:(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9]))
untilEOL:
regex: .*$
streams:
nginx:
cmd:
- cat
- /tmp/access.log
filters:
directusFailedLogin:
actions:
ban:
cmd:
- sleep
- 0.01
unban:
after: 4h
cmd:
- sleep
- 0.01
regex:
- ^<ip> .* "POST /repertoire/auth/login HTTP/..." 401 [0-9]+ .https://babos.land
- ^<ip> .* "POST /pompeani.art/auth/login HTTP/..." 401 [0-9]+ .https://edit.ppom.me
- ^<ip> .* "POST /leborddeleau/auth/login HTTP/..." 401 [0-9]+ .https://edit.ppom.me
- ^<ip> .* "POST /5eroue/auth/login HTTP/..." 401 [0-9]+ .https://edit.ppom.me
- ^<ip> .* "POST /edit/auth/login HTTP/..." 401 [0-9]+ .https://edit.ppom.me
- ^<ip> .* "POST /auth/login HTTP/..." 401 [0-9]+ .https://edit.ppom.fr
retry: 6
retryperiod: 4h
gptbot:
actions:
ban:
cmd:
- sleep
- 0.01
unban:
after: 4h
cmd:
- sleep
- 0.01
regex:
- ^<ip>.*"[^"]*AI2Bot[^"]*"$
- ^<ip>.*"[^"]*Amazonbot[^"]*"$
- ^<ip>.*"[^"]*Applebot[^"]*"$
- ^<ip>.*"[^"]*Applebot-Extended[^"]*"$
- ^<ip>.*"[^"]*Bytespider[^"]*"$
- ^<ip>.*"[^"]*CCBot[^"]*"$
- ^<ip>.*"[^"]*ChatGPT-User[^"]*"$
- ^<ip>.*"[^"]*ClaudeBot[^"]*"$
- ^<ip>.*"[^"]*Diffbot[^"]*"$
- ^<ip>.*"[^"]*DuckAssistBot[^"]*"$
- ^<ip>.*"[^"]*FacebookBot[^"]*"$
- ^<ip>.*"[^"]*GPTBot[^"]*"$
- ^<ip>.*"[^"]*Google-Extended[^"]*"$
- ^<ip>.*"[^"]*Kangaroo Bot[^"]*"$
- ^<ip>.*"[^"]*Meta-ExternalAgent[^"]*"$
- ^<ip>.*"[^"]*Meta-ExternalFetcher[^"]*"$
- ^<ip>.*"[^"]*OAI-SearchBot[^"]*"$
- ^<ip>.*"[^"]*PerplexityBot[^"]*"$
- ^<ip>.*"[^"]*Timpibot[^"]*"$
- ^<ip>.*"[^"]*Webzio-Extended[^"]*"$
- ^<ip>.*"[^"]*YouBot[^"]*"$
- ^<ip>.*"[^"]*omgili[^"]*"$
slskd-failedLogin:
actions:
ban:
cmd:
- sleep
- 0.01
unban:
after: 4h
cmd:
- sleep
- 0.01
regex:
- ^<ip> .* "POST /slskd/api/v0/session HTTP/..." 401 [0-9]+ .https://ppom.me
- ^<ip> .* "POST /kiosque/api/v0/session HTTP/..." 401 [0-9]+ .https://babos.land
retry: 3
retryperiod: 1h
suspectRequests:
actions:
ban:
cmd:
- sleep
- 0.01
unban:
after: 4h
cmd:
- sleep
- 0.01
regex:
- ^<ip> .*"GET /(?:[^/" ]*/)*wp-login\.php
- ^<ip> .*"GET /(?:[^/" ]*/)*wp-includes
- '^<ip> .*"GET /(?:[^/" ]*/)*\.env '
- '^<ip> .*"GET /(?:[^/" ]*/)*config\.json '
- '^<ip> .*"GET /(?:[^/" ]*/)*info\.php '
- '^<ip> .*"GET /(?:[^/" ]*/)*owa/auth/logon.aspx '
- '^<ip> .*"GET /(?:[^/" ]*/)*auth.html '
- '^<ip> .*"GET /(?:[^/" ]*/)*auth1.html '
- '^<ip> .*"GET /(?:[^/" ]*/)*password.txt '
- '^<ip> .*"GET /(?:[^/" ]*/)*passwords.txt '
- '^<ip> .*"GET /(?:[^/" ]*/)*dns-query '
- '^<ip> .*"GET /(?:[^/" ]*/)*\.git/ '