- Uses py-spy under the covers. See here for all invocation params.
- Uses shared PID namespaces,
SYS_PTRACE
capability, and heuristics for PID identification to attach to the appropriate live/unmodified Agent running in a separate container. - Assumes that the name of the agent container is
dd-agent
but you can easily modifyprofiler.sh
to match either the container ID or name.
Note: In theory, this tool supports Python up to 3.10 as of this writing (Nov 2021).
$ # "top"-like dynamic UI
$ ./profiler.sh
$ # With custom options (flamegraph in this case). Output saved in bind-mounted CWD.
$ ./profiler.sh record -d 30 -r 100 -o /output/profile.svg
$ # With custom options (dump callstack in this case)
$ # This is a bit useless for the agent as we run the checks at periodic intervals
$ ./profiler.sh dump
$ # "top"-like dynamic UI
$ docker run --rm -it \
--name="dd-agent-profiler" \
--pid="container:${AGENT_CONTAINER_ID}" \
--cap-add="SYS_PTRACE" \
--security-opt="seccomp=unconfined" \
--security-opt="apparmor=unconfined" \
datadog/agent-dev:pyprof
$ # With custom options (flamegraph in this case). Output saved in bind-mounted CWD.
$ docker run --rm -it \
--name="dd-agent-profiler" \
--pid="container:${AGENT_CONTAINER_ID}" \
--cap-add="SYS_PTRACE" \
--security-opt="seccomp=unconfined" \
--security-opt="apparmor=unconfined" \
-v "$(pwd):/output" \
datadog/agent-dev:pyprof record -d 30 -r 100 -o /output/profile.svg
$ # With custom options (dump callstack in this case)
$ # This is a bit useless for the agent as we run the checks at periodic intervals
$ docker run --rm -it \
--name="dd-agent-profiler" \
--pid="container:${AGENT_CONTAINER_ID}" \
--cap-add="SYS_PTRACE" \
--security-opt="seccomp=unconfined" \
--security-opt="apparmor=unconfined" \
datadog/agent-dev:pyprof dump