-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit fccfff1
Showing
27 changed files
with
1,722 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.idea | ||
vendor | ||
composer.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
before_commands: | ||
- "composer install --no-dev --prefer-source" | ||
|
||
tools: | ||
external_code_coverage: | ||
timeout: 1200 | ||
php_code_coverage: | ||
enabled: true | ||
php_code_sniffer: | ||
enabled: true | ||
config: | ||
standard: PSR2 | ||
filter: | ||
paths: ["src/*"] | ||
php_cpd: | ||
enabled: true | ||
excluded_dirs: ["ide-stubs", "tests", 'vendor'] | ||
php_cs_fixer: | ||
enabled: true | ||
config: | ||
level: all | ||
filter: | ||
paths: ["src/*"] | ||
php_loc: | ||
enabled: true | ||
excluded_dirs: ["ide-stubs", "tests", 'vendor'] | ||
php_pdepend: | ||
enabled: true | ||
excluded_dirs: ["ide-stubs", "tests", 'vendor'] | ||
php_analyzer: | ||
enabled: true | ||
filter: | ||
paths: ["src/*"] | ||
sensiolabs_security_checker: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
language: php | ||
php: | ||
- 5.4 | ||
- 5.5 | ||
- 5.6 | ||
- 7.0 | ||
- 7.1 | ||
- 7.2 | ||
- hhvm | ||
|
||
before_script: composer install | ||
script: vendor/bin/phpunit --verbose --colors --coverage-clover=coverage.xml | ||
|
||
after_success: | ||
- bash <(curl -s https://codecov.io/bash) | ||
- wget https://scrutinizer-ci.com/ocular.phar | ||
- php ocular.phar code-coverage:upload --format=php-clover coverage.xml | ||
|
||
notifications: | ||
email: "timur.shagiakhmetov@corp.badoo.com" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
FROM php:5.4 | ||
MAINTAINER Timur Shagiakhmetov <timur.shagiakhmetov@corp.badoo.com> | ||
|
||
COPY . /app | ||
WORKDIR /app | ||
|
||
RUN apt-get update && apt-get install -y --no-install-recommends git unzip \ | ||
&& curl --silent --show-error https://getcomposer.org/installer | php \ | ||
&& ./composer.phar -q install \ | ||
&& echo 'date.timezone = Europe/London' >> /usr/local/etc/php/php.ini \ | ||
&& pecl install xhprof-0.9.4 && docker-php-ext-enable xhprof # xhprof profiler installation | ||
|
||
CMD ["php", "/app/bin/example.php"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
FROM hhvm/hhvm:latest | ||
MAINTAINER Timur Shagiakhmetov <timur.shagiakhmetov@corp.badoo.com> | ||
|
||
COPY . /app | ||
WORKDIR /app | ||
|
||
RUN curl -sS https://getcomposer.org/installer | hhvm --php \ | ||
&& hhvm ./composer.phar -q install | ||
|
||
CMD ["hhvm", "/app/bin/example.php"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
FROM php:7.0 | ||
MAINTAINER Timur Shagiakhmetov <timur.shagiakhmetov@corp.badoo.com> | ||
|
||
COPY . /app | ||
WORKDIR /app | ||
|
||
RUN apt-get update && apt-get install -y --no-install-recommends git unzip \ | ||
&& curl --silent --show-error https://getcomposer.org/installer | php \ | ||
&& ./composer.phar -q install | ||
|
||
# tideways profiler installation | ||
RUN git clone https://github.com/tideways/php-profiler-extension.git /tmp/xhptof | ||
WORKDIR /tmp/xhptof | ||
RUN phpize && ./configure && make && make install \ | ||
&& echo "extension=tideways_xhprof.so" >> /usr/local/etc/php/conf.d/20-xhprof.ini \ | ||
&& echo "xhprof.output_dir='/usr/src/myapp/xhprof'" >> /usr/local/etc/php/conf.d/20-xhprof.ini | ||
|
||
CMD ["php", "/app/bin/example.php"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
FROM php:5.4 | ||
MAINTAINER Timur Shagiakhmetov <timur.shagiakhmetov@corp.badoo.com> | ||
|
||
COPY . /app | ||
WORKDIR /app | ||
|
||
RUN apt-get update && apt-get install -y --no-install-recommends git unzip \ | ||
&& curl --silent --show-error https://getcomposer.org/installer | php \ | ||
&& ./composer.phar -q install \ | ||
&& echo 'date.timezone = Europe/London' >> /usr/local/etc/php/php.ini | ||
|
||
# uprofiler installation | ||
RUN git clone https://github.com/FriendsOfPHP/uprofiler.git /tmp/uprofiler | ||
WORKDIR /tmp/uprofiler/extension | ||
RUN phpize && ./configure && make && make install \ | ||
&& echo "extension=uprofiler.so" >> /usr/local/etc/php/conf.d/20-uprofiler.ini \ | ||
&& echo "uprofiler.output_dir='/usr/src/myapp/uprofiler'" >> /usr/local/etc/php/conf.d/20-uprofiler.ini | ||
|
||
CMD ["php", "/app/bin/example.php"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
The MIT License (MIT) | ||
|
||
Copyright (c) 2016 Badoo Development | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
Live Profiler | ||
================ | ||
|
||
 | ||
|
||
Live Profiler is a system-wide performance monitoring system in use at Badoo that is built on top of [XHProf](http://pecl.php.net/package/xhprof) or its forks ([Uprofiler](https://github.com/FriendsOfPHP/uprofiler) or [Tideways](https://github.com/tideways/php-profiler-extension)). | ||
Live Profiler continually gathers function-level profiler data from production tier by running a sample of page requests under XHProf. | ||
|
||
[Live profiler UI](https://github.com/badoo/liveprof-ui) then aggregates the profile data corresponding to individual requests by various dimensions such a time, page type, and can help answer a variety of questions such as: | ||
What is the function-level profile for a specific page? | ||
How expensive is function "foo" across all pages, or on a specific page? | ||
What functions regressed most in the last day/week/month? | ||
What is the historical trend for execution time of a page/function? and so on. | ||
|
||
System Requirements | ||
=================== | ||
|
||
* PHP version 5.4 or later / hhvm version 3.25.0 or later | ||
* One of [XHProf](http://pecl.php.net/package/xhprof), | ||
[Uprofiler](https://github.com/FriendsOfPHP/uprofiler) or | ||
[Tideways](https://github.com/tideways/php-profiler-extension) to actually profile the data. | ||
You can use other profiler which returns data in the follow format: | ||
```php | ||
$data = [ | ||
[ | ||
'parent_method==>child_method' => [ | ||
'param' => 'value' | ||
] | ||
] | ||
]; | ||
``` | ||
* Database extension to save profiling results | ||
|
||
Installation | ||
============ | ||
|
||
* You can install Live Profiler via [Composer](https://getcomposer.org/): | ||
|
||
```bash | ||
php composer.phar require badoo/liveprof | ||
``` | ||
|
||
* Prepare a database server. You can use any driver described [here](https://www.doctrine-project.org/projects/doctrine-dbal/en/2.8/reference/configuration.html#configuration) or implement the custom one | ||
* Run a script to configure database. This script creates "details" table | ||
|
||
```bash | ||
LIVE_PROFILER_CONNECTION_URL=mysql://db_user:db_password@db_mysql:3306/Profiler?charset=utf8 php vendor/badoo/liveprof/bin/install.php | ||
``` | ||
|
||
* Init a profiler before working code in the project entry point (usually public/index.php). | ||
|
||
You should add a profiler call before your code to start profiling with default parameters: | ||
```php | ||
<?php | ||
include 'vendor/autoload.php'; | ||
|
||
\Badoo\LiveProfiler\LiveProfiler::getInstance()->start(); | ||
// Code is here | ||
``` | ||
|
||
There is a full list of methods you can use to change options: | ||
```php | ||
<?php | ||
|
||
// Start profiling | ||
\Badoo\LiveProfiler\LiveProfiler::getInstance() | ||
->setConnectionString('mysql://db_user:db_password@db_mysql:3306/Profiler?charset=utf8') // optional, you can also set the connection url in the environment variable LIVE_PROFILER_CONNECTION_URL | ||
->setApp('Site1') // optional, current app name to use one profiler in several apps, "Default" by default | ||
->setLabel('users') // optional, the request name, by default the url path or script name in cli | ||
->setDivider(700) // optional, profiling starts for 1 of 700 requests with the same app and label, 1000 by default | ||
->setTotalDivider(7000) // optional, profiling starts for 1 of 7000 requests with forces label "All", 10000 by default | ||
->setLogger($Logger) // optional, a custom logger implemented \Psr\Log\LoggerInterface | ||
->setConnection($Connection) // optional, a custom instance of \Doctrine\DBAL\Connection if you can't use the connection url | ||
->setDataPacker($DatePacker) // optional, a class implemented \Badoo\LiveProfiler\DataPackerInterface to convert array into string | ||
->setStartCallback($profiler_start_callback) // optional, set it if you use custom profiler | ||
->setEndCallback($profiler_profiler_callback) // optional, set it if you use custom profiler | ||
->start(); | ||
``` | ||
|
||
If you want to change the Label during running (for instance, after you got some information in the router or controller) you can call: | ||
```php | ||
<?php | ||
|
||
$number = random_int(0, 100); | ||
$current_label = \Badoo\LiveProfiler\LiveProfiler::getInstance()->getLabel(); | ||
\Badoo\LiveProfiler\LiveProfiler::getInstance()->setLabel($current_label . $number); | ||
``` | ||
|
||
if you don't want to save profiling result you can reset it anytime: | ||
```php | ||
<?php | ||
|
||
\Badoo\LiveProfiler\LiveProfiler::getInstance()->reset(); | ||
``` | ||
|
||
After script ends it will call `\Badoo\LiveProfiler\LiveProfiler::getInstance()->end();` on shutdown, but you can call it explicitly after working code. | ||
|
||
Environment Variables | ||
===================== | ||
|
||
`LIVE_PROFILER_CONNECTION_URL`: [url](https://www.doctrine-project.org/projects/doctrine-dbal/en/2.8/reference/configuration.html#configuration) for the database connection | ||
|
||
Work flow | ||
========= | ||
|
||
Live profiler allows to run profiling with custom frequency (for instance 1 of 1000 requests) grouped by app name ('Default' by default) and custom label (by default it's the url path or script name). | ||
|
||
It's important to calculate **the request divider** properly to have enough data for aggregation. You should divide daily request count to have approximately 1 profile per minute. | ||
For instance, if you have 1M requests a day for the page /users the divider should be 1000000/(60*24) = 694, so divider = 700 is enough. | ||
|
||
Also you have to calculate **a total divider** for all request profiling. It's important to control the whole system health. It can be calculated the same way as a divider calculation for particularly request, | ||
but in this case you should use count of all daily requests. For instance, if you have 10M requests a day - total_divider=10000000/(60*24) = 6940, so total_divider = 7000 is enough. | ||
|
||
The profiler automatically detects which profiler extension you have (xhprof, uprofiler or tidyways). You have to set profiler callbacks if you use other profiler. | ||
|
||
You can run the test script in the docker container with **xhprof** extension and look at the example of the server configuration in Dockerfile: | ||
```bash | ||
docker build -t badoo/liveprof . | ||
docker run badoo/liveprof | ||
``` | ||
|
||
or you can build a docker container with **tideways** extension: | ||
```bash | ||
docker build -f DockerfileTidyWays -t badoo/liveprof . | ||
``` | ||
|
||
or **uprofiler** extension: | ||
```bash | ||
docker build -f DockerfileUprofiler -t badoo/liveprof . | ||
``` | ||
|
||
or latest hhvm with included **xhprof** extension: | ||
```bash | ||
docker build -f DockerfileHHVM -t badoo/liveprof . | ||
``` | ||
|
||
If your server has php version 7.0 or later it's better to use [Tideways](https://github.com/tideways/php-profiler-extension) as profiler. | ||
|
||
Steps to install tideways extension: | ||
```bash | ||
git clone https://github.com/tideways/php-profiler-extension.git | ||
cd php-profiler-extension | ||
phpize | ||
./configure | ||
make | ||
make install | ||
echo "extension=tideways_xhprof.so" >> /usr/local/etc/php/conf.d/20-tideways_xhprof.ini | ||
echo "xhprof.output_dir='/tmp/xhprof'" >> /usr/local/etc/php/conf.d/20-tideways_xhprof.ini | ||
``` | ||
|
||
Steps to install uprofiler: | ||
```bash | ||
git clone https://github.com/FriendsOfPHP/uprofiler.git | ||
cd uprofiler/extension/ | ||
phpize | ||
./configure | ||
make | ||
make install | ||
echo "extension=uprofiler.so" >> /usr/local/etc/php/conf.d/20-uprofiler.ini | ||
echo "uprofiler.output_dir='/tmp/uprofiler'" >> /usr/local/etc/php/conf.d/20-uprofiler.ini | ||
``` | ||
|
||
Tests | ||
===== | ||
|
||
Install Live Profiler with dev requirements: | ||
```bash | ||
php composer.phar require --dev badoo/liveprof | ||
``` | ||
|
||
In the project directory, run: | ||
```bash | ||
vendor/bin/phpunit | ||
``` | ||
|
||
License | ||
======= | ||
|
||
This project is licensed under the MIT open source license. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
<?php | ||
/** | ||
* Runs profiling test code | ||
* @maintainer Timur Shagiakhmetov <timur.shagiakhmetov@corp.badoo.com> | ||
*/ | ||
|
||
if (file_exists(__DIR__ . '/../vendor/autoload.php')) { | ||
require_once __DIR__ . '/../vendor/autoload.php'; | ||
} elseif (file_exists(__DIR__ . '/../../../../vendor/autoload.php')) { | ||
require_once __DIR__ . '/../../../../vendor/autoload.php'; | ||
} | ||
|
||
use Badoo\LiveProfiler\LiveProfiler; | ||
|
||
// Create source database in the memory | ||
$Profiler = new LiveProfiler('sqlite:///:memory:'); | ||
$Profiler->setDivider(1); | ||
$Profiler->createTable(); | ||
|
||
// Run this method before profiled code | ||
$Profiler->start(); | ||
|
||
// Start of profiled code | ||
testCode(1); | ||
// End of profiled code | ||
|
||
// Run this method after profiled code | ||
$profiling_result = $Profiler->end(); | ||
print_r($Profiler->getLastProfileData()); | ||
|
||
echo $profiling_result ? "Prof;ling successfully finished\n" : "Error in profiling\n"; | ||
|
||
/** | ||
* Test functions | ||
* @param int $level | ||
*/ | ||
function testCode($level = 2) | ||
{ | ||
getSlower($level); | ||
getFaster($level); | ||
} | ||
|
||
/** | ||
* @param int $level | ||
* @return float | ||
*/ | ||
function getSlower($level) | ||
{ | ||
$result = 0; | ||
for ($i = 0; $i < $level; $i++) { | ||
for ($j = 0; $j < 1000000; $j++) { | ||
$result = $j * (1000000 - $j); | ||
} | ||
} | ||
return $result; | ||
} | ||
|
||
/** | ||
* @param int $level | ||
* @return float | ||
*/ | ||
function getFaster($level) | ||
{ | ||
$result = 0; | ||
for ($i = 0; $i < (10 - $level); $i++) { | ||
for ($j = 0; $j < 1000000; $j++) { | ||
$result = $i * (1000000 - $i); | ||
} | ||
} | ||
return $result; | ||
} |
Oops, something went wrong.