-
-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #199 from buggregator/feature/195
Improved Profiler Module:
- Loading branch information
Showing
38 changed files
with
1,564 additions
and
11 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
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
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 |
---|---|---|
|
@@ -10,6 +10,7 @@ | |
'exclude' => [ | ||
directory('resources'), | ||
directory('config'), | ||
directory('vendor'), | ||
'tests', | ||
], | ||
]; |
31 changes: 31 additions & 0 deletions
31
app/database/Migrations/20240608.112643_1_1_default_create_profiles.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,31 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Database\Migrations; | ||
|
||
use Cycle\Migrations\Migration; | ||
|
||
class OrmDefault178280ff82db54b14ccc25ce1028b465 extends Migration | ||
{ | ||
protected const DATABASE = 'default'; | ||
|
||
public function up(): void | ||
{ | ||
$this->table('profiles') | ||
->addColumn('uuid', 'string', ['nullable' => false, 'defaultValue' => null, 'size' => 36]) | ||
->addColumn('name', 'string', ['nullable' => false, 'defaultValue' => null, 'size' => 255]) | ||
->addColumn('cpu', 'integer', ['nullable' => false, 'defaultValue' => null]) | ||
->addColumn('wt', 'integer', ['nullable' => false, 'defaultValue' => null]) | ||
->addColumn('ct', 'integer', ['nullable' => false, 'defaultValue' => null]) | ||
->addColumn('mu', 'integer', ['nullable' => false, 'defaultValue' => null]) | ||
->addColumn('pmu', 'integer', ['nullable' => false, 'defaultValue' => null]) | ||
->setPrimaryKeys(['uuid']) | ||
->create(); | ||
} | ||
|
||
public function down(): void | ||
{ | ||
$this->table('profiles')->drop(); | ||
} | ||
} |
60 changes: 60 additions & 0 deletions
60
app/database/Migrations/20240608.112643_2_2_default_create_profile_edges.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,60 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Database\Migrations; | ||
|
||
use Cycle\Migrations\Migration; | ||
|
||
class OrmDefault972859df19369e40b49f2fae46c0a310 extends Migration | ||
{ | ||
protected const DATABASE = 'default'; | ||
|
||
public function up(): void | ||
{ | ||
$this->table('profile_edges') | ||
->addColumn('uuid', 'string', ['nullable' => false, 'defaultValue' => null, 'size' => 36]) | ||
->addColumn('profile_uuid', 'string', ['nullable' => false, 'defaultValue' => null, 'size' => 36]) | ||
->addColumn('order', 'integer', ['nullable' => false, 'defaultValue' => null]) | ||
->addColumn('callee', 'text', ['nullable' => false, 'defaultValue' => null]) | ||
->addColumn('caller', 'text', ['nullable' => true, 'defaultValue' => null]) | ||
->addColumn('parent_uuid', 'string', ['nullable' => true, 'defaultValue' => null, 'size' => 36]) | ||
->addColumn('cpu', 'integer', ['nullable' => false, 'defaultValue' => null]) | ||
->addColumn('wt', 'integer', ['nullable' => false, 'defaultValue' => null]) | ||
->addColumn('ct', 'integer', ['nullable' => false, 'defaultValue' => null]) | ||
->addColumn('mu', 'integer', ['nullable' => false, 'defaultValue' => null]) | ||
->addColumn('pmu', 'integer', ['nullable' => false, 'defaultValue' => null]) | ||
->addColumn('d_cpu', 'integer', ['nullable' => false, 'defaultValue' => null]) | ||
->addColumn('d_wt', 'integer', ['nullable' => false, 'defaultValue' => null]) | ||
->addColumn('d_ct', 'integer', ['nullable' => false, 'defaultValue' => null]) | ||
->addColumn('d_mu', 'integer', ['nullable' => false, 'defaultValue' => null]) | ||
->addColumn('d_pmu', 'integer', ['nullable' => false, 'defaultValue' => null]) | ||
->addColumn('p_cpu', 'float', ['nullable' => false, 'defaultValue' => null]) | ||
->addColumn('p_wt', 'float', ['nullable' => false, 'defaultValue' => null]) | ||
->addColumn('p_ct', 'float', ['nullable' => false, 'defaultValue' => null]) | ||
->addColumn('p_mu', 'float', ['nullable' => false, 'defaultValue' => null]) | ||
->addColumn('p_pmu', 'float', ['nullable' => false, 'defaultValue' => null]) | ||
->addIndex(['profile_uuid'], ['name' => 'profile_edges_index_profile_uuid_66643ff3139b6', 'unique' => false], | ||
) | ||
->addIndex(['parent_uuid'], ['name' => 'profile_edges_index_parent_uuid_66643ff3139e7', 'unique' => false]) | ||
->addForeignKey(['profile_uuid'], 'profiles', ['uuid'], [ | ||
'name' => 'profile_edges_foreign_profile_uuid_66643ff3139c9', | ||
'delete' => 'CASCADE', | ||
'update' => 'CASCADE', | ||
'indexCreate' => true, | ||
]) | ||
->addForeignKey(['parent_uuid'], 'profile_edges', ['uuid'], [ | ||
'name' => 'profile_edges_foreign_parent_uuid_66643ff3139f1', | ||
'delete' => 'CASCADE', | ||
'update' => 'CASCADE', | ||
'indexCreate' => true, | ||
]) | ||
->setPrimaryKeys(['uuid']) | ||
->create(); | ||
} | ||
|
||
public function down(): void | ||
{ | ||
$this->table('profile_edges')->drop(); | ||
} | ||
} |
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
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,14 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Modules\Profiler\Application\CallGraph; | ||
|
||
enum Metric: string | ||
{ | ||
case CPU = 'cpu'; | ||
case WallTime = 'wt'; | ||
case MemoryChange = 'pmu'; | ||
case Memory = 'mu'; | ||
case Calls = 'ct'; | ||
} |
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,126 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Modules\Profiler\Application\CallGraph; | ||
|
||
use App\Application\Domain\ValueObjects\Uuid; | ||
use Modules\Profiler\Domain\Edge; | ||
|
||
final readonly class Node implements \JsonSerializable | ||
{ | ||
public static function fromEdge( | ||
Edge $edge, | ||
Metric $metric, | ||
int $maxColorPercentage, | ||
): self { | ||
return new self( | ||
$edge->getUuid(), | ||
$edge->getCallee(), | ||
$metric, | ||
$edge->getCost(), | ||
$edge->getPercents(), | ||
$maxColorPercentage, | ||
); | ||
} | ||
|
||
public string $color; | ||
public string $textColor; | ||
public string $label; | ||
|
||
public function __construct( | ||
public Uuid $uuid, | ||
public string $callee, | ||
public Metric $metric, | ||
public Edge\Cost $cost, | ||
public Edge\Percents $percents, | ||
public int $maxColorPercentage, | ||
) { | ||
$this->color = $this->isImportant() ? $this->detectNodeColor() : '#FFFFFF'; | ||
$this->textColor = $this->isImportant() ? $this->detectTextColor($this->color) : '#000000'; | ||
$this->label = $this->buildLabel(); | ||
} | ||
|
||
public function isImportant(): bool | ||
{ | ||
return $this->getPercentsMetric() >= $this->maxColorPercentage; | ||
} | ||
|
||
public function isSatisfied(int|float $threshold): bool | ||
{ | ||
return $this->getPercentsMetric() <= $threshold; | ||
} | ||
|
||
public function getCostMetric(): float|int | ||
{ | ||
return $this->cost->{$this->metric->value}; | ||
} | ||
|
||
public function getPercentsMetric(): float|int | ||
{ | ||
return $this->percents->{$this->metric->value}; | ||
} | ||
|
||
public function jsonSerialize(): array | ||
{ | ||
return [ | ||
'id' => (string) $this->uuid, | ||
'name' => $this->label, | ||
'cost' => [ | ||
'cpu' => $this->cost->cpu, | ||
'wt' => $this->cost->wt, | ||
'pmu' => $this->cost->pmu, | ||
'mu' => $this->cost->mu, | ||
'ct' => $this->cost->ct, | ||
], | ||
'metrics' => [ | ||
'cost' => $this->getCostMetric(), | ||
'percents' => $this->getPercentsMetric(), | ||
], | ||
'color' => $this->color, | ||
'textColor' => $this->textColor, | ||
]; | ||
} | ||
|
||
private function buildLabel(): string | ||
{ | ||
if ($this->cost->ct > 0) { | ||
return \sprintf( | ||
'%s (%sx)', | ||
$this->callee, | ||
$this->cost->ct, | ||
); | ||
} | ||
|
||
return $this->callee; | ||
} | ||
|
||
private function detectNodeColor(): string | ||
{ | ||
$percent = $this->getPercentsMetric(); | ||
|
||
return match (true) { | ||
$percent <= 10 => '#FFFFFF', // White | ||
$percent <= 20 => '#f19797', // Lighter shade towards dark red | ||
$percent <= 30 => '#d93939', // Light shade towards dark red | ||
$percent <= 40 => '#ad1e1e', // Intermediate lighter shade towards dark red | ||
$percent <= 50 => '#982525', // Intermediate shade towards dark red | ||
$percent <= 60 => '#862323', // Intermediate darker shade towards dark red | ||
$percent <= 70 => '#671d1d', // Darker shade towards dark red | ||
$percent <= 80 => '#540d0d', // More towards dark red | ||
$percent <= 90 => '#340707', // Almost dark red | ||
default => '#000000', // Black | ||
}; | ||
} | ||
|
||
private function detectTextColor(string $nodeColor): string | ||
{ | ||
$hex = \ltrim($nodeColor, '#'); | ||
$r = \hexdec(\substr($hex, 0, 2)); | ||
$g = \hexdec(\substr($hex, 2, 2)); | ||
$b = \hexdec(\substr($hex, 4, 2)); | ||
$brightness = ($r * 299 + $g * 587 + $b * 114) / 1000; | ||
|
||
return $brightness > 125 ? '#000000' : '#FFFFFF'; | ||
} | ||
} |
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
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
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
Oops, something went wrong.