Skip to content

Commit edb490f

Browse files
authored
Merge pull request #7772 from ProcessMaker/feature/FOUR-20535
FOUR-20535 Initial Setup (Laravel + Prometheus Integration)
2 parents 2496c6a + 6760384 commit edb490f

File tree

15 files changed

+720
-3
lines changed

15 files changed

+720
-3
lines changed

ProcessMaker/Facades/Metrics.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace ProcessMaker\Facades;
4+
5+
use Illuminate\Support\Facades\Facade;
6+
use ProcessMaker\Services\MetricsService;
7+
8+
class Metrics extends Facade
9+
{
10+
/**
11+
* Get the registered name of the component.
12+
*
13+
* @return string
14+
*/
15+
protected static function getFacadeAccessor()
16+
{
17+
return MetricsService::class;
18+
}
19+
}

ProcessMaker/Http/Controllers/Designer/DesignerController.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Illuminate\Http\Request;
77
use Illuminate\Support\Composer;
88
use Illuminate\Support\Facades\Auth;
9+
use ProcessMaker\Facades\Metrics;
910
use ProcessMaker\Http\Controllers\Controller;
1011
use ProcessMaker\Traits\HasControllerAddons;
1112

@@ -20,6 +21,11 @@ class DesignerController extends Controller
2021
*/
2122
public function index(Request $request)
2223
{
24+
// Register a counter for the total number of requests
25+
Metrics::registerCounter('requests_total', 'Total requests made', ['method']);
26+
// Increment the counter for the current request
27+
Metrics::incrementCounter('requests_total', ['GET']);
28+
2329
$hasPackage = false;
2430
if (class_exists(\ProcessMaker\Package\Projects\Models\Project::class)) {
2531
$hasPackage = true;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace ProcessMaker\Providers;
4+
5+
use ProcessMaker\Services\MetricsService;
6+
use Illuminate\Support\ServiceProvider;
7+
8+
class MetricsServiceProvider extends ServiceProvider
9+
{
10+
/**
11+
* Register services.
12+
*/
13+
public function register(): void
14+
{
15+
$this->app->singleton(MetricsService::class, function ($app) {
16+
return new MetricsService();
17+
});
18+
}
19+
20+
/**
21+
* Bootstrap services.
22+
*/
23+
public function boot(): void
24+
{
25+
//
26+
}
27+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
3+
namespace ProcessMaker\Services;
4+
5+
use Prometheus\CollectorRegistry;
6+
use Prometheus\RenderTextFormat;
7+
use Prometheus\Storage\Redis;
8+
9+
class MetricsService
10+
{
11+
private $registry;
12+
13+
/**
14+
* Initializes the MetricsService with a CollectorRegistry using the provided storage adapter.
15+
*
16+
* @param mixed $adapter The storage adapter to use (e.g., Redis).
17+
*/
18+
public function __construct($adapter = null)
19+
{
20+
// Set up Redis as the adapter if none is provided
21+
if ($adapter === null) {
22+
$adapter = new Redis([
23+
'host' => env('REDIS_HOST', '127.0.0.1'),
24+
'port' => env('REDIS_PORT', '6379')
25+
]);
26+
}
27+
$this->registry = new CollectorRegistry($adapter);
28+
}
29+
30+
/**
31+
* Returns the CollectorRegistry used by the MetricsService.
32+
*
33+
* @return \Prometheus\CollectorRegistry The CollectorRegistry used by the MetricsService.
34+
*/
35+
public function getMetrics()
36+
{
37+
return $this->registry;
38+
}
39+
40+
/**
41+
* Retrieves a metric by its name.
42+
*
43+
* This method iterates through all registered metrics and returns the first metric that matches the given name.
44+
* If no metric with the specified name is found, it returns null.
45+
*
46+
* @param string $name The name of the metric to retrieve.
47+
* @return \Prometheus\MetricFamilySamples|null The metric with the specified name, or null if not found.
48+
*/
49+
public function getMetricByName(string $name)
50+
{
51+
$metrics = $this->registry->getMetricFamilySamples();
52+
foreach ($metrics as $metric) {
53+
if ($metric->getName() === $name) {
54+
return $metric;
55+
}
56+
}
57+
return null;
58+
}
59+
60+
/**
61+
* Registers a new counter metric.
62+
*
63+
* @param string $name The name of the counter.
64+
* @param string $help The help text of the counter.
65+
* @param array $labels The labels of the counter.
66+
* @return \Prometheus\Counter The registered counter.
67+
*/
68+
public function registerCounter(string $name, string $help, array $labels = [])
69+
{
70+
return $this->registry->registerCounter('app', $name, $help, $labels);
71+
}
72+
73+
/**
74+
* Registers a new histogram metric.
75+
*
76+
* @param string $name The name of the histogram.
77+
* @param string $help The help text of the histogram.
78+
* @param array $labels The labels of the histogram.
79+
* @param array $buckets The buckets of the histogram.
80+
* @return \Prometheus\Histogram The registered histogram.
81+
*/
82+
public function registerHistogram(string $name, string $help, array $labels = [], array $buckets = [])
83+
{
84+
return $this->registry->registerHistogram('app', $name, $help, $labels, $buckets);
85+
}
86+
87+
/**
88+
* Increments a counter metric by 1.
89+
*
90+
* @param string $name The name of the counter.
91+
* @param array $labelValues The values of the labels for the counter.
92+
*/
93+
public function incrementCounter(string $name, array $labelValues = [])
94+
{
95+
$counter = $this->registry->getCounter('app', $name);
96+
$counter->inc($labelValues);
97+
}
98+
99+
/**
100+
* Renders the metrics in the Prometheus text format.
101+
*
102+
* @return string The rendered metrics.
103+
*/
104+
public function renderMetrics()
105+
{
106+
$renderer = new RenderTextFormat();
107+
$metrics = $this->registry->getMetricFamilySamples();
108+
return $renderer->render($metrics);
109+
}
110+
}

0 commit comments

Comments
 (0)