it profiles

Signed-off-by: Ava Hahn <a.hahn@f5.com>
This commit is contained in:
Ava Hahn 2025-08-25 23:04:54 +00:00
parent 8924f2ef22
commit d07bf56cd7
7 changed files with 112 additions and 33 deletions

View file

@ -1,6 +1,11 @@
FROM archlinux:latest FROM archlinux:latest
RUN pacman -Sy curl --noconfirm RUN pacman -Sy git base-devel curl luajit unzip --noconfirm
RUN git clone https://github.com/wg/wrk
WORKDIR /wrk
RUN make
WORKDIR /
COPY run.sh / COPY run.sh /
CMD ["/run.sh"] CMD ["/run.sh"]

View file

@ -1,28 +1,42 @@
#!/bin/bash #!/bin/bash
log_request () { function log_request_to () {
return_code=$(curl -Sikl -o /dev/null -w "%{http_code}" $1 2>/dev/null) return_code=$(curl -Sikl -o /dev/null -w "%{http_code}" $1 2>/dev/null)
case ${return_code:0:1} in case ${return_code:0:1} in
"4" | "5") "4" | "5")
echo "query of $1 returned $return_code" echo "query of $1 returned $return_code"
return 1
;; ;;
*) *)
return 0
;; ;;
esac esac
} }
while : function do_wrk_on () {
do /wrk/wrk -t1 -c10 $1 &
log_request "https://kaproxy:8080/0" }
log_request "https://kaproxy:8080/1"
log_request "https://kaproxy:8080/2"
log_request "https://kaproxy:8080/3"
log_request "https://kaproxy:8080/4"
log_request "https://kaproxy:8080/5"
log_request "https://kaproxy:8080/6"
log_request "https://kaproxy:8080/7"
log_request "https://kaproxy:8080/8"
log_request "https://kaproxy:8080/9"
done
# TODO: use wrk2 or something to stress test endpoints I dunno function sigint_handler() {
jobs -p | xargs kill -9
exit
}
trap 'sigint_handler' INT
// TODO: make this a more elegant item
// maybe a while loop with curl
sleep 0.5
do_wrk_on "https://kaproxy:8080/0"
do_wrk_on "https://kaproxy:8080/1"
do_wrk_on "https://kaproxy:8080/2"
do_wrk_on "https://kaproxy:8080/3"
do_wrk_on "https://kaproxy:8080/4"
do_wrk_on "https://kaproxy:8080/5"
do_wrk_on "https://kaproxy:8080/6"
do_wrk_on "https://kaproxy:8080/7"
do_wrk_on "https://kaproxy:8080/8"
do_wrk_on "https://kaproxy:8080/9"
wait $(jobs -p)

View file

@ -2,13 +2,13 @@ FROM archlinux:latest
EXPOSE 8080 EXPOSE 8080
RUN pacman -Syyu --noconfirm RUN pacman -Syyu --noconfirm
RUN pacman -S base-devel glibc gcc-libs perf --noconfirm RUN pacman -S base-devel glibc gcc-libs valgrind --noconfirm
COPY nginx /nginx COPY nginx /nginx
WORKDIR /nginx WORKDIR /nginx
RUN auto/configure \ RUN auto/configure \
--with-debug \ --with-debug \
--with-http_ssl_module \ --with-http_ssl_module \
--with-cc-opt="-ggdb -fno-omit-frame-pointer" --with-cc-opt="-gdwarf-4 -fno-omit-frame-pointer"
RUN make RUN make
RUN make install RUN make install
COPY nginx.conf / COPY nginx.conf /

@ -1 +0,0 @@
Subproject commit 64d0795ac41836b6be8fcceba68f1dbb62b4035a

View file

@ -1,9 +1,9 @@
worker_processes 5; worker_processes 10;
error_log /dev/stdout notice; error_log /dev/stdout notice;
pid /tmp/pid; pid /tmp/pid;
events { events {
worker_connections 20; worker_connections 10;
} }
http { http {

View file

@ -1,20 +1,23 @@
#!/bin/bash #!/bin/bash
function p_invoke() { function p_invoke() {
perf record -F1000 --call-graph dwarf -o /perf.data \ # set trace-children=yes to profile worker processes
-- /nginx/objs/nginx \ valgrind --tool=callgrind \
-p /tmp \ --trace-children=no \
-e /tmp/error.log \ --callgrind-out-file=/tmp/callgrind.output \
-c /nginx.conf \ /nginx/objs/nginx \
-p /tmp \
-e /tmp/error.log \
-c /nginx.conf \
-g "daemon off;" -g "daemon off;"
} }
function invoke() { function invoke() {
/nginx/objs/nginx \ /nginx/objs/nginx \
-p /tmp \ -p /tmp \
-e /tmp/error.log \ -e /tmp/error.log \
-c /nginx.conf \ -c /nginx.conf \
-g "daemon off;" \ -g "daemon off;" \
$@ $@
} }

62
run.sh
View file

@ -1,5 +1,63 @@
#!/bin/zsh #!/bin/zsh
if [[ ! $1 ]]; then
echo "Error: expected one argument (nginx code directory)"
exit
fi
if [[ ! -d $1 ]]; then
echo "Error: provided nginx code directory is invalid"
exit
fi
PROFILE_OUTPUT=PROFILE.LOG
if [ -f $PROFILE_OUTPUT ]; then
mv $PROFILE_OUTPUT $PROFILE_OUTPUT.old
fi
KACLIENT=nginx-profile-setup-kaclient-1
KAPROXY=nginx-profile-setup-kaproxy-1
echo "[+] building and deploying containers"
go build keepalive-svc.go go build keepalive-svc.go
mv keepalive-svc kasvc/ mv keepalive-svc kasvc/
rsync -avz ../nginx kaproxy/ rsync -avz $1 kaproxy/
sudo docker-compose up --build sudo docker-compose up --build -d
sudo docker exec -it $KAPROXY callgrind_control -i off
sudo docker wait $KACLIENT
echo "[+] client finished, triggering reload"
sudo docker exec -it $KAPROXY callgrind_control -i on
sudo docker kill -s CONT $KAPROXY
echo "[+] wait five seconds for reload complete"
sleep 5
sudo docker exec -it $KAPROXY callgrind_control -i off
echo " > restarting client"
sudo docker-compose restart kaclient
sudo docker wait $KACLIENT
echo "[+] client finished again. Killing NGINX and fetching profile data"
sudo docker kill -s INT $KAPROXY
sudo docker exec -it $KAPROXY callgrind_control -d
echo "[+] building profiling report"
sudo docker exec $KAPROXY bash -c "find /tmp -iname \"callgrind.out*\"" | while read file
do
echo " > processing: " $file
F=$(basename $file)
sudo docker cp $KAPROXY:$file $F;
sudo chmod 777 $F
echo "Output file: $F" >> $PROFILE_OUTPUT
callgrind_annotate \
--include=kaproxy \
--auto=yes \
$F >> $PROFILE_OUTPUT
echo "End of profile: $F\n\n\n" >> $PROFILE_OUTPUT
rm -f $F
done
echo "[+] cleaning up"
sudo docker-compose down
less $PROFILE_OUTPUT