Download the PHP package makinacorpus/profiling without Composer
On this page you can find all versions of the php package makinacorpus/profiling. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download makinacorpus/profiling
More information about makinacorpus/profiling
Files in makinacorpus/profiling
Package profiling
Short Description Lightweight and flexible profiling toolbox, using the high resolution timer.
License GPL-2.0-or-later
Informations about the package profiling
Profiling toolbox
Profiling and metrics toolbox.
Contains many features:
-
Timer API, very much alike
symfony/stopwatch
with time and memory consumption measurement. Timers can be started within a timer tree which allows to have a multi-dimensional view of timers. -
Prometheus compatible various metrics collection, counters, gauges, summaries and histograms. Those metrics can be exposed via a Promotheus compatible scrapping endpoint.
- Integration with
symfony/stopwatch
for Symfony web profiler when in development mode.
Timers uses the monotonic high resolution timer if available using the PHP
\hrtime()
function for timings, which yields more precision and is resilient
to system clock changes in opposition to \microtime()
Using \hrtime()
function makes this API being suitable for running discretly in production.
Setup
Installation
Simply run:
For registering the Symfony bundle, add to your config/bundles.php
:
Enable it by setting this environment variable:
Enable prometheus support can be done as well:
Then copy the src/Bridge/Symfony/Resources/packages/profiling.yaml
in this
package in the config/packages/
directory. You may read it and modify
following your needs. All configuration options are documented within the
sample configuration file itself.
Storage configuration
Default storage is a PostgreSQL database implementation that uses
makinacorpus/query-builder
for writing SQL queries.
It can create automatically the missing tables at runtime, although this
unperformant and disabled per default. In order to allow automatic table
creation, you can set the PROFILING_PROMETHEUS_SCHEMA_AUTOCREATE=1
environment variable.
Recommended method is to run the profiling:prometheus:create-schema
console
command at least once:
Usage
Important notes:
-
For each incomming request, the must be one and only one
MakinaCorpus\Profiling\Profiler
instance. - By "incomming request", we mean a single workload, which in the context of a message bus consumer can be a single message processing.
Timers
Basic usage
Here is a code sample:
Timer advanced usage
There are many methods on the MakinaCorpus\Profiling\Timer
interface, all are documented.
Timer trace handlers
Timer trace handlers are components that listen to all timers being emited, then can log information. A few handlers are provided by default:
-
MakinaCorpus\Profiling\Timer\Handler\SentryHandler
(sentry
) can send your timers to a Sentry instance. -
MakinaCorpus\Profiling\Timer\Handler\StoreHandler
(store
) can send your timers to a local storage implementation. Only one implementation exist as of now, which sends data to an SQL database table. -
MakinaCorpus\Profiling\Timer\Handler\StreamHandler
(file
) sends your timers into a log file, each timer gets a line. MakinaCorpus\Profiling\Timer\Handler\SymfonyStopwatchHandler
(stopwatch
) sends the timers into thesymfony/stopwatch
component. This is useful when the web profiler debug toolbar is installed, in development mode.
Handlers can be configured to accept timers from all channels, some channels, or all channels but some channels.
See the example configuration file for more information about handler configuration.
Prometheus metrics
Setup
First, enable it using an environment variable:
Then compute a random access token, with any method of your choice, then set it into your environments variables:
In order to setup the prometheus HTTP endpoint, add into config/routes.yaml
:
Then for fetching metrics, simply hit the following URL:
Also, please note that if you configured some firewalls, you probably need
to put the ^/prometheus/
path into a non-secured firewall.
Default configuration simply works, aside for the driver that needs to
be configured. Default is in_memory
which means it simply stores nothing.
Define your own metrics
Each sample must be defined in the schema
configuration section. If a sample
is not defined in this file, then it will simply be a no-op if you attempt
collecting it.
Edit your config/packages/profiling.yaml
file:
Then, at the point in code where you need to profile, inject the
MakinaCorpus\Profiling\Profiler
service and use it.
Gauge
Use the gauge()
method:
Counter
Use the counter()
method:
Summary
Use the summary
method in conjonction with a timer:
Of course, you could measure something else than a duration, any value which yield some meanings to you can be added to summaries.
Important note: histogram are much more performant to use than summaries in both output rendering and storage. Avoid summaries when you know in advance expected values span.
Histogram
Use the histogram
method in conjonction with a timer:
Of course, you could measure something else than a duration, any value which yield some meanings to you can be added to summaries.
Important note: histogram are much more performant to use than summaries in both output rendering and storage. Always prefer histogram over summary when when you know in advance expected values span.
Exposed metrics
HTTP requests
NAMESPACE_http_exception_total
(counter
),{action: ROUTE, method: HTTP_METHOD, type: EXCEPTION_CLASS}
NAMESPACE_http_request_duration_msec
(summary
),{action: ROUTE, method: HTTP_METHOD, status: HTTP_STATUS_CODE}
NAMESPACE_http_request_total
(counter
),{action: ROUTE, method: HTTP_METHOD}
NAMESPACE_http_response_total
(counter
),{action: ROUTE, method: HTTP_METHOD, status: HTTP_STATUS_CODE}
NAMESPACE_instance_name
(gauge
),{instance_name: HOSTNAME}
Console commands
NAMESPACE_console_command_total
(counter
),{action: COMMAND_NAME}
NAMESPACE_console_duration_msec
(summary
),{action: COMMAND_NAME, method: "command", status: EXIT_STATUS_CODE}
NAMESPACE_console_exception_total
(counter
),{action: COMMAND_NAME, method: "command", type: EXCEPTION_CLASS}
NAMESPACE_console_status_total
(counter
),{action: COMMAND_NAME, method: "command", status: EXIT_STATUS_CODE}
Messenger
Not implemented yet. It will probably be:
NAMESPACE_message_consumed_total
(counter
),{action: MESSAGE_CLASS, method: "message"}
NAMESPACE_message_duration_msec
(summary
),{action: MESSAGE_CLASS, method: "message"}
NAMESPACE_message_exception_total
(counter
),{action: MESSAGE_CLASS, method: "message", type: EXCEPTION_CLASS}
Monolog
Not implemented yet. It will probably be:
NAMESPACE_monolog_message_total
(counter
),{action: ROUTE|COMMAND_NAME|MESSAGE_CLASS, method: "message"|"command"|HTTP_METHOD, severity: MONOLOG_LEVEL, channel: MONOLOG_CHANNEL}
System information
If you don't have system monitoring, this bundle can collect a few system information samples.
Please see complete documentation in the
src/Bridge/Symfony/Resources/config/packages/profiling.yaml
file.
CPU load average samples:
NAMESPACE_sys_load_avg
(gauge
),{span: INT}
- value as a fractional number, for thespan
last minutes.
Memory usage samples:
NAMESPACE_sys_mem_total
(gauge
) - value in bytes.NAMESPACE_sys_mem_free
(gauge
) - value in bytes.NAMESPACE_sys_mem_used
(gauge
) - value in bytes.NAMESPACE_sys_mem_available
(gauge
) - value in bytes.NAMESPACE_sys_mem_buffers
(gauge
) - value in bytes.NAMESPACE_sys_mem_cached
(gauge
) - value in bytes.NAMESPACE_sys_mem_swap_total
(gauge
) - value in bytes.NAMESPACE_sys_mem_swap_free
(gauge
) - value in bytes.NAMESPACE_sys_mem_swap_used
(gauge
) - value in bytes.
Disk usage samples:
NAMESPACE_sys_disk_total
(gauge
),{name: NAME}
- value in bytes.NAMESPACE_sys_disk_free
(gauge
),{name: NAME}
- value in bytes.NAMESPACE_sys_disk_used
(gauge
),{name: NAME}
- value in bytes.
Per default, if you don't configure any disk, the current project directory
mount point is targeted, and NAME
is app
.
Warning: because the probes are only collecting data when a request happen
you can chose to run the profiling:prometheus:sys-info
console command to run
as a cron job for collecting system information regularily.
Inject profiler into your services
When working in a Symfony project, the recommended way for registering the profiler onto a service is the following:
By using the \MakinaCorpus\Profiling\ProfilerAwareTrait
you allow your code to be resilient in case of misinitialisation:
-
If the autoconfiguration failed, it will create a default null instance doing nothing, which will have a near-to-zero performance impact.
- If the bundle is deactivated, it will create a default null instance doing nothing, which will have a near-to-zero performance impact.
You can then use the profiler:
And that's pretty much it.
Memory usage
The timer class also measure memory usage, but beware that those results will be biased by this API itself consuming memory.
CLI killswitch
If you are working in CLI, and with to disable profiling for long running tasks
or migration batches, simply add the PROFILING_ENABLE=0
environment variable
in your command line.
This will not completely disable the bundle, this is a soft-disable and will only prevent profiliers from being created during this runtime, for example:
Roadmap
- Allow configuration of formatter in stream handler.
- Implement Redis storage for prometheus metrics.
- Merge Metrics and Profiler interfaces/classes.
- Plug timers in prometheus summary and histogram.
- Prometheus doctrine SQL query count metrics.
- Prometheus messenger metrics.
- Prometheus monolog metrics.
- Prometheus response size metrics.
- Prometheus unexpected metrics log into monolog.
- Purge console command with date.
- View console command.
- Write documentation site.