diff --git a/bench/bench.sh b/bench/bench.sh new file mode 100755 index 0000000..59d4894 --- /dev/null +++ b/bench/bench.sh @@ -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" diff --git a/bench/heavy-load.sh b/bench/heavy-load.sh deleted file mode 100644 index 0abf296..0000000 --- a/bench/heavy-load.sh +++ /dev/null @@ -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" diff --git a/bench/heavy-load.yml b/bench/heavy-load.yml index f6ba1a4..73c7a3e 100644 --- a/bench/heavy-load.yml +++ b/bench/heavy-load.yml @@ -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: diff --git a/bench/nginx.yml b/bench/nginx.yml new file mode 100644 index 0000000..a328d88 --- /dev/null +++ b/bench/nginx.yml @@ -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: + - ^ .* "POST /repertoire/auth/login HTTP/..." 401 [0-9]+ .https://babos.land + - ^ .* "POST /pompeani.art/auth/login HTTP/..." 401 [0-9]+ .https://edit.ppom.me + - ^ .* "POST /leborddeleau/auth/login HTTP/..." 401 [0-9]+ .https://edit.ppom.me + - ^ .* "POST /5eroue/auth/login HTTP/..." 401 [0-9]+ .https://edit.ppom.me + - ^ .* "POST /edit/auth/login HTTP/..." 401 [0-9]+ .https://edit.ppom.me + - ^ .* "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: + - ^.*"[^"]*AI2Bot[^"]*"$ + - ^.*"[^"]*Amazonbot[^"]*"$ + - ^.*"[^"]*Applebot[^"]*"$ + - ^.*"[^"]*Applebot-Extended[^"]*"$ + - ^.*"[^"]*Bytespider[^"]*"$ + - ^.*"[^"]*CCBot[^"]*"$ + - ^.*"[^"]*ChatGPT-User[^"]*"$ + - ^.*"[^"]*ClaudeBot[^"]*"$ + - ^.*"[^"]*Diffbot[^"]*"$ + - ^.*"[^"]*DuckAssistBot[^"]*"$ + - ^.*"[^"]*FacebookBot[^"]*"$ + - ^.*"[^"]*GPTBot[^"]*"$ + - ^.*"[^"]*Google-Extended[^"]*"$ + - ^.*"[^"]*Kangaroo Bot[^"]*"$ + - ^.*"[^"]*Meta-ExternalAgent[^"]*"$ + - ^.*"[^"]*Meta-ExternalFetcher[^"]*"$ + - ^.*"[^"]*OAI-SearchBot[^"]*"$ + - ^.*"[^"]*PerplexityBot[^"]*"$ + - ^.*"[^"]*Timpibot[^"]*"$ + - ^.*"[^"]*Webzio-Extended[^"]*"$ + - ^.*"[^"]*YouBot[^"]*"$ + - ^.*"[^"]*omgili[^"]*"$ + slskd-failedLogin: + actions: + ban: + cmd: + - sleep + - 0.01 + unban: + after: 4h + cmd: + - sleep + - 0.01 + regex: + - ^ .* "POST /slskd/api/v0/session HTTP/..." 401 [0-9]+ .https://ppom.me + - ^ .* "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: + - ^ .*"GET /(?:[^/" ]*/)*wp-login\.php + - ^ .*"GET /(?:[^/" ]*/)*wp-includes + - '^ .*"GET /(?:[^/" ]*/)*\.env ' + - '^ .*"GET /(?:[^/" ]*/)*config\.json ' + - '^ .*"GET /(?:[^/" ]*/)*info\.php ' + - '^ .*"GET /(?:[^/" ]*/)*owa/auth/logon.aspx ' + - '^ .*"GET /(?:[^/" ]*/)*auth.html ' + - '^ .*"GET /(?:[^/" ]*/)*auth1.html ' + - '^ .*"GET /(?:[^/" ]*/)*password.txt ' + - '^ .*"GET /(?:[^/" ]*/)*passwords.txt ' + - '^ .*"GET /(?:[^/" ]*/)*dns-query ' + - '^ .*"GET /(?:[^/" ]*/)*\.git/ '