Skip to content
This repository was archived by the owner on Oct 9, 2018. It is now read-only.

Lumen compat #5

Merged
merged 1 commit into from
Nov 22, 2016
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
51 changes: 42 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
# laravel-prometheus-exporter

A prometheus exporter for the Laravel web framework.
A prometheus exporter for the Laravel and the Lumen web framework.

It tracks latency and request counts by
request method, route and response code.

By default the app will then exporter prometheus metrics on `/metrics`.

## Installation
`composer require tback/laravel-prometheus-exporter`

Expand All @@ -23,30 +21,65 @@ Ensure php redis is installed and enabled.
By default it looks for a redis server at localhost:6379. The server
can be configured in `config/prometheus_exporter.php`.

### Register the ServiceProvider
### Laravel
#### Register the ServiceProvider
In `config/app.php`
```
'providers' => [
...
Tback\PrometheusExporter\ServiceProvider::class,
Tback\PrometheusExporter\LpeServiceProvider::class,
];
```

### Enable the Middleware
#### Enable the Middleware
In `app/Http/Kernel.php`
```
protected $middleware = [
...
\Tback\PrometheusExporter\Middleware::class,
\Tback\PrometheusExporter\Middleware\LaravelResponseTimeMiddleware::class,
];
```

#### Add an endpoint for the metrics
```
Route::get('metric', \Tback\PrometheusExporter\LpeController::class . '@metrics');
```

### Lumen
#### Register the ServiceProvider
In `bootstrap/app.php`
```
$app->register(\Tback\PrometheusExporter\LpeServiceProvider::class);
```

#### Enable the Middleware
In `bootstrap/app.php`
```
$app->middleware([
\Tback\PrometheusExporter\Middleware\LumenResponseTimeMiddleware::class
]);
```

#### Add an endpoint for the metrics
```
Route::get('metric', \Tback\PrometheusExporter\LpeController::class . '@metrics');
```

## Configuration
The configuration can be found in `config/prometheus_exporter.php`.

| name | description |
|-------------|---------------------------------------------------------|
| adapter | Storage adapter to use: 'apc' or 'redis' default: 'apc' |
| metrics_path| Where to reach metrics. default: '/metrics' |
| name | name (prefix) to use in prometheus metrics. default: 'http_server' |
| namespace | name (prefix) to use in prometheus metrics. default: 'default' |
| namespace_http_server | name (prefix) to use for http latency in prometheus metrics. default: 'http_server' |
| redis | array of redis parameters. see prometheus_exporter.php for details |

## Usage
```
$manager = app('LpeManager');

$manager->incCounter('NAME', 'HELP', 'NAMESPACE', 'LABELS', 'DATA');

$manager->incByCounter('NAME', 'HELP', 'VALUE', 'NAMESPACE', 'LABELS', 'DATA');
```
30 changes: 30 additions & 0 deletions src/LpeController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php
namespace Tback\PrometheusExporter;

use Illuminate\Http\Response;
use Illuminate\Routing\Controller;
use Prometheus\RenderTextFormat;

/**
* Class LpeController
* @package Tback\PrometheusExporter
*/
class LpeController extends Controller
{
/**
* metric
*
* Expose metrics for prometheus
*
* @return Response
*/
public function metrics()
{
$manager = app('LpeManager');

$renderer = new RenderTextFormat();

return response($renderer->render($manager->getMetricFamilySamples()))
->header('Content-Type', $renderer::MIME_TYPE);
}
}
74 changes: 74 additions & 0 deletions src/LpeManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php
namespace Tback\PrometheusExporter;

use Prometheus\CollectorRegistry;

/**
* Class LpeManager
*
* @author Christopher Lorke <lorke@traum-ferienwohnungen.de>
* @package Tback\PrometheusExporter
*/
class LpeManager
{
/**
* @var CollectorRegistry
*/
protected $registry;

/**
* LpeManager constructor.
* @param CollectorRegistry $registry
*/
public function __construct(CollectorRegistry $registry)
{
$this->registry = $registry;
}

/**
* Get metric family samples
*
* @return \Prometheus\MetricFamilySamples[]
*/
public function getMetricFamilySamples()
{
return $this->registry->getMetricFamilySamples();
}

/**
* inc
*
* @param string $name
* @param string $help
* @param string|null $namespace
* @param array $labels
* @param array $data
*/
public function incCounter($name, $help, $namespace = null, array $labels = [], array $data = [])
{
if (!$namespace) {
$namespace = config('prometheus_exporter.namespace');
}

$this->registry->registerCounter($namespace, $name, $help, $labels)->inc($data);
}

/**
* incBy
*
* @param string $name
* @param string $help
* @param string|null $namespace
* @param array $labels
* @param float $value
* @param array $data
*/
public function incByCounter($name, $help, $value, $namespace = null, array $labels = [], array $data = [])
{
if (!$namespace) {
$namespace = config('prometheus_exporter.namespace');
}

$this->registry->registerCounter($namespace, $name, $help, $labels)->incBy($value, $data);
}
}
32 changes: 16 additions & 16 deletions src/ServiceProvider.php → src/LpeServiceProvider.php
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
<?php

namespace Tback\PrometheusExporter;

use Prometheus\CollectorRegistry;
use Prometheus\Storage\APC;
use Prometheus\Storage\Redis;
use Illuminate\Support\ServiceProvider;

class ServiceProvider extends \Illuminate\Support\ServiceProvider
/**
* Class LpeServiceProvider
* @package Tback\PrometheusExporter
*/
class LpeServiceProvider extends ServiceProvider
{
public function boot()
{
$this->publishes([
__DIR__.'/config.php' => config_path('prometheus_exporter.php'),
]);

if (!$this->app->routesAreCached()) {
require __DIR__.'/routes.php';
}
}

/**
* Register the service provider.
*/
public function register()
{
$this->mergeConfigFrom(
__DIR__.'/config.php', 'prometheus_exporter'
__DIR__.'/config/config.php',
'prometheus_exporter'
);

$this->app->singleton('prometheus', function ($app) {
/**
* LpeManager
*/
$this->app->singleton('LpeManager', function () {
switch (config('prometheus_exporter.adapter')) {
case 'apc':
$adapter = new APC();
Expand All @@ -39,7 +39,7 @@ public function register()

$registry = new CollectorRegistry($adapter);

return $registry;
return new LpeManager($registry);
});
}
}
34 changes: 0 additions & 34 deletions src/Middleware.php

This file was deleted.

75 changes: 75 additions & 0 deletions src/Middleware/AbstractResponseTimeMiddleware.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php
namespace Tback\PrometheusExporter\Middleware;

use Closure;
use Illuminate\Http\Request;
use Tback\PrometheusExporter\LpeManager;

/**
* Class AbstractResponseTimeMiddleware
* @package Tback\PrometheusExporter
*/
abstract class AbstractResponseTimeMiddleware
{
/**
* @var Request
*/
protected $request;

/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
$start = microtime(true);
$this->request = $request;

/** @var \Illuminate\Http\Response $response */
$response = $next($request);
$duration = microtime(true) - $start;

$label_keys = ['uri', 'request_method', 'status_code'];
$route_name = $this->getRouteName();

$label_values = [
$route_name,
$request->method(),
$response->status()
];

/** @var LpeManager $manager */
$manager = app('LpeManager');

// requests total
$manager->incCounter(
'requests_total',
'number of http requests',
config('prometheus_exporter.namespace_http_server'),
$label_keys,
$label_values
);

// request duration
$manager->incByCounter(
'requests_latency_milliseconds',
'duration of http_requests',
$duration * 1000.0,
config('prometheus_exporter.namespace_http_server'),
$label_keys,
$label_values
);

return $response;
}

/**
* Get route name
*
* @return string
*/
abstract protected function getRouteName();
}
19 changes: 19 additions & 0 deletions src/Middleware/LaravelResponseTimeMiddleware.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php
namespace Tback\PrometheusExporter\Middleware;

/**
* Class LaravelResponseTimeMiddleware
* @package Tback\PrometheusExporter\Middleware
*/
class LaravelResponseTimeMiddleware extends AbstractResponseTimeMiddleware
{
/**
* Get route name
*
* @return string
*/
protected function getRouteName()
{
return $this->request->route()->uri();
}
}
19 changes: 19 additions & 0 deletions src/Middleware/LumenResponseTimeMiddleware.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php
namespace Tback\PrometheusExporter\Middleware;

/**
* Class LumenResponseTimeMiddleware
* @package Tback\PrometheusExporter\Middleware
*/
class LumenResponseTimeMiddleware extends AbstractResponseTimeMiddleware
{
/**
* Get route name
*
* @return string
*/
protected function getRouteName()
{
return $this->request->route()[1]['uri'];
}
}
Loading