Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

low-overhead sampling profiler for PHP 7+

License

NotificationsYou must be signed in to change notification settings

adsr/phpspy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

phpspy is a low-overhead sampling profiler for PHP. It works with non-ZTS PHP7.0+ with CLI, Apache, and FPM SAPIs on 64-bit Linux 3.2+.

Build Status

Demos

You can profile PHP scripts:

child

You can attach to running PHP processes:

attach cli

attach httpd

It has a top-like mode:

top

It can collect request info, memory usage, and variables:

advanced

You can also use it to make flamegraphs like this:

FlameGraph example

All with no changes to your application and minimal overhead.

Synopsis

$ git clone https://github.com/adsr/phpspy.gitCloning into 'phpspy'......$ cd phpspy$ make...$ sudo ./phpspy --limit=1000 --pid=$(pgrep -n httpd) >traces...$ ./stackcollapse-phpspy.pl <traces | ./vendor/flamegraph.pl >flame.svg$ google-chrome flame.svg # View flame.svg in browser

Build options

$ make                   # Use built-in structs$ # or$ USE_ZEND=1 make ...    # Use Zend structs (requires PHP development headers)

Usage

$ ./phpspy -hUsage:  phpspy [options] -p <pid>  phpspy [options] -P <pgrep-args>  phpspy [options] [--] <cmd>Options:  -h, --help                         Show this help  -p, --pid=<pid>                    Trace PHP process at `pid`  -P, --pgrep=<args>                 Concurrently trace processes that                                       match pgrep `args` (see also `-T`)  -T, --threads=<num>                Set number of threads to use with `-P`                                       (default: 16)  -s, --sleep-ns=<ns>                Sleep `ns` nanoseconds between traces                                       (see also `-H`) (default: 10101010)  -H, --rate-hz=<hz>                 Trace `hz` times per second                                       (see also `-s`) (default: 99)  -V, --php-version=<ver>            Set PHP version                                       (default: auto;                                       supported: 70 71 72 73 74 80 81 82)  -l, --limit=<num>                  Limit total number of traces to capture                                       (approximate limit in pgrep mode)                                       (default: 0; 0=unlimited)  -i, --time-limit-ms=<ms>           Stop tracing after `ms` milliseconds                                       (second granularity in pgrep mode)                                       (default: 0; 0=unlimited)  -n, --max-depth=<max>              Set max stack trace depth                                       (default: -1; -1=unlimited)  -r, --request-info=<opts>          Set request info parts to capture                                       (q=query c=cookie u=uri p=path                                       capital=negation)                                       (default: QCUP; none)  -m, --memory-usage                 Capture peak and current memory usage                                       with each trace (requires target PHP                                       process to have debug symbols)  -o, --output=<path>                Write phpspy output to `path`                                       (default: -; -=stdout)  -O, --child-stdout=<path>          Write child stdout to `path`                                       (default: phpspy.%d.out)  -E, --child-stderr=<path>          Write child stderr to `path`                                       (default: phpspy.%d.err)  -x, --addr-executor-globals=<hex>  Set address of executor_globals in hex                                       (default: 0; 0=find dynamically)  -a, --addr-sapi-globals=<hex>      Set address of sapi_globals in hex                                       (default: 0; 0=find dynamically)  -1, --single-line                  Output in single-line mode  -b, --buffer-size=<size>           Set output buffer size to `size`.                                       Note: In `-P` mode, setting this                                       above PIPE_BUF (4096) may lead to                                       interlaced writes across threads                                       unless `-J m` is specified.                                       (default: 4096)  -f, --filter=<regex>               Filter output by POSIX regex                                       (default: none)  -F, --filter-negate=<regex>        Same as `-f` except negated  -d, --verbose-fields=<opts>        Set verbose output fields                                       (p=pid t=timestamp                                       capital=negation)                                       (default: PT; none)  -c, --continue-on-error            Attempt to continue tracing after                                       encountering an error  -#, --comment=<any>                Ignored; intended for self-documenting                                       commands  -@, --nothing                      Ignored  -v, --version                      Print phpspy version and exitExperimental options:  -j, --event-handler=<handler>      Set event handler (fout, callgrind)                                       (default: fout)  -J, --event-handler-opts=<opts>    Set event handler options                                       (fout: m=use mutex to prevent                                       interlaced writes on stdout in `-P`                                       mode)  -S, --pause-process                Pause process while reading stacktrace                                       (unsafe for production!)  -e, --peek-var=<varspec>           Peek at the contents of the var located                                       at `varspec`, which has the format:                                       <varname>@<path>:<lineno>                                       <varname>@<path>:<start>-<end>                                       e.g., xyz@/path/to.php:10-20  -g, --peek-global=<glospec>        Peek at the contents of a global var                                       located at `glospec`, which has                                       the format: <global>.<key>                                       where <global> is one of:                                       post|get|cookie|server|files|globals                                       e.g., server.REQUEST_TIME  -t, --top                          Show dynamic top-like output

Example (variable peek)

$ sudo ./phpspy -e 'i@/var/www/test/lib/test.php:12' -p $(pgrep -n httpd) | grep varpeek# varpeek i@/var/www/test/lib/test.php:12 = 42# varpeek i@/var/www/test/lib/test.php:12 = 42# varpeek i@/var/www/test/lib/test.php:12 = 43# varpeek i@/var/www/test/lib/test.php:12 = 44...

Example (pgrep daemon mode)

$ sudo ./phpspy -H1 -T4 -P '-x php'0 proc_open <internal>:-11 system_with_timeout /home/adam/php-src/run-tests.php:11372 run_test /home/adam/php-src/run-tests.php:19373 run_all_tests /home/adam/php-src/run-tests.php:12154 <main> /home/adam/php-src/run-tests.php:986# - - - - -...^Cmain_pgrep finished gracefully

Example (httpd)

$ sudo ./phpspy -p $(pgrep -n httpd)0 Memcached::get <internal>:-11 Cache_MemcachedToggleable::get /foo/bar/lib/Cache/MemcachedToggleable.php:262 Cache_Memcached::get /foo/bar/lib/Cache/Memcached.php:2513 IpDb_CacheBase::getFromCache /foo/bar/lib/IpDb/CacheBase.php:1654 IpDb_CacheBase::get /foo/bar/lib/IpDb/CacheBase.php:1075 IpDb_CacheBase::contains /foo/bar/lib/IpDb/CacheBase.php:706 IpDb_Botnet::has /foo/bar/lib/IpDb/Botnet.php:327 Security_Rule_IpAddr::__construct /foo/bar/lib/Security/Rule/IpAddr.php:538 Security_Rule_HttpRequestContext::initVariables /foo/bar/lib/Security/Rule/HttpRequestContext.php:229 Security_Rule_Context::__construct /foo/bar/lib/Security/Rule/Context.php:4410 Security_Rule_Engine::getContextByName /foo/bar/lib/Security/Rule/Engine.php:22511 Security_Rule_Engine::getContextByLocation /foo/bar/lib/Security/Rule/Engine.php:21012 Security_Rule_Engine::evaluateActionRules /foo/bar/lib/Security/Rule/Engine.php:11613 <main> /foo/bar/lib/bootstrap/api.php:4914 <main> /foo/bar/htdocs/v3/public.php:5# - - - - -...

Example (cli child)

$ ./phpspy -- php -r 'usleep(100000);'0 usleep <internal>:-11 <main> <internal>:-10 usleep <internal>:-11 <main> <internal>:-10 usleep <internal>:-11 <main> <internal>:-10 usleep <internal>:-11 <main> <internal>:-10 usleep <internal>:-11 <main> <internal>:-10 usleep <internal>:-11 <main> <internal>:-1process_vm_readv: No such process

Example (cli attach)

$ php -r 'sleep(10);' &[1] 28586$ sudo ./phpspy -p 285860 sleep <internal>:-11 <main> <internal>:-1...

Example (docker)

$ docker build . -t phpspy$ docker run -it --cap-add SYS_PTRACE phpspy:latest ./phpspy/phpspy -V73 -r -- php -r 'sleep(1);'0 sleep <internal>:-11 <main> <internal>:-1...

Known bugs

  • phpspy may not work with a chrooted mod_php process whose binary lives inside overlayfs. (See#109.)

See also

TODO

About

low-overhead sampling profiler for PHP 7+

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors13


[8]ページ先頭

©2009-2025 Movatter.jp