Swoole PHP Tools

Swoole brings a new environment to the developer and allows you to take advantage of coroutines and stateful requests, with that being said, it means some tools we are use to in the PHP world either need to be updated or we must adopt new ways of doing things.

Once you understand the basics of what Swoole offers and realise the performance benefits and adopt the coroutine model when programming, you will quickly begin to see how easy it is to integrate with Swoole, as you can widely keep on doing what you already do within your applications, just some API or setup changes are required, Swoole Hooks make this much easier.

Swoole aims to support the existing PHP ecosystem as much as possible and we already have a wide range of tools to use during development and production, let's take a look at them.


Tools Supported By Swoole


Swoole IDE Helper

Swoole is installed as a PHP PECL extension and adds a lot of functionality and API to the PHP language. Because of this it is nice to be able to access type hinting and help from your IDE to guide you when using the Swoole API. There is an official Swoole IDE Helper for PHPStorm, you can install it by searching for the Swoole IDE Helper as a plugin but the GitHub repository can be found here. You can also find the PHPStorm plugin page here.

YASD (Yet Another Swoole Debugger)

Most PHP developers are aware of XDebug which provides a range of debugging features, this includes things like step debugging, improved error reporting, tracing, code profiling etc. However, currently, XDebug does not support the use of Swoole due to coroutines but we do have YASD.

YASD is very similar to XDebug but it has fully support for PHP FPM and Swoole, even when using coroutines. You can link up YASD to your IDE and use it like you would with XDebug.

Currently YASD supports VSCode and PHPStorm but you can also use it with just the terminal.

You can find the GitHub repository and documentation here.

With YASD you can use breakpoints, step over, step into, step out and watch variable changes etc.

Currently, YASD is in active development and is experimental


TCP Dump

Usually when developing PHP applications you let Apache or Nginx handle a lot of the network communication between the client and server, however, Swoole enables you to handle a lot of networking operations at the PHP level. So it is good to get use to how we can monitor and debug problematic network communication issues.

One way we can monitor TCP traffic is with tcpdump and is available on most Linux distributions. This program allows us to display transmitted or received packets over a network and monitor the outcome. With Swoole this is useful for seeing traffic when running a HTTP server.

For example, we can do sudo tcpdump -i any tcp port 9501, meaning:

  • The -i parameter specifies the network card, any means all network cards
  • The next parameter tcp means we want to only monitor tcp traffic
  • And the port is where your Swoole HTTP server is running

This kind of command will get us an output similar to:

13:29:07.788802 IP localhost.42333 > localhost.9501: Flags [S], seq 828582357, win 43690, options [mss 65495,sackOK,TS val 2207513 ecr 0,nop,wscale 7], length 0
13:29:07.788815 IP localhost.9501 > localhost.42333: Flags [S.], seq 1242884615, ack 828582358, win 43690, options [mss 65495,sackOK,TS val 2207513 ecr 2207513,nop,wscale 7], length 0
13:29:07.788830 IP localhost.42333 > localhost.9501: Flags [.], ack 1, win 342, options [nop,nop,TS val 2207513 ecr 2207513], length 0
13:29:10.298686 IP localhost.42333 > localhost.9501: Flags [P.], seq 1:5, ack 1, win 342, options [nop,nop,TS val 2208141 ecr 2207513], length 4
13:29:10.298708 IP localhost.9501 > localhost.42333: Flags [.], ack 5, win 342, options [nop,nop,TS val 2208141 ecr 2208141], length 0
13:29:10.298795 IP localhost.9501 > localhost.42333: Flags [P.], seq 1:13, ack 5, win 342, options [nop,nop,TS val 2208141 ecr 2208141], length 12
13:29:10.298803 IP localhost.42333 > localhost.9501: Flags [.], ack 13, win 342, options [nop,nop,TS val 2208141 ecr 2208141], length 0
13:29:11.563361 IP localhost.42333 > localhost.9501: Flags [F.], seq 5, ack 13, win 342, options [nop,nop,TS val 2208457 ecr 2208141], length 0
13:29:11.563450 IP localhost.9501 > localhost.42333: Flags [F.], seq 13, ack 6, win 342, options [nop,nop,TS val 2208457 ecr 2208457], length 0
13:29:11.563473 IP localhost.42333 > localhost.9501: Flags [.], ack 14, win 342, options [nop,nop,TS val 2208457 ecr 2208457], length 0

From this output you can monitor the time of request/connection, client and server communication, type of request being sent or received, information about the data packets and the size of the data being sent. There are more options you can add and tcpdump is very powerful, there is more documentation for tcpdump on their page.


STrace

When developing with Swoole and you come across a problem, you can use strace to debug problems related to system calls, process and kernel communication. Displaying signal deliveries and changes of process states. This is more for advanced debugging but can come in useful.

For example, we can run the following command: strace -o /tmp/strace.log -f -p $PID

  • -f Means to track multi-threaded and multi-processes, if you do not add the -f parameter, you cannot capture the running status of the child processes and the child threads
  • -o Means output the result to a file
  • -p $PID, specify the tracked process ID, which can be seen through ps aux
  • -tt Print the time when the system call occurred
  • -s Limits the length of the string to be printed, such as the data received by the recvfrom system call, only 32 bytes are printed by default
  • -c Real-time statistics of the time consumed for each system call
  • -T Print the time consumed for each system call

You can find more information for strace on their GitHub.

Truss can be used for FreeBSD or MacOS


GDB (GNU Project debugger)

GDB is a powerful UNIX program used for debugging C/C++ applications, it is released by the GNU open source organisation. Because PHP and Swoole are developed with C++ we are able to use GDB to debug a PHP+Swoole application.

You use GDB on the command line and some of the use cases are:

  • Track the running PHP program, use gdb -p <process ID>
  • Use gdb to run and debug PHP programs, use gdb php -> run server.php to debug
  • After the coredump of the PHP program, use gdb to load the core memory image for debugging with gdb php core

You can find more information about GDB on their website.


Zbacktrace

With GDB there is a custom command provided by PHP itself called zbacktrace and it enables you to see the call stack at the PHP level instead of seeing call stacks from C/C++ code. This is helpful because it allows you to debug PHP functions rather than C/C++ functions.

Because zbacktrace is developed by the PHP Group itself, the required file called .gdbinit can be downloaded from the PHP GitHub.

Once you have the .gdbinit, open a gdb shell and enter:

source .gdbinit
zbacktrace

You can then use gdb -p <Process ID> to debug your PHP code.

  • Use ps aux tools to identify the Worker process ID you want to trace
  • Then by running gdb -p <Process ID> you can trace the process
  • Repeated calls ctrl + c, zbacktrace, c cycle through the program segment which occurs in PHP code


LSOF

On Linux platforms you can use the command lsof which means "list open files" and can be used to view open file handles by a process. It can be used to track open sockets, files and resources by Swoole's worker processes.

To track a process, you can run lsof -p <Process ID>.

More information and documentation can be found here.


Perf

The command perf is included with the Linux Kernel, it is a dynamic tracing tool which can be used for tracepoints, kprobes, uprobes and lightweight profiling.

You can use perf to analyse the performance of a running program in realtime, for example, we can use the following:

perf top ip <Process ID>

Which will allow us to see in realtime where the program spends most of its time and the events which are called. This is useful because you can work out which part of your program is taking up more CPU cycles.

Logging instead of steps debugging

The principal problem with debugging is that it doesn’t scale. (…) in order to catch bugs, we often need to be able to run with sufficiently large and representative data sets. When we’re at this point, the debugger is usually a crude tool to use (…) Using a debugger doesn’t scale. Types and tools and tests do.