diff --git a/Model/Profiler/Driver/Buggregator.php b/Model/Profiler/Driver/Buggregator.php
new file mode 100644
index 0000000..12e5df8
--- /dev/null
+++ b/Model/Profiler/Driver/Buggregator.php
@@ -0,0 +1,55 @@
+driver->start(
+ [
+ self::IGNORED_FUNCTIONS_KEY => ['SpiralPackages\Profiler\Profiler::end'],
+ ]
+ );
+ }
+
+ /**
+ * Terminates the current profiling session and stores the results.
+ * @param array $tags Optional tags to attach to the profiling data.
+ * @return void
+ * @throws FileSystemException
+ * @throws RuntimeException
+ */
+ public function end(array $tags = []): void
+ {
+ $result = $this->driver->end();
+ $endpoint = $this->deploymentConfig->get('xhprofprofiler/endpoint');
+ $appName = $this->deploymentConfig->get('xhprofprofiler/app_name');
+ if (!empty($appName) && !empty($endpoint) && is_string($endpoint) && is_string($appName)) {
+ $storage = new WebStorage(new NativeHttpClient(), $endpoint);
+ $storage->store(
+ $appName,
+ $tags,
+ new \DateTimeImmutable(),
+ $result
+ );
+ }
+ }
+}
diff --git a/Model/Profiler/Driver/XHGui.php b/Model/Profiler/Driver/XHGui.php
new file mode 100644
index 0000000..a263bed
--- /dev/null
+++ b/Model/Profiler/Driver/XHGui.php
@@ -0,0 +1,35 @@
+initializeDriver($config);
+ }
+
+ private function initializeDriver(array $config): void
+ {
+ $this->driver = new Profiler($config);
+ }
+
+ public function start(): void
+ {
+ $this->driver->enable();
+ }
+
+ public function end(array $tags = []): void
+ {
+ $this->driver->save($this->driver->disable());
+ }
+}
diff --git a/Model/Profiler/XhprofProfiler.php b/Model/Profiler/XhprofProfiler.php
index db760e6..1eae27a 100644
--- a/Model/Profiler/XhprofProfiler.php
+++ b/Model/Profiler/XhprofProfiler.php
@@ -2,25 +2,13 @@
namespace JustBetter\XhprofProfiler\Model\Profiler;
-use Magento\Framework\App\DeploymentConfig;
-use Magento\Framework\Exception\FileSystemException;
-use Magento\Framework\Exception\RuntimeException;
-use SpiralPackages\Profiler\Driver\XhprofDriver;
-use SpiralPackages\Profiler\Storage\WebStorage;
-use Symfony\Component\HttpClient\NativeHttpClient;
+use JustBetter\XhprofProfiler\Api\DriverInterface;
class XhprofProfiler
{
- public const HEADER = 'X-Xhprof-Enabled';
-
- public const IGNORED_FUNCTIONS_KEY = 'ignored_functions';
-
- public array $tags;
-
public function __construct(
- protected XhprofDriver $driver,
- protected DeploymentConfig $deploymentConfig,
- array $tags = []
+ protected DriverInterface $driver,
+ protected array $tags = []
)
{
$this->tags = $tags;
@@ -28,30 +16,11 @@ public function __construct(
public function handle(): void
{
- $this->driver->start(
- [
- self::IGNORED_FUNCTIONS_KEY => ['SpiralPackages\Profiler\Profiler::end'],
- ]
- );
+ $this->driver->start();
}
- /**
- * @throws FileSystemException
- * @throws RuntimeException
- */
public function terminate(array $tags = []): void
{
- $result = $this->driver->end();
- $endpoint = $this->deploymentConfig->get('xhprofprofiler/endpoint');
- $appName = $this->deploymentConfig->get('xhprofprofiler/app_name');
- if (!empty($appName) && !empty($endpoint) && is_string($endpoint) && is_string($appName)) {
- $storage = new WebStorage(new NativeHttpClient(), $endpoint);
- $storage->store(
- $appName,
- \array_merge($this->tags ?? [], $tags),
- new \DateTimeImmutable(),
- $result
- );
- }
+ $this->driver->end(array_merge($this->tags ?? [], $tags));
}
}
diff --git a/Plugin/AppInterfacePlugin.php b/Plugin/AppInterfacePlugin.php
index dae73eb..6ce778f 100644
--- a/Plugin/AppInterfacePlugin.php
+++ b/Plugin/AppInterfacePlugin.php
@@ -1,4 +1,5 @@
isEnabled()) {
return $proceed();
@@ -34,12 +38,12 @@ public function aroundLaunch(
return $response;
}
- public function isEnabled(): bool
+ private function isEnabled(): bool
{
- if ($this->request->getHeader(XhprofProfiler::HEADER)) {
- return filter_var($this->request->getHeader(XhprofProfiler::HEADER), FILTER_VALIDATE_BOOLEAN);
+ if ($this->request->getHeader(self::HEADER)) {
+ return filter_var($this->request->getHeader(self::HEADER), FILTER_VALIDATE_BOOLEAN);
}
- return isset($_ENV['XHPROF_ENABLED']) ? (bool) $_ENV['XHPROF_ENABLED'] : false;
+ return isset($_ENV['XHPROF_ENABLED']) ? (bool)$_ENV['XHPROF_ENABLED'] : false;
}
}
diff --git a/README.md b/README.md
index 8141698..afcd5dd 100644
--- a/README.md
+++ b/README.md
@@ -8,6 +8,7 @@ This module integrates Xhprof profiling capabilities into your Magento 2 applica
- Magento 2.4.7 or higher
- Xhprof PHP extension
+- Compatible with XHGui
- Compatible with Buggregator
## Installation
@@ -31,7 +32,16 @@ This module integrates Xhprof profiling capabilities into your Magento 2 applica
bin/magento setup:di:compile
```
-## Configuration
+## Configuration for Buggregator
+
+By default this module uses XHGui for processing the profiling data. We can use the Buggregator driver by overriding the default driver via xml:
+```
+
+
+ JustBetter\XhprofProfiler\Model\Profiler\Driver\Buggregator
+
+
+```
Configure the module by adding the following configuration to your `app/etc/env.php` file:
@@ -48,30 +58,36 @@ return [
- **app_name**: The name of your application.
- **endpoint**: The endpoint where the profiling data will be stored.
-## Usage
+## Compatibility
-The profiling is automatically enabled for all requests. The module uses the `AppInterfacePlugin` to start and terminate the profiler around each request.
+This module is compatible with [XHGui](https://github.com/perftools/xhgui) and [Buggregator](https://buggregator.dev/). These are graphical interfaces for viewing XHProf profiling data.
-### Key Classes and Methods
+### To integrate with XHGui:
-- **`XhprofProfiler`**
- - **Constants:**
- - `HEADER`: The header key used to enable Xhprof profiling.
- - `IGNORED_FUNCTIONS_KEY`: The key for ignored functions in the profiler.
- - **Methods:**
- - `__construct()`: Initializes the profiler with the given driver, deployment configuration, and optional tags.
- - `handle()`: Starts the profiler.
- - `terminate()`: Ends the profiler and stores the profiling data.
+1. Follow the installation guide of XHGui at [XHGui](https://github.com/perftools/xhgui)
+2. By default we use the default xhprof profiler and the results are getting uploaded to XHGui.
+3. Update default configuration via di.xml, check [config.default.php](https://github.com/perftools/xhgui/blob/0.23.x/config/config.default.php) for the possible options.
-- **`AppInterfacePlugin`**
- - **Methods:**
- - `aroundLaunch()`: Wraps around the application launch to start and stop the profiler.
-
-## Buggregator Compatibility
+#### Default XHGui configuration
+You can pass custom configuration to the XHGui driver via the arguments like the default configuration.
+```
+
+
+
+ - xhprof
+ - upload
+ -
+
- http://xhgui.xhgui.orb.local/run/import
+ - 3
+ - token
+
+
+
+
-This module is compatible with [Buggregator](https://buggregator.dev/), a debug and profiler tool for PHP applications. Buggregator can collect and visualize profiling data generated by this module, providing a comprehensive debugging and performance analysis experience.
+```
-To integrate with Buggregator:
+### To integrate with Buggregator:
1. Ensure Buggregator is installed and configured in your environment.
2. Configure the endpoint in `app/etc/env.php` to point to Buggregator's profiling data endpoint.
@@ -88,45 +104,22 @@ return [
];
```
-## Example
-
-Here is an example of how the profiler is used in the plugin:
-
-```php
-namespace JustBetter\XhprofProfiler\Plugin;
-
-use JustBetter\XhprofProfiler\Model\Profiler\XhprofProfiler;
-use Magento\Framework\App\ResponseInterface;
-use Magento\Framework\AppInterface as Application;
-
-class AppInterfacePlugin
-{
- public function __construct(
- protected XhprofProfiler $profiler
- )
- {
- }
-
- public function aroundLaunch(
- Application $subject,
- callable $proceed,
- ) : ResponseInterface {
- $this->profiler->handle();
- $response = $proceed();
- $this->profiler->terminate();
- return $response;
- }
-}
-```
+## Usage
-## Exception Handling
+The profiling is automatically enabled for all requests. The module uses the `AppInterfacePlugin` to start and terminate the profiler around each request.
-The `terminate` method of the `XhprofProfiler` class can throw the following exceptions:
-- **FileSystemException**: If there is an issue with the file system.
-- **RuntimeException**: If there is a runtime issue.
+### Key Classes and Methods
-Ensure you have proper exception handling in place when integrating this module.
+- **`XhprofProfiler`**
+ - **Methods:**
+ - `__construct()`: Initializes the profiler with the given driver and optional tags.
+ - `handle()`: Starts the profiler.
+ - `terminate()`: Ends the profiler and stores the profiling data.
+- **`AppInterfacePlugin`**
+ - **Methods:**
+ - `aroundLaunch()`: Wraps around the application launch to start and stop the profiler.
+
## License
This project is licensed under the MIT License - see the LICENSE file for details.
diff --git a/composer.json b/composer.json
index 1e551c0..b76cdbd 100644
--- a/composer.json
+++ b/composer.json
@@ -13,7 +13,8 @@
"php": ">=8.2",
"magento/framework": "*",
"magento/module-config": "^101.2",
- "spiral-packages/profiler": "^1.2"
+ "spiral-packages/profiler": "^1.2",
+ "perftools/php-profiler": "^1.1"
},
"repositories": {
"magento": {
diff --git a/etc/di.xml b/etc/di.xml
index 3912ef6..0675c31 100644
--- a/etc/di.xml
+++ b/etc/di.xml
@@ -3,4 +3,22 @@
+
+
+ JustBetter\XhprofProfiler\Model\Profiler\Driver\XHGui
+
+
+
+
+
+ - xhprof
+ - upload
+ -
+
- http://xhgui.xhgui.orb.local/run/import
+ - 3
+ - token
+
+
+
+