Skip to content

Commit

Permalink
Added base configuration options
Browse files Browse the repository at this point in the history
  • Loading branch information
Petr Knap committed Oct 5, 2016
2 parents b9084ca + b9cc642 commit a3c0a62
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 49 deletions.
23 changes: 22 additions & 1 deletion README.md
Expand Up @@ -74,6 +74,20 @@ extensions:

If you wish to profile before the container is ready, call `Profiler::enable` manually.

#### Configuration

```neon
profiler:
profile:
createService: false # or true
bar:
primaryValue: effective # or absolute
show:
memoryUsageChart: true # or false
shortProfiles: true # or false
timeLines: true # or false
```

There is a live demo available - run `make demo` and [click here](http://127.0.0.1:8080/nette/).


Expand All @@ -84,7 +98,14 @@ Add panel `Netpromotion\Profiler\Adapter\TracyBarAdapter` to your bar via `Bar::
```php
tracy_wrap(function() {
/* your code goes here */
}, [new TracyBarAdapter()]);
}, [new TracyBarAdapter([
"primaryValue" => "effective", // or "absolute"
"show" => [
"memoryUsageChart" => true, // or false
"shortProfiles" => true, // or false
"timeLines" => true // or false
]
])]);
```

There is a live demo available - run `make demo` and [click here](http://127.0.0.1:8080/lumen/).
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Expand Up @@ -32,7 +32,7 @@
"nette/application": "^2.3",
"latte/latte": "^2.3",
"phpunit/phpunit": "^4.8",
"netpromotion/tracy-wrapper": "1.0.0-a1 as 1.0.0",
"netpromotion/tracy-wrapper": "^1.0",
"laravel/lumen-framework": "^5.0"
},
"autoload": {
Expand Down
4 changes: 4 additions & 0 deletions demo/nette/config/config.neon
@@ -1,6 +1,10 @@
extensions:
profiler: Netpromotion\Profiler\Extension\ProfilerNetteExtension

profiler:
profile:
createService: true

application:
scanDirs: false
mapping:
Expand Down
112 changes: 85 additions & 27 deletions src/Profiler/Adapter/TracyBarAdapter.php
Expand Up @@ -9,14 +9,42 @@

class TracyBarAdapter implements IBarPanel
{
const CONFIG_PRIMARY_VALUE = "primaryValue";
const CONFIG_PRIMARY_VALUE_ABSOLUTE = "absolute";
const CONFIG_PRIMARY_VALUE_EFFECTIVE = "effective";
const CONFIG_SHOW = "show";
const CONFIG_SHOW_MEMORY_USAGE_CHART = "memoryUsageChart";
const CONFIG_SHOW_SHORT_PROFILES = "shortProfiles";
const CONFIG_SHOW_TIME_LINES = "timeLines";

private $profilerService;

public function __construct()
private $config;

public function __construct(array $config = [])
{
$this->config = array_replace_recursive(TracyBarAdapter::getDefaultConfig(), $config);

/** @noinspection PhpInternalEntityUsedInspection */
$this->profilerService = ProfilerService::getInstance();
}

/**
* @internal
* @return array
*/
public static function getDefaultConfig()
{
return [
self::CONFIG_PRIMARY_VALUE => self::CONFIG_PRIMARY_VALUE_EFFECTIVE,
self::CONFIG_SHOW => [
self::CONFIG_SHOW_MEMORY_USAGE_CHART => true,
self::CONFIG_SHOW_SHORT_PROFILES => true,
self::CONFIG_SHOW_TIME_LINES => true
]
];
}

/**
* @inheritdoc
*/
Expand All @@ -40,9 +68,19 @@ public function getPanel()
{
$table = "<style>.tracy-addons-profiler-hidden{display:none}.tracy-addons-profiler-bar{display:inline-block;margin:0;height:0.8em;}</style>";
$table .= "<table>";
$table .= "<tr><td colspan='4' style='text-align: center'>" . $this->getMemoryChart() . "</td></tr>";
$table .= "<tr><th>Start</th><th>Finish</th><th>Time (absolute)</th><th>Memory change (absolute)</th></tr>";
if ($this->config[self::CONFIG_SHOW][self::CONFIG_SHOW_MEMORY_USAGE_CHART]) {
$table .= "<tr><td colspan='4' style='text-align: center'>" . $this->getMemoryChart() . "</td></tr>";
}
if ($this->config[self::CONFIG_PRIMARY_VALUE] == self::CONFIG_PRIMARY_VALUE_EFFECTIVE) {
$table .= "<tr><th>Start</th><th>Finish</th><th>Time (absolute)</th><th>Memory change (absolute)</th></tr>";
} else {
$table .= "<tr><th>Start</th><th>Finish</th><th>Time (effective)</th><th>Memory change (effective)</th></tr>";
}
$this->profilerService->iterateProfiles(function (Profile $profile) use (&$table) {
/** @noinspection PhpInternalEntityUsedInspection */
if (!$this->config[self::CONFIG_SHOW][self::CONFIG_SHOW_SHORT_PROFILES] && ($profile->meta[ProfilerService::TIME_LINE_ACTIVE] + $profile->meta[ProfilerService::TIME_LINE_INACTIVE]) < 1) {
return /* continue */;
}
if ($profile->meta[Profiler::START_LABEL] == $profile->meta[Profiler::FINISH_LABEL]) {
$labels = sprintf(
"<td colspan='2'>%s</td>",
Expand All @@ -56,28 +94,42 @@ public function getPanel()
$profile->meta[Profiler::FINISH_LABEL]
);
}
$table .= sprintf(
"<tr>%s<td>%d&nbsp;ms (%d&nbsp;ms)</td><td>%d&nbsp;kB (%d&nbsp;kB)</td></tr>",
$labels,
$profile->duration * 1000,
$profile->absoluteDuration * 1000,
$profile->memoryUsageChange / 1024,
$profile->absoluteMemoryUsageChange / 1024
);

/** @noinspection PhpInternalEntityUsedInspection */
$table .= sprintf(
"<tr class='tracy-addons-profiler-hidden'><td colspan='4'></td></tr><tr><td colspan='4'>" .
"<span class='tracy-addons-profiler-bar' style='width:%d%%;background-color:#cccccc;'></span>" .
"<span class='tracy-addons-profiler-bar' style='width:%d%%;background-color:#3987d4;'></span>" .
"<span class='tracy-addons-profiler-bar' style='width:%s%%;background-color:#6ba9e6;'></span>" .
"<span class='tracy-addons-profiler-bar' style='width:%s%%;background-color:#cccccc;'></span>" .
"</td></tr>",
$profile->meta[ProfilerService::TIME_LINE_BEFORE],
$profile->meta[ProfilerService::TIME_LINE_ACTIVE],
$profile->meta[ProfilerService::TIME_LINE_INACTIVE],
$profile->meta[ProfilerService::TIME_LINE_AFTER]
);
if ($this->config[self::CONFIG_PRIMARY_VALUE] == self::CONFIG_PRIMARY_VALUE_EFFECTIVE) {
$table .= sprintf(
"<tr>%s<td>%d&nbsp;ms (%d&nbsp;ms)</td><td>%d&nbsp;kB (%d&nbsp;kB)</td></tr>",
$labels,
$profile->duration * 1000,
$profile->absoluteDuration * 1000,
$profile->memoryUsageChange / 1024,
$profile->absoluteMemoryUsageChange / 1024
);
} else {
$table .= sprintf(
"<tr>%s<td>%d&nbsp;ms (%d&nbsp;ms)</td><td>%d&nbsp;kB (%d&nbsp;kB)</td></tr>",
$labels,
$profile->absoluteDuration * 1000,
$profile->duration * 1000,
$profile->absoluteMemoryUsageChange / 1024,
$profile->memoryUsageChange / 1024
);
}

if ($this->config[self::CONFIG_SHOW][self::CONFIG_SHOW_TIME_LINES]) {
/** @noinspection PhpInternalEntityUsedInspection */
$table .= sprintf(
"<tr class='tracy-addons-profiler-hidden'><td colspan='4'></td></tr><tr><td colspan='4'>" .
"<span class='tracy-addons-profiler-bar' style='width:%d%%;background-color:#cccccc;'></span>" .
"<span class='tracy-addons-profiler-bar' style='width:%d%%;background-color:#3987d4;'></span>" .
"<span class='tracy-addons-profiler-bar' style='width:%s%%;background-color:#6ba9e6;'></span>" .
"<span class='tracy-addons-profiler-bar' style='width:%s%%;background-color:#cccccc;'></span>" .
"</td></tr>",
$profile->meta[ProfilerService::TIME_LINE_BEFORE],
$profile->meta[ProfilerService::TIME_LINE_ACTIVE],
$profile->meta[ProfilerService::TIME_LINE_INACTIVE],
$profile->meta[ProfilerService::TIME_LINE_AFTER]
);
}
});

$table .= "</table>";
Expand Down Expand Up @@ -128,12 +180,13 @@ private function getMemoryChart()
);
}

$firstIteration = true;
$prevX = 0;
$prevY = $maxHeight;
$lines = "";
$points = "";
$this->profilerService->iterateMemoryTimeLine(function ($width, $height, $metaData) use ($colors, &$memoryChart, $maxWidth, $maxHeight, $margin, &$prevX, &$prevY, &$lines, &$points) {
if ($prevX == 0) {
$this->profilerService->iterateMemoryTimeLine(function ($time, $height, $metaData) use ($colors, &$memoryChart, $maxWidth, $maxHeight, $margin, &$firstIteration, &$prevX, &$prevY, &$lines, &$points) {
if ($firstIteration) {
/** @noinspection PhpInternalEntityUsedInspection */
$memoryChart .= sprintf(
"<text x='%d' y='%d' font-size='%d'>%d kB</text>",
Expand All @@ -142,8 +195,13 @@ private function getMemoryChart()
10,
floor($metaData[ProfilerService::META_MEMORY_PEAK] / 1024)
);
$firstIteration = false;
}
/** @noinspection PhpInternalEntityUsedInspection */
$thisX = floor(max(0, $time) / $metaData[ProfilerService::META_TIME_TOTAL] * $maxWidth);
if ($thisX == $prevX) {
return /* continue */;
}
$thisX = floor($prevX + $width * $maxWidth / 100);
$thisY = floor($maxHeight - $height * $maxHeight / 100);
$lines .= sprintf(
"<line x1='%d' y1='%d' x2='%d' y2='%d' stroke-width='1' stroke='%s' />",
Expand Down
35 changes: 31 additions & 4 deletions src/Profiler/Extension/ProfilerNetteExtension.php
Expand Up @@ -2,6 +2,7 @@

namespace Netpromotion\Profiler\Extension;

use Netpromotion\Profiler\Adapter\TracyBarAdapter;
use Netpromotion\Profiler\Profiler;
use Nette\DI\CompilerExtension;
use Nette\PhpGenerator\ClassType;
Expand All @@ -11,6 +12,10 @@ class ProfilerNetteExtension extends CompilerExtension
const PROFILER = "Netpromotion\\Profiler\\Profiler";
const TRACY_BAR_ADAPTER = "Netpromotion\\Profiler\\Adapter\\TracyBarAdapter";

const CONFIG_TRACY_BAR = "bar";
const CONFIG_PROFILE = "profile";
const CONFIG_PROFILE_CREATE_SERVICE = "createService";

/**
* @internal
* @return bool
Expand All @@ -31,10 +36,18 @@ private static function isActive()
public function loadConfiguration()
{
if (self::isActive()) {
/** @noinspection PhpInternalEntityUsedInspection */
$this->validateConfig([
self::CONFIG_PROFILE => [
self::CONFIG_PROFILE_CREATE_SERVICE => false
],
self::CONFIG_TRACY_BAR => TracyBarAdapter::getDefaultConfig()
]);

$builder = $this->getContainerBuilder();
$builder
->addDefinition($this->prefix("panel"))
->setClass(self::TRACY_BAR_ADAPTER);
->setFactory(self::TRACY_BAR_ADAPTER, [$this->config[self::CONFIG_TRACY_BAR]]);
$builder
->getDefinition("tracy.bar")
->addSetup("addPanel", ["@" . $this->prefix("panel")]);
Expand All @@ -47,12 +60,26 @@ public function loadConfiguration()
public function afterCompile(ClassType $class)
{
if (self::isActive()) {
$method = $class->getMethod("__construct");
$method->setBody(sprintf(
$__construct = $class->getMethod("__construct");
$__construct->setBody(sprintf(
"%s::enable();%s",
self::PROFILER,
$method->getBody()
$__construct->getBody()
));

if ($this->config[self::CONFIG_PROFILE][self::CONFIG_PROFILE_CREATE_SERVICE]) {
foreach ($class->getMethods() as $method) {
if (preg_match('/^createService/', $method->getName())) {
$createService = &$method;
$createService->setBody(sprintf(
"%s::start(__METHOD__);%s%s::finish(__METHOD__);return \$return;",
self::PROFILER,
str_replace("return ", "\$return = ", $createService->getBody()),
self::PROFILER
));
}
}
}
}
}

Expand Down
19 changes: 6 additions & 13 deletions src/Profiler/Service/ProfilerService.php
Expand Up @@ -133,25 +133,18 @@ public function iterateProfiles(callable $callback)
public function iterateMemoryTimeLine(callable $callback)
{
$metaData = $this->getMetaData();
$total = 0;
$previousTime = $metaData[self::META_TIME_ZERO] * 1000;
$totalTime = 0;
$height = 0;
foreach ($metaData[self::META_TIME_LINE] as $time => $values) {
$width = floor(
($time - $previousTime) / $metaData[self::META_TIME_TOTAL] / 10
);
if ($width <= 0) {
continue;
}
$time = $time / 1000 - $metaData[self::META_TIME_ZERO];
$height = floor(
$values[self::META_TIME_LINE__MEMORY_USAGE] / $metaData[self::META_MEMORY_PEAK] * 100
);
$total += $width;
$previousTime = $time;
call_user_func($callback, $width, $height, $metaData);
$totalTime += $time;
call_user_func($callback, $time, $height, $metaData);
}
if ($total < 100) {
call_user_func($callback, 100 - $total, $height, $metaData);
if ($totalTime < $metaData[self::META_TIME_TOTAL]) {
call_user_func($callback, $metaData[self::META_TIME_TOTAL] - $totalTime, $height, $metaData);
}
}
}
6 changes: 3 additions & 3 deletions tests/Profiler/Service/ProfilerServiceTest.php
Expand Up @@ -6,7 +6,7 @@
use /** @noinspection PhpInternalEntityUsedInspection */ Netpromotion\Profiler\Service\ProfilerService;
use PetrKnap\Php\Profiler\Profile;

class TracyBarAdapterTest extends \PHPUnit_Framework_TestCase
class ProfilerServiceTest extends \PHPUnit_Framework_TestCase
{
/**
* @runInSeparateProcess
Expand Down Expand Up @@ -142,8 +142,8 @@ public function testIterateMemoryTimeLineComputesCorrectValues(array $input, arr
public function dataIterateMemoryTimeLineComputesCorrectValues()
{
return [
[[[0 => 0, 10 => 10]], [0 => 0, 100 => 100]],
[[[0 => 1, 10 => 10], [4 => 6, 6 => 4]], [0 => 10, 40 => 60, 60 => 40, 100 => 100]],
[[[0 => 0, 10 => 10]], [0 => 0, 10 => 100]],
[[[0 => 1, 10 => 10], [4 => 6, 6 => 4]], [0 => 10, 4 => 60, 6 => 40, 10 => 100]],
];
}
}

0 comments on commit a3c0a62

Please sign in to comment.