Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FOUR-20535 Initial Setup (Laravel + Prometheus Integration) #7772

Merged
merged 6 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions ProcessMaker/Facades/Metrics.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace ProcessMaker\Facades;

use Illuminate\Support\Facades\Facade;
use ProcessMaker\Services\MetricsService;

class Metrics extends Facade
{
/**
* Get the registered name of the component.
*
* @return string
*/
protected static function getFacadeAccessor()
{
return MetricsService::class;
}
}
6 changes: 6 additions & 0 deletions ProcessMaker/Http/Controllers/Designer/DesignerController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Illuminate\Http\Request;
use Illuminate\Support\Composer;
use Illuminate\Support\Facades\Auth;
use ProcessMaker\Facades\Metrics;
use ProcessMaker\Http\Controllers\Controller;
use ProcessMaker\Traits\HasControllerAddons;

Expand All @@ -20,6 +21,11 @@ class DesignerController extends Controller
*/
public function index(Request $request)
{
// Register a counter for the total number of requests
Metrics::registerCounter('requests_total', 'Total requests made', ['method']);
// Increment the counter for the current request
Metrics::incrementCounter('requests_total', ['GET']);

$hasPackage = false;
if (class_exists(\ProcessMaker\Package\Projects\Models\Project::class)) {
$hasPackage = true;
Expand Down
27 changes: 27 additions & 0 deletions ProcessMaker/Providers/MetricsServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace ProcessMaker\Providers;

use ProcessMaker\Services\MetricsService;
use Illuminate\Support\ServiceProvider;

class MetricsServiceProvider extends ServiceProvider
{
/**
* Register services.
*/
public function register(): void
{
$this->app->singleton(MetricsService::class, function ($app) {
return new MetricsService();
});
}

/**
* Bootstrap services.
*/
public function boot(): void
{
//
}
}
110 changes: 110 additions & 0 deletions ProcessMaker/Services/MetricsService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<?php

namespace ProcessMaker\Services;

use Prometheus\CollectorRegistry;
use Prometheus\RenderTextFormat;
use Prometheus\Storage\Redis;

class MetricsService
{
private $registry;

/**
* Initializes the MetricsService with a CollectorRegistry using the provided storage adapter.
*
* @param mixed $adapter The storage adapter to use (e.g., Redis).
*/
public function __construct($adapter = null)
{
// Set up Redis as the adapter if none is provided
if ($adapter === null) {
$adapter = new Redis([
'host' => env('REDIS_HOST', '127.0.0.1'),
'port' => env('REDIS_PORT', '6379')
]);
}
$this->registry = new CollectorRegistry($adapter);
}

/**
* Returns the CollectorRegistry used by the MetricsService.
*
* @return \Prometheus\CollectorRegistry The CollectorRegistry used by the MetricsService.
*/
public function getMetrics()
{
return $this->registry;
}

/**
* Retrieves a metric by its name.
*
* This method iterates through all registered metrics and returns the first metric that matches the given name.
* If no metric with the specified name is found, it returns null.
*
* @param string $name The name of the metric to retrieve.
* @return \Prometheus\MetricFamilySamples|null The metric with the specified name, or null if not found.
*/
public function getMetricByName(string $name)
{
$metrics = $this->registry->getMetricFamilySamples();
foreach ($metrics as $metric) {
if ($metric->getName() === $name) {
return $metric;
}
}
return null;
}

/**
* Registers a new counter metric.
*
* @param string $name The name of the counter.
* @param string $help The help text of the counter.
* @param array $labels The labels of the counter.
* @return \Prometheus\Counter The registered counter.
*/
public function registerCounter(string $name, string $help, array $labels = [])
{
return $this->registry->registerCounter('app', $name, $help, $labels);
}

/**
* Registers a new histogram metric.
*
* @param string $name The name of the histogram.
* @param string $help The help text of the histogram.
* @param array $labels The labels of the histogram.
* @param array $buckets The buckets of the histogram.
* @return \Prometheus\Histogram The registered histogram.
*/
public function registerHistogram(string $name, string $help, array $labels = [], array $buckets = [])
{
return $this->registry->registerHistogram('app', $name, $help, $labels, $buckets);
}

/**
* Increments a counter metric by 1.
*
* @param string $name The name of the counter.
* @param array $labelValues The values of the labels for the counter.
*/
public function incrementCounter(string $name, array $labelValues = [])
{
$counter = $this->registry->getCounter('app', $name);
$counter->inc($labelValues);
}

/**
* Renders the metrics in the Prometheus text format.
*
* @return string The rendered metrics.
*/
public function renderMetrics()
{
$renderer = new RenderTextFormat();
$metrics = $this->registry->getMetricFamilySamples();
return $renderer->render($metrics);
}
}
Loading