{"id":13490401,"url":"https://github.com/NoiseByNorthwest/php-spx","last_synced_at":"2025-03-28T06:31:13.254Z","repository":{"id":38451531,"uuid":"94931170","full_name":"NoiseByNorthwest/php-spx","owner":"NoiseByNorthwest","description":"A simple \u0026 straight-to-the-point PHP profiling extension with its built-in web UI","archived":false,"fork":false,"pushed_at":"2025-01-04T12:26:14.000Z","size":7994,"stargazers_count":2272,"open_issues_count":62,"forks_count":90,"subscribers_count":36,"default_branch":"master","last_synced_at":"2025-03-27T14:03:01.440Z","etag":null,"topics":["data-visualization","flamegraph","performance-analysis","php","php-extension","profiler","reverse-engineering","statistical-profiling","tracer","visualization"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/NoiseByNorthwest.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-06-20T20:14:41.000Z","updated_at":"2025-03-26T07:33:21.000Z","dependencies_parsed_at":"2024-08-06T15:47:25.728Z","dependency_job_id":"7bf9569e-b37a-47a9-ac8a-7e6cef12ebb4","html_url":"https://github.com/NoiseByNorthwest/php-spx","commit_stats":{"total_commits":323,"total_committers":22,"mean_commits":"14.681818181818182","dds":"0.33746130030959753","last_synced_commit":"6196f0b1778169b951e55491945c018da083b826"},"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NoiseByNorthwest%2Fphp-spx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NoiseByNorthwest%2Fphp-spx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NoiseByNorthwest%2Fphp-spx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NoiseByNorthwest%2Fphp-spx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NoiseByNorthwest","download_url":"https://codeload.github.com/NoiseByNorthwest/php-spx/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245984423,"owners_count":20704791,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["data-visualization","flamegraph","performance-analysis","php","php-extension","profiler","reverse-engineering","statistical-profiling","tracer","visualization"],"created_at":"2024-07-31T19:00:46.126Z","updated_at":"2025-03-28T06:31:13.219Z","avatar_url":"https://github.com/NoiseByNorthwest.png","language":"C","funding_links":["https://www.buymeacoffee.com/noisebynw"],"categories":["C","代码分析","Languages"],"sub_categories":[],"readme":"# SPX - A simple profiler for PHP\n\n[![Build Status][:badge-ci:]][:link-ci:]\n![Supported PHP versions: 5.4 .. 8.x][:badge-php-versions:]\n![Supported platforms: GNU/Linux, macOS \u0026 FreeBSD][:badge-supported-platforms:]\n![Supported architectures: x86-64 or ARM64][:badge-supported-arch:]\n[![License][:badge-license:]][:link-license:]\n\n\n\u003ca href=\"https://www.buymeacoffee.com/noisebynw\" target=\"_blank\"\u003e\u003cimg src=\"https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png\" alt=\"Buy Me A Coffee\" style=\"height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;\" \u003e\u003c/a\u003e\n\n\n[Click here for a live demo of the analysis screen](https://noisebynorthwest.github.io/php-spx/demo/report.html?key=spx-full-20191229_175636-06d2fe5ee423-3795-233665123)\n\n![Showcase](https://github.com/NoiseByNorthwest/NoiseByNorthwest.github.io/blob/d8a90827d6eb256f49d580de448b6b6fad4119ac/php-spx/doc/as.apng)\n\n![Showcase](https://github.com/NoiseByNorthwest/NoiseByNorthwest.github.io/blob/43e3ffe185a1dcec70e7c8ced36acfdf316bae65/php-spx/doc/fp1.gif)\n\nSPX, which stands for _Simple Profiling eXtension_, is just another profiling extension for PHP.\nIt differentiates itself from other similar extensions as being:\n* totally free and confined to your infrastructure (i.e. no data leaks to a SaaS).\n* very simple to use: just set an environment variable (command line) or switch on a radio button (web request) to profile your script. Thus, you are free of:\n  * manually instrumenting your code (Ctrl-C a long running command line script is even supported).\n  * using a dedicated browser extension or command line launcher.\n* [multi metrics](#available-metrics) capable: 22 are currently supported (various time \u0026 memory metrics, included files, objects in use, I/O...).\n* able to collect data without losing context. For example Xhprof (and potentially its forks) aggregates data per caller / callee pairs, which implies the loss of the full call stack and forbids timeline or Flamegraph based analysis.\n* shipped with its [web UI](#web-ui) which allows to:\n  * enable / configure profiling for the current browser session\n  * list profiled script reports\n  * select a report for in-depth analysis, featuring these interactive visualizations:\n    * timeline (scale to millions of function calls)\n    * flat profile\n    * Flamegraph\n\n## Requirements\n\nPlatforms support is currently quite limited. Feel free to open an issue if your platform is not supported.\nCurrent requirements are:\n\n* x86-64 or ARM64\n* **GNU/Linux**, **macOS** or **FreeBSD**\n* zlib dev package (e.g. zlib1g-dev on Debian based distros)\n* PHP 5.4 to 8.4\n\n## Installation\n\n### Prerequisites\n\n* PHP development package (corresponding to your installed PHP version).\n* zlib development package:\n  * For Debian based distros (including Ubuntu, Kubuntu...), just run: `sudo apt-get install zlib1g-dev`.\n  * For Fedora based distros (including CentOS, AlmaLinux, Rocky Linux...), just run: `sudo dnf install zlib-devel`.\n\n### Install the extension\n\n```shell\ngit clone https://github.com/NoiseByNorthwest/php-spx.git\ncd php-spx\ngit checkout release/latest\nphpize\n./configure\nmake\nsudo make install\n```\n\nThen add `extension=spx.so` to your *php.ini*, or in a dedicated *spx.ini* file created within the include directory.\nYou may also want to override [default SPX configuration](#configuration) to be able to profile a web request, with [this one](#private-environment) for example for a local development environment.\n\n\n### ZTS PHP (multi-thread)\n\nZTS PHP is supported, with these extra limitations:\n- a little overhead (theorically unnoticeable in most cases) is added when SPX is loaded, even if it is not enabled.\n- Ctrl-C a CLI script will not make the possible profiling session to be properly finished.\n- segfaults are more likely than for NTS PHP. In this regard, avoid more than ever mixing SPX with other instrumenting extensions (debuggers, profilers...).\n\nAlso, consider ZTS PHP support as still being in beta.\n\n### Linux, PHP-FPM \u0026 I/O stats\n\nOn GNU/Linux, SPX uses procfs (i.e. by reading files under `/proc` directory) to get some stats for the current process or thread. This is what is done under the hood when you select at least one of these metrics: `mor`, `io`, `ior` or `iow`.\n\nBut, on most PHP-FPM setups, you will have a permission issue preventing SPX to open a file under `/proc/self` directory.\nThis is due to the fact that PHP-FPM master process runs as root when child processes run as another unprivileged user.\n\nWhen this is the case, the `process.dumpable = yes` line must be added to the FPM pool configuration so that child processes will be able to read any file under `/proc/self`.\n\n## Development status\n\nThis is still **experimental**. API might change, features might be added or dropped, or development could be frozen.\n\nYou can still safely use it in a **non-production** environment.\n\nContributions are welcome but be aware of the experimental status of this project and **please follow the contribution rules** described here: [CONTRIBUTING.md](CONTRIBUTING.md)\n\n## Basic usage\n\n### web request\n\nAssuming a development environment with the configuration [described here](#private-environment) and your application is accessible via `http://localhost`.\n\nJust open with your browser the following URL: `http://localhost/?SPX_KEY=dev\u0026SPX_UI_URI=/` to access to the web UI [control panel](#control-panel).\n\n_N.B.: `http://localhost/` must be served by a PHP script through standard web server feature like directory index or URL rewriting. The PHP script will however not be executed, SPX will intercept and disable its execution to serve its content in place._\n\n_If you see only a blank page then make sure to set `zlib.output_compression = 0` in your PHP configuration file_\n\nYou will then see the following form:\n\n![Showcase](https://github.com/NoiseByNorthwest/NoiseByNorthwest.github.io/blob/93baabbcba04223586d06756dbcecfbd6ec1293d/php-spx/doc/cp-form.png)\n\nThen switch on \"Enabled\". At this point profiling is enabled for the current domain and your current browser session through a set of dedicated cookies.\n\nProfiling can also be triggered with Curl as shown in this example:\n\n`curl --cookie \"SPX_ENABLED=1; SPX_KEY=dev\" http://localhost/`\n\n_N.B.: You can also enable the profiling at INI configuration level via the `spx.http_profiling_enabled` [setting](#configuration), and therefore for all HTTP requests. However, keep in mind that using this setting on a high-traffic environment could quickly exhaust the storage device's capacity of the SPX's data directory._\n\nThen refresh the web request you want to profile and refresh the control panel to see the generated report in the list below the control panel form.\n\n![Showcase](https://github.com/NoiseByNorthwest/NoiseByNorthwest.github.io/blob/d8a90827d6eb256f49d580de448b6b6fad4119ac/php-spx/doc/cp-list2.png)\n\nThen click on the report in the list and enjoy the [analysis screen](#analysis-screen).\n\n### Command line script\n\n#### Instant flat profile\n\nJust prepend your command line with `SPX_ENABLED=1` to trigger profiling. You will get the flat profile printed on STDERR at the end of the execution, even if you abort it by hitting Ctrl-C, as in the following example:\n\n```shell\n$ SPX_ENABLED=1 composer update\nLoading composer repositories with package information\nUpdating dependencies (including require-dev)\n^C\n*** SPX Report ***\n\nGlobal stats:\n\n  Called functions    :    27.5K\n  Distinct functions  :      714\n\n  Wall time           :    7.39s\n  ZE memory           :   62.6MB\n\nFlat profile:\n\n Wall time           | ZE memory           |\n Inc.     | *Exc.    | Inc.     | Exc.     | Called   | Function\n----------+----------+----------+----------+----------+----------\n  101.6ms |  101.6ms |   41.8MB |   41.8MB |       12 | Composer\\Json\\JsonFile::parseJson\n   53.6ms |   53.6ms |     544B |     544B |        4 | Composer\\Cache::sha256\n    6.91s |   41.5ms |   41.5MB |   -7.5MB |        4 | Composer\\Repository\\ComposerRepository::fetchFile\n    6.85s |   32.3ms |   47.5MB |    5.4MB |        5 | 1@Composer\\Repository\\ComposerRepository::loadProviderListings\n    7.8ms |    7.8ms |       0B |       0B |        4 | Composer\\Cache::write\n    1.1ms |    1.1ms |     -72B |     -72B |        1 | Composer\\Console\\Application::Composer\\Console\\{closure}\n  828.5us |  828.5us |     976B |     976B |       12 | Composer\\Util\\RemoteFilesystem::findHeaderValue\n  497.6us |  491.0us |  710.2KB |  710.2KB |        1 | Composer\\Cache::read\n    2.4ms |  332.6us |   20.9KB | -378.8KB |       34 | 3@Symfony\\Component\\Finder\\Iterator\\FilterIterator::rewind\n  298.9us |  298.9us |    2.2KB |    2.2KB |       47 | Symfony\\Component\\Finder\\Iterator\\FileTypeFilterIterator::accept\n```\n\nN.B.: Just add `SPX_FP_LIVE=1` to enable the live refresh of the flat profile during script execution.\n\n#### Generate profiling report for the web UI\n\nYou just have to specify `SPX_REPORT=full` to generate a report available via the web UI:\n\n```shell\nSPX_ENABLED=1 SPX_REPORT=full ./bin/console cache:clear\n```\n\n\n#### Handle long-living / daemon processes\n\nIf your CLI script is long-living and/or daemonized (e.g. via supervisord), profiling its whole lifespan could be meaningless. This is especially true in case of a service waiting for tasks to process.  \nTo handle this case, SPX allows to disable the automatic start of profiling and exposes 2 userland functions, `spx_profiler_start(): void` \u0026 `spx_profiler_stop(): ?string`, in order to respectively control the start and the end of the profiled spans.  \n\nHere is how you can instrument your script:\n\n```php\n\u003c?php\n\nwhile ($task = get_next_ready_task()) {\n  spx_profiler_start();\n  try {\n    $task-\u003eprocess();\n  } finally {\n    spx_profiler_stop();\n  }\n}\n\n```\n\nAnd of course this script must be run at least with profiling enabled and the automatic start disabled as in the following command:\n\n```shell\nSPX_ENABLED=1 SPX_REPORT=full SPX_AUTO_START=0 my_script.php\n```\n\nAutomatic start can also be disabled for web requests via the `spx.http_profiling_auto_start` INI parameter or via the control panel.\n\n\nSide notes:\n- `spx_profiler_start()` and `spx_profiler_stop()` can safely be nested.\n- when profiling with the _full_ report type, `spx_profiler_stop()` returns the report key so that you will be able to store it somewhere, for instance among other information related to the profiled span. With the report key you can build the analysis screen URL which ends with this pattern `/?SPX_UI_URI=/report.html\u0026key=\u003creport key\u003e`.  \n- in CLI context, when automatic start is disabled, no signal handlers (i.e. on SIGINT/SIGTERM) are registered by SPX.\n\n\n#### Add custom metadata to the current full report\n\nWhen profiling with _full_ report as output, it could be handy to add custom metadata to the current report so that you will be able to easily retrieve it or differentiate it from other similar reports.\n\nThis is especially true for the long-living process use case which otherwise would not allow to differentiate a report from other ones of the same process.\n\nTo do that SPX exposes the `spx_profiler_full_report_set_custom_metadata_str(string $customMetadataStr): void` function.\n\nAs you may have notificed, this function accepts a string as custom metadata, for the sake of flexibility and simplicity on SPX side. It is up to you to encode any structured data to a string, for instance using JSON format.\n\nThe metadata string is limited to 4KB, which is large enough for most use cases. If you pass a string exceeding this limit it will be discarded and a notice log will be emitted.\n\nThis string will be stored among other current report's metadata and you will retrieve it in the report list on web UI side.\n\n`spx_profiler_full_report_set_custom_metadata_str()` can be called at any moment as long as the profiler is already started and not finished yet, which means:\n- at any moment during the script execution when automatic start is enabled (default mode).\n- at any moment after the call of `spx_profiler_start()` and before the call of `spx_profiler_stop()` when automatic start is disabled.\n\nHere is an example:\n\n```php\n\u003c?php\n\nwhile ($task = get_next_ready_task()) {\n  spx_profiler_start();\n\n  spx_profiler_full_report_set_custom_metadata_str(json_encode(\n    [\n      'taskId' =\u003e $task-\u003egetId(),\n    ]\n  ));\n\n  try {\n    $task-\u003eprocess();\n  } finally {\n    spx_profiler_stop();\n  }\n}\n\n```\n\n\n## Advanced usage\n\n### Configuration\n\n| Name                  | Default  | Changeable  | Description  |\n| --------------------- | -------- | ----------- | ------------ |\n| _spx.data_dir_     | `/tmp/spx` | _PHP_INI_SYSTEM_ | The directory where profiling reports will be stored. You may change it to point to a shared file system for example in case of multi-server architecture.  |\n| _spx.http_enabled_      | `0`  | _PHP_INI_SYSTEM_ | Whether to enable web UI and HTTP request profiling. |\n| _spx.http_key_          |  | _PHP_INI_SYSTEM_ | The secret key used for authentication (see [security concern](#security-concern) for more details). You can use the following command to generate a 16 bytes random key as an hex string: `openssl rand -hex 16`. |\n| _spx.http_ip_var_       | `REMOTE_ADDR` | _PHP_INI_SYSTEM_ | The `$_SERVER` key holding the client IP address used for authentication (see [security concern](#security-concern) for more details). Overriding the default value is required when your application is behind a reverse proxy. |\n| _spx.http_trusted_proxies_       | `127.0.0.1` | _PHP_INI_SYSTEM_ | The trusted proxy list as a comma separated list of IP addresses\u003cb\u003e*\u003c/b\u003e. This setting is ignored when `spx.http_ip_var`'s value is `REMOTE_ADDR`. |\n| _spx.http_ip_whitelist_ |  | _PHP_INI_SYSTEM_ | The IP address white list used for authentication as a comma separated list of IP addresses\u003cb\u003e*\u003c/b\u003e. |\n| _spx.http_ui_assets_dir_ | `/usr/local/share/misc/php-spx/assets/web-ui` | _PHP_INI_SYSTEM_ | The directory where the [web UI](#web-ui) files are installed. In most cases you do not have to change it. |\n| _spx.http_profiling_enabled_ | _NULL_ | _PHP_INI_SYSTEM_ | The INI level counterpart of the `SPX_ENABLED` parameter, for HTTP requests only. See [here for more details](#available-parameters). |\n| _spx.http_profiling_auto_start_ | _NULL_ | _PHP_INI_SYSTEM_ | The INI level counterpart of the `SPX_AUTO_START` parameter, for HTTP requests only. See [here for more details](#available-parameters). |\n| _spx.http_profiling_builtins_ | _NULL_ | _PHP_INI_SYSTEM_ | The INI level counterpart of the `SPX_BUILTINS` parameter, for HTTP requests only. See [here for more details](#available-parameters). |\n| _spx.http_profiling_sampling_period_ | _NULL_ | _PHP_INI_SYSTEM_ | The INI level counterpart of the `SPX_SAMPLING_PERIOD` parameter, for HTTP requests only. See [here for more details](#available-parameters). |\n| _spx.http_profiling_depth_ | _NULL_ | _PHP_INI_SYSTEM_ | The INI level counterpart of the `SPX_DEPTH` parameter, for HTTP requests only. See [here for more details](#available-parameters). |\n| _spx.http_profiling_metrics_ | _NULL_ | _PHP_INI_SYSTEM_ | The INI level counterpart of the `SPX_METRICS` parameter, for HTTP requests only. See [here for more details](#available-parameters). |\n\n_\\*: `*` (match all) and subnet masks (e.g. `192.168.1.0/24`) are supported._\n\n#### Private environment\n\nFor your local \u0026 private development environment, since there is no need for authentication, you can use this configuration:\n\n```\nspx.http_enabled=1\nspx.http_key=\"dev\"\nspx.http_ip_whitelist=\"127.0.0.1\"\n```\n\nAnd then access to the web UI at `http(s)://\u003cyour application host\u003e/?SPX_KEY=dev\u0026SPX_UI_URI=/`.\n\n### Available metrics\n\nHere is the list of available metrics to collect. By default only _Wall time_ and _Zend Engine memory usage_ are collected.\n\n| Key (command line) | Name | Description |\n| ---- | ---------------- | ------ |\n| _wt_ | Wall time | The absolute elapsed time. |\n| _ct_ | CPU time | The time spent while running on CPU. |\n| _it_ | Idle time | The time spent off-CPU, that means waiting for CPU, I/O completion, a lock acquisition... or explicitly sleeping. |\n| _zm_ | Zend Engine memory usage | Equivalent to `memory_get_usage(false)`. |\n| _zmac_ | Zend Engine allocation count | Number of memory allocations (i.e. allocated blocks) performed. |\n| _zmab_ | Zend Engine allocated bytes\u003cb\u003e*\u003c/b\u003e | Number of allocated bytes. |\n| _zmfc_ | Zend Engine free count | Number of memory releases (i.e. freed blocks) performed. |\n| _zmfb_ | Zend Engine freed bytes\u003cb\u003e*\u003c/b\u003e | Number of freed bytes. |\n| _zgr_ | Zend Engine GC run count | Number of times the GC (cycle collector) have been triggered (either manually or automatically). |\n| _zgb_ | Zend Engine GC root buffer length | Root buffer length, see explanation [here](http://php.net/manual/en/features.gc.collecting-cycles.php). It could be helpful to track pressure on garbage collector. |\n| _zgc_ | Zend Engine GC collected cycle count | Total number of collected cycles through all GC runs. |\n| _zif_ | Zend Engine included file count | Number of included files. |\n| _zil_ | Zend Engine included line count | Number of included lines. |\n| _zuc_ | Zend Engine user class count | Number of userland classes. |\n| _zuf_ | Zend Engine user function count | Number of userland functions (including userland class/instance methods). |\n| _zuo_ | Zend Engine user opcode count | Number of included userland opcodes (sum of all userland file/function/method opcodes). |\n| _zo_ | Zend Engine object count | Number of objects currently held by user code. |\n| _ze_ | Zend Engine error count | Number of raised PHP errors. |\n| _mor_ | Process's own RSS\u003cb\u003e\\*\\*\u003c/b\u003e | The part of the process's memory held in RAM. The shared (with other processes) memory blocks are not taken into account. This metric can be useful to highlight a memory leak within a PHP extension or deeper (e.g. a third-party C library). |\n| _io_ | I/O (reads + writes)**\\*\\*** | Bytes read or written while performing I/O. |\n| _ior_ | I/O (reads)**\\*\\*** | Bytes read while performing I/O. |\n| _iow_ | I/O (writes)**\\*\\*** | Bytes written while performing I/O. |\n\n_\\*: Allocated and freed byte counts will not be collected if you use a custom allocator or if you force the libc one through the `USE_ZEND_ALLOC` environment variable set to `0`._\n\n_\\*\\*: RSS \u0026 I/O metrics are not supported on macOS and FreeBSD. On GNU/Linux you should [read this if you use PHP-FPM](#linux-php-fpm--io-stats)._\n\n### Command line script\n\n#### Available report types\n\nContrary to web request profiling which only support _full_ report type (the one exploitable by the web UI), command line script profiling supports several types of report.\nHere is the list below:\n\n| Key  | Name  | Description  |\n| ---- | ----- | ------------ |\n| _fp_ | Flat profile | The flat profile provided by SPX. It is the **default report type** and is directly printed on STDERR. |\n| _full_ | Full report | This is the report type for web UI. Reports will be stored in SPX data directory and thus will be available for analysis on web UI side. |\n| _trace_ | Trace file | A custom format (human readable text) trace file. |\n\n#### Available parameters\n\n| Name  | Default  | Description  |\n| ----- | -------- | ------------ |\n| _SPX_ENABLED_ | `0` | Whether to enable SPX profiler (i.e. triggering profiling). When disabled there is no performance impact on your application (except for ZTS PHP where a disabled SPX still adds a little overhead). |\n| _SPX_AUTO_START_ | `1` | Whether to enable SPX profiler's automatic start. When automatic start is disabled, you have to start \u0026 stop profiling on your own at runtime via the `spx_profiler_start()` \u0026 `spx_profiler_stop()` functions. [See here](#handle-long-living--daemon-processes) for more details. |\n| _SPX_BUILTINS_ | `0` | Whether to profile internal functions, script compilations, GC runs and request shutdown. |\n| _SPX_DEPTH_ | `0` | The stack depth at which profiling must stop (i.e. aggregate measures of deeper calls). 0 (default value) means unlimited. |\n| _SPX_SAMPLING_PERIOD_ | `0` | Whether to collect data for the current call stack at regular intervals according to the specified sampling period (`0` means no sampling). The result will usually be less accurate but in some cases it could be far more accurate by not over-evaluating small functions called many times. It is recommended to try sampling (with different periods) if you want to accurately find a time bottleneck. When profiling a long running \u0026 CPU intensive script, this option will allow you to contain report size and thus keeping it small enough to be exploitable by the [web UI](#web-ui). See [here](#performance-report-size--sampling) for more details. |\n| _SPX_METRICS_ | `wt,zm` | Comma separated list of [available metric keys](#available-metrics) to collect. All report types take advantage of multi-metric profiling. |\n| _SPX_REPORT_ | `fp` | Selected [report key](#available-report-types). |\n| _SPX_FP_FOCUS_ | `wt` | [Metric key](#available-metrics) for flat profile sort. |\n| _SPX_FP_INC_ | `0` | Whether to sort functions by inclusive value instead of exclusive value in flat profile. |\n| _SPX_FP_REL_ | `0` | Whether to display metric values as relative (i.e. percentage) in flat profile. |\n| _SPX_FP_LIMIT_ | `10` | The flat profile size (i.e. top N shown functions). |\n| _SPX_FP_LIVE_ | `0` | Whether to enable flat profile live refresh. Since it plays with cursor position through ANSI escape sequences, it uses STDOUT as output, replacing script output (both STDOUT \u0026 STDERR). |\n| _SPX_FP_COLOR_ | `1` | Whether to enable flat profile color mode. |\n| _SPX_TRACE_SAFE_ | `0` | The trace file is by default written in a way to enforce accuracy, but in case of process crash (e.g. segfault) some logs could be lost. If you want to enforce durability (e.g. to find the last event before a crash) you just have to set this parameter to 1. |\n| _SPX_TRACE_FILE_ |  | Custom trace file name. If not specified it will be generated in `/tmp` and displayed on STDERR at the end of the script. |\n\n#### Setting parameters\n\nWell, as you might already noticed in corresponding [basic usage example](#command-line-script), setting a SPX parameter for a command line script simply means setting an environment variable with the same name.\n\n### Web UI\n\n#### Supported browsers\n\nSince the web UI uses advanced JavaScript features, only the following browsers are known to be supported:\n- most recent version of any Chromium-based browser.\n- most recent version of Firefox.\n\n#### Control panel \u0026 report list\n\nThis is the home page of the web UI, divided into 2 parts:\n- the control panel for setting the profiling setup for your current browser session.\n- the profile report list as a sortable table. A click on a row allows to go to the [analysis screen](#analysis-screen) for the corresponding report.\n\n#### Analysis screen\n\n[Click here for a live demo of the analysis screen](https://noisebynorthwest.github.io/php-spx/demo/report.html?key=spx-full-20180603_211110-dev-3540-294703905)\n\n![Showcase](https://github.com/NoiseByNorthwest/NoiseByNorthwest.github.io/blob/d8a90827d6eb256f49d580de448b6b6fad4119ac/php-spx/doc/as.th.png)\n\n##### Performance, report size \u0026 sampling\n\nThe analysis screen can nicely handle profile reports with up to several (5+) millions of recorded function calls with Chromium on my i5 @ 3.3GHz / 8GB desktop.\nIn case you want to profile a long running, CPU intensive, script which tends to generate giant reports, you can enable sampling mode with the suitable sampling period.\nSee _SPX_SAMPLING_PERIOD_ [parameter](#available-parameters) for command line script.\n\n##### Metric selector\n\nThis is simply a combo box for selecting the currently analyzed metric.\n\n![Showcase](https://github.com/NoiseByNorthwest/NoiseByNorthwest.github.io/blob/d8a90827d6eb256f49d580de448b6b6fad4119ac/php-spx/doc/as-ms.png)\n\n##### Color scheme selector\n\nBy default, function related blocks in the visualizations are colored according to their cost, with a color scale displayed at the top right of the screen.\n\nYou can also define a custom color scheme by clicking on the color scheme mode link, displayed at the top of the screen just after the metric selector.\nA drop-down window will then appear and allow you to switch between `default` and `category` mode and define (add/edit/delete) your categories (color, name, pattern list) for the `category` mode (see the screenshot below).\n\n![Showcase](https://github.com/NoiseByNorthwest/NoiseByNorthwest.github.io/blob/d8a90827d6eb256f49d580de448b6b6fad4119ac/php-spx/doc/as-csm.png)\n\n##### Timeline overview\n\nThis visualization is the timeline overview of all called functions.\nYou can change the selected time range by, represented by a transparent green rectangle, by simply dragging it horizontally.\n\nExcept for wall time, the current metric is also plotted (current value over time) on a foreground layer.\n\nSupported controls:\n- horizontal left click drag: shift the selected time range\n- resize click on selected time range rectangle: shift one of the selected time range boundary\n\n![Showcase](https://github.com/NoiseByNorthwest/NoiseByNorthwest.github.io/blob/d8a90827d6eb256f49d580de448b6b6fad4119ac/php-spx/doc/as-ov.png)\n\n##### Timeline focus\n\nThis visualization is an interactive timeline which is able to control and keep focus on the selected time range.\n\nSupported controls:\n- left click drag: time range shift (horizontal) or depth range shift (vertical)\n- middle click vertical drag: time range zoom in/out\n- mouse wheel: time range zoom in/out\n- hovering a function call to show more details\n- double click on a function call: set the current time range as the one of the selected function call\n\nExcept for wall time, the current metric is also plotted (current value over time) on a foreground layer.\n\n![Showcase](https://github.com/NoiseByNorthwest/NoiseByNorthwest.github.io/blob/d8a90827d6eb256f49d580de448b6b6fad4119ac/php-spx/doc/as-tl.png)\n\n##### Flat profile\n\nThis visualization is the flat profile for the selected time range and the selected metric, displayed as a sortable table.\n\nThe `Inc.` and `Exc.` sub-columns respectively correspond to:\n- the inclusive resource consumption of the function, including its called functions consumption\n- the exclusive resource consumption of the function, excluding its called functions consumption\n\n![Showcase](https://github.com/NoiseByNorthwest/NoiseByNorthwest.github.io/blob/d8a90827d6eb256f49d580de448b6b6fad4119ac/php-spx/doc/as-fp.png)\n\n##### Flame Graph\n\nThis visualization, designed by [Brendan Gregg](http://www.brendangregg.com/flamegraphs.html), allows to quickly find the hot code path for the selected time range and the selected metric.\nMetrics corresponding to releasable resources (memory, objects in use...) are not supported by this visualization.\n\n![Showcase](https://github.com/NoiseByNorthwest/NoiseByNorthwest.github.io/blob/d8a90827d6eb256f49d580de448b6b6fad4119ac/php-spx/doc/as-fg.png)\n\n\n##### Function highlighting\n\nYou can highlight a function by clicking on one of its spans within the timeline or Flamegraph widgets or its name within the flat profile widget.\n\n![Showcase](https://github.com/NoiseByNorthwest/NoiseByNorthwest.github.io/blob/47d8f8d93fad1e6659c46c47e5aa8f82822454a9/php-spx/doc/as-fh.png)\n\n\n## Security concern\n\n_The lack of review / feedback about this concern is the main reason **SPX cannot yet be considered as production ready**._\n\nSPX allows you to profile web request as well as command line scripts, and also to list and analyze profile reports through its embedded web UI.\nThis is why there is a huge security risk, since an attacker could:\n - access to web UI and get sensible information about your application.\n - to a lesser extent, make a DoS attack against your application with a costly profiling setup.\n\nSo, unless access to your application is already restricted at lower layer (i.e. before your application is hit, not by the application / PHP framework itself), a client triggering profiling or accessing to the web UI must be authenticated.\n\nSPX provides two-factor authentication with these 2 mandatory locks:\n* IP address white list (exact string representation matching).\n* Fixed secret random key (generated on your own) provided via a request header, cookie or query string parameter.\n\nThus a client can profile your application via a web request only if **its IP address is white listed and its provided key is valid**.\n\n## Notes on accuracy\n\nIn tracing mode (default), SPX is subject to accuracy issues for time related metrics when the measured function execution time is:\n- close or lower than the timer precision\n- close or lower than SPX's own per function overhead\n\nThe first issue is mitigated by using the highest resolution timer provided by the platform. On Linux, FreeBSD \u0026 recent macOS versions the timer resolution is 1ns; on macOS before 10.12/Sierra, the timer resolution is only 1us.\n\nThe second issue is mitigated by taking into account SPX's time (wall / cpu) overhead by subtracting it to measured function execution time. This is done by evaluating SPX constant per function overhead before starting profiling the script.\n\nHowever, whatever the platform, if you want to maximize accuracy to find a time bottleneck, you should also:\n- avoid profiling internal functions.\n- avoid collecting additional metrics.\n- try sampling mode with different sampling periods.\n- try to play with maximum depth parameter to stop profiling at a given depth.\n\n## Stubs\n\nStubs for SPX functions to be used with [Intelephense](https://www.npmjs.com/package/intelephense)\n\n    composer require --dev 8ctopus/php-spx-stubs\n\n## Credits\n\nI have found lot of inspiration and hints reading:\n - [XHProf](https://github.com/phacility/xhprof)\n - [Xdebug](https://github.com/xdebug/xdebug)\n - [PHP](https://github.com/php/php-src)\n\n## License\n\n**SPX** is open source software licensed under the GNU General Public License (GPL-3).\nSee the [LICENSE][:link-license:] file for more information.\n\n\u003c!-- All external links should be here to avoid duplication and long lines with links --\u003e\n[:badge-ci:]:           https://github.com/NoiseByNorthwest/php-spx/actions/workflows/main.yml/badge.svg\n[:link-ci:]:            https://github.com/NoiseByNorthwest/php-spx/actions/workflows/main.yml\n\n[:badge-php-versions:]: https://img.shields.io/badge/php-5.4--8.4-blue.svg\n[:badge-supported-platforms:]: https://img.shields.io/badge/platform-GNU/Linux%20|%20macOS%20|%20FreeBSD%20-yellow\n[:badge-supported-arch:]: https://img.shields.io/badge/architecture-x86--64%20|%20ARM64%20-silver\n\n[:badge-license:]:      https://img.shields.io/github/license/NoiseByNorthwest/php-spx\n[:link-license:]:       https://github.com/NoiseByNorthwest/php-spx/blob/master/LICENSE\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FNoiseByNorthwest%2Fphp-spx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FNoiseByNorthwest%2Fphp-spx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FNoiseByNorthwest%2Fphp-spx/lists"}