• Stars
    star
    1,424
  • Rank 33,043 (Top 0.7 %)
  • Language
    C
  • License
    MIT License
  • Created over 6 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

low-overhead sampling profiler for PHP 7+

phpspy

phpspy is a low-overhead sampling profiler for PHP. It works with non-ZTS PHP 7.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.git
Cloning 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 -h
Usage:
  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 exit

Experimental 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>:-1
1 system_with_timeout /home/adam/php-src/run-tests.php:1137
2 run_test /home/adam/php-src/run-tests.php:1937
3 run_all_tests /home/adam/php-src/run-tests.php:1215
4 <main> /home/adam/php-src/run-tests.php:986
# - - - - -
...
^C
main_pgrep finished gracefully

Example (httpd)

$ sudo ./phpspy -p $(pgrep -n httpd)
0 Memcached::get <internal>:-1
1 Cache_MemcachedToggleable::get /foo/bar/lib/Cache/MemcachedToggleable.php:26
2 Cache_Memcached::get /foo/bar/lib/Cache/Memcached.php:251
3 IpDb_CacheBase::getFromCache /foo/bar/lib/IpDb/CacheBase.php:165
4 IpDb_CacheBase::get /foo/bar/lib/IpDb/CacheBase.php:107
5 IpDb_CacheBase::contains /foo/bar/lib/IpDb/CacheBase.php:70
6 IpDb_Botnet::has /foo/bar/lib/IpDb/Botnet.php:32
7 Security_Rule_IpAddr::__construct /foo/bar/lib/Security/Rule/IpAddr.php:53
8 Security_Rule_HttpRequestContext::initVariables /foo/bar/lib/Security/Rule/HttpRequestContext.php:22
9 Security_Rule_Context::__construct /foo/bar/lib/Security/Rule/Context.php:44
10 Security_Rule_Engine::getContextByName /foo/bar/lib/Security/Rule/Engine.php:225
11 Security_Rule_Engine::getContextByLocation /foo/bar/lib/Security/Rule/Engine.php:210
12 Security_Rule_Engine::evaluateActionRules /foo/bar/lib/Security/Rule/Engine.php:116
13 <main> /foo/bar/lib/bootstrap/api.php:49
14 <main> /foo/bar/htdocs/v3/public.php:5
# - - - - -
...

Example (cli child)

$ ./phpspy -- php -r 'usleep(100000);'
0 usleep <internal>:-1
1 <main> <internal>:-1

0 usleep <internal>:-1
1 <main> <internal>:-1

0 usleep <internal>:-1
1 <main> <internal>:-1

0 usleep <internal>:-1
1 <main> <internal>:-1

0 usleep <internal>:-1
1 <main> <internal>:-1

0 usleep <internal>:-1
1 <main> <internal>:-1

process_vm_readv: No such process

Example (cli attach)

$ php -r 'sleep(10);' &
[1] 28586
$ sudo ./phpspy -p 28586
0 sleep <internal>:-1
1 <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>:-1
1 <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

More Repositories

1

mle

flexible terminal-based text editor (C)
C
788
star
2

irslackd

self-hosted IRC gateway to Slack
JavaScript
160
star
3

rw.rs

free shell account and web 1.0 hosting @ http://rw.rs/~you
Shell
90
star
4

traer-js

Particle-based physics engine for JavaScript ported from Jeff Traer's Processing library
JavaScript
48
star
5

termbox-php

a termbox wrapper for PHP
C
31
star
6

flow-tools

Automatically exported from code.google.com/p/flow-tools
C
13
star
7

injection-php

libinjection PHP wrapper
C
10
star
8

php-lzo

lzo php extension
C
7
star
9

bashp

output shell commands as parsed JSON trees
C
7
star
10

gobashd

asynchronous queryable bash executor
Go
6
star
11

php4j

call PHP from Java
C
5
star
12

blackfish

MIDI sequencer
C
5
star
13

mlbuf

multiline buffer library
C
5
star
14

pwdrive

GnuPG+GDrive-based password vault
Shell
4
star
15

php-meta-sapi

PHP SAPI written in PHP (via FFI)
PHP
4
star
16

pymachinedrum

Python module for generating Elektron Machinedrum MIDI messages
Python
4
star
17

crawdb

Toy file-based read-write key-value store
C
4
star
18

inkfish

Scriptable MIDI controller and sequencer with plugin support for Elektron Machinedrum, Elektron Monomachine, Novation Launchpad
Java
4
star
19

xselect

a wait-for-stdin wrapper
C
3
star
20

ffmpeg-bodylang

🙊
PHP
3
star
21

elektron-tools

PHP
3
star
22

bpm-parrot

http://atoi.cc/parrot
JavaScript
3
star
23

nes-metroid

mirror of http://www.metroid-database.com/m1/sourcecode.php
3
star
24

syscall-examples

C
3
star
25

dyncall

mirror of dyncall at http://www.dyncall.org
C
3
star
26

nweb

a tiny, safe Web server (static pages only)
C
3
star
27

terminal-editors

Shell
2
star
28

xinject

C
2
star
29

ra-editor

an editor for the Waldorf RackAttack
Python
2
star
30

opl2fun

Arduino
2
star
31

phpkd

Go
2
star
32

fastmac

Shell
2
star
33

dssi

dssi mirror
C
2
star
34

sp

Easy access to file paths in your screen or tmux session
PHP
2
star
35

tree

Mirror of http://mama.indstate.edu/users/ice/tree/
C
2
star
36

mysw

C
2
star
37

QR2Clip

Scan QR code contents directly to clipboard
Java
2
star
38

voidrpc

C
2
star
39

lv2h

C
2
star
40

loghup

log rotation for stdout/stderr
C
2
star
41

pocketjet3plus-linux-setup

2
star
42

adsr

1
star
43

circbuf

a circular buffer cli tool
C
1
star
44

json_decode

cli wrapper for PHP's json_decode function
PHP
1
star
45

xfce4-terminal

personal fork of xfce terminal
C
1
star
46

adsr.github.io

HTML
1
star
47

ladspa-sdk

ladspa-sdk mirror
C
1
star
48

portmidi-php

a portmidi wrapper for PHP
C
1
star
49

rdio_ad_muter

I'm sorry Rdio
JavaScript
1
star
50

dotfiles

personal dotfiles
Shell
1
star
51

marble

C
1
star
52

epollbench

C
1
star
53

screen

GNU Screen
C
1
star
54

dssih

C
1
star
55

pcre-utf-test

C
1
star
56

katzify

Image processing script that automatically generates "Dr. Katz"-style animations from still images
PHP
1
star
57

pingtop2

1
star
58

twitch-avconv

Shell
1
star
59

TemplateRenderer

Minimal PHP template rendering library
PHP
1
star
60

keelpbx

Experimental PBX
Shell
1
star
61

nlua

branch of GNU nano 2.3.2 with hacky-as-shit Lua scriptability
C
1
star
62

wordplay

algorithmic wordplay
Python
1
star
63

ffvumeter

PHP
1
star
64

agar

Agar 1.4.1
C
1
star
65

farmhash

Automatically exported from code.google.com/p/farmhash
C++
1
star
66

a

'a' for abandoned
C
1
star
67

hiredis-php

Redis client for PHP
C
1
star
68

padviz

quick and dirty NES controller visualizer
C
1
star
69

dldyn

dynamically invoke functions in dynamic libraries
C
1
star
70

vte

personal fork of vte
C++
1
star
71

cmudict

fork of cmudict
1
star
72

alsa-lib

alsa-lib mirror
C
1
star
73

aoc2016

http://adventofcode.com/2016
PHP
1
star
74

pchan

Golang-style channels in C
C
1
star
75

railviz

Messing around with transit timetables
Go
1
star
76

mkcstubs

generate function stubs and synchronize function signatures across header and source files
PHP
1
star