initial commit
This commit is contained in:
commit
bf1a4e1879
17 changed files with 822 additions and 0 deletions
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
.idea
|
||||
composer.lock
|
||||
vendor
|
||||
bin
|
||||
coverage
|
||||
coverage.xml
|
76
.styleci.yml
Normal file
76
.styleci.yml
Normal file
|
@ -0,0 +1,76 @@
|
|||
preset: psr2
|
||||
|
||||
enabled:
|
||||
- alpha_ordered_imports
|
||||
- binary_operator_spaces
|
||||
- blank_line_after_opening_tag
|
||||
- cast_spaces
|
||||
- concat_with_spaces
|
||||
- const_visibility_required
|
||||
- declare_equal_normalize
|
||||
- function_typehint_space
|
||||
- hash_to_slash_comment
|
||||
- heredoc_to_nowdoc
|
||||
- include
|
||||
- lowercase_cast
|
||||
- method_separation
|
||||
- native_function_casing
|
||||
- new_with_braces
|
||||
- no_blank_lines_after_class_opening
|
||||
- no_blank_lines_after_phpdoc
|
||||
- no_blank_lines_after_return
|
||||
- no_blank_lines_after_throw
|
||||
- no_blank_lines_between_imports
|
||||
- no_blank_lines_between_traits
|
||||
- no_empty_statement
|
||||
- no_extra_consecutive_blank_lines
|
||||
- no_leading_import_slash
|
||||
- no_leading_namespace_whitespace
|
||||
- no_multiline_whitespace_around_double_arrow
|
||||
- no_short_bool_cast
|
||||
- no_short_echo_tag
|
||||
- no_singleline_whitespace_before_semicolons
|
||||
- no_spaces_inside_offset
|
||||
- no_spaces_outside_offset
|
||||
- no_trailing_comma_in_list_call
|
||||
- no_trailing_comma_in_singleline_array
|
||||
- no_unneeded_control_parentheses
|
||||
- no_unreachable_default_argument_value
|
||||
- no_unused_imports
|
||||
- no_useless_return
|
||||
- no_whitespace_before_comma_in_array
|
||||
- no_whitespace_in_blank_line
|
||||
- normalize_index_brace
|
||||
- object_operator_without_whitespace
|
||||
- phpdoc_add_missing_param_annotation
|
||||
- phpdoc_indent
|
||||
- phpdoc_inline_tag
|
||||
- phpdoc_link_to_see
|
||||
- phpdoc_no_access
|
||||
- phpdoc_no_empty_return
|
||||
- phpdoc_no_package
|
||||
- phpdoc_order
|
||||
- phpdoc_property
|
||||
- phpdoc_scalar
|
||||
- phpdoc_separation
|
||||
- phpdoc_single_line_var_spacing
|
||||
- phpdoc_to_comment
|
||||
- phpdoc_trim
|
||||
- phpdoc_type_to_var
|
||||
- phpdoc_types
|
||||
- phpdoc_var_without_name
|
||||
- print_to_echo
|
||||
- self_accessor
|
||||
- short_array_syntax
|
||||
- short_scalar_cast
|
||||
- single_blank_line_before_namespace
|
||||
- single_quote
|
||||
- space_after_semicolon
|
||||
- standardize_not_equals
|
||||
- ternary_operator_spaces
|
||||
- trailing_comma_in_multiline_array
|
||||
- trim_array_spaces
|
||||
- unalign_double_arrow
|
||||
- unalign_equals
|
||||
- unary_operator_spaces
|
||||
- whitespace_after_comma_in_array
|
12
.travis.yml
Normal file
12
.travis.yml
Normal file
|
@ -0,0 +1,12 @@
|
|||
language: php
|
||||
|
||||
php:
|
||||
- 5.6
|
||||
- 7.0
|
||||
- 7.1
|
||||
- nightly
|
||||
|
||||
before_script:
|
||||
- composer install
|
||||
|
||||
script: ./vendor/bin/phpunit --configuration phpunit.xml
|
21
LICENSE
Normal file
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 Superbalist.com a division of Takealot Online (Pty) Ltd
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
65
README.md
Normal file
65
README.md
Normal file
|
@ -0,0 +1,65 @@
|
|||
# laravel-prometheus-exporter
|
||||
|
||||
A prometheus exporter for Laravel.
|
||||
|
||||
[![Author](http://img.shields.io/badge/author-@superbalist-blue.svg?style=flat-square)](https://twitter.com/superbalist)
|
||||
[![Build Status](https://img.shields.io/travis/Superbalist/laravel-prometheus-exporter/master.svg?style=flat-square)](https://travis-ci.org/Superbalist/laravel-prometheus-exporter)
|
||||
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE)
|
||||
[![Packagist Version](https://img.shields.io/packagist/v/superbalist/laravel-prometheus-exporter.svg?style=flat-square)](https://packagist.org/packages/superbalist/laravel-prometheus-exporter)
|
||||
[![Total Downloads](https://img.shields.io/packagist/dt/superbalist/laravel-prometheus-exporter.svg?style=flat-square)](https://packagist.org/packages/superbalist/laravel-prometheus-exporter)
|
||||
|
||||
This package is a wrapper bridging [jimdo/prometheus_client_php](https://github.com/Jimdo/prometheus_client_php) into Laravel.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
composer require superbalist/laravel-prometheus-exporter
|
||||
```
|
||||
|
||||
Register the service provider in app.php
|
||||
```php
|
||||
'providers' => [
|
||||
// ...
|
||||
Superbalist\LaravelPrometheusExporter\PrometheusServiceProvider::class,
|
||||
]
|
||||
```
|
||||
|
||||
Register the facade in app.php
|
||||
```php
|
||||
'aliases' => [
|
||||
// ...
|
||||
'PubSub' => Superbalist\LaravelPrometheusExporter\PrometheusFacade::class,
|
||||
]
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
The package has a default configuration which uses the following environment variables.
|
||||
```
|
||||
PROMETHEUS_NAMESPACE=app
|
||||
|
||||
PROMETHEUS_METRICS_ROUTE_ENABLED=true
|
||||
PROMETHEUS_METRICS_ROUTE_PATH=metrics
|
||||
PROMETHEUS_METRICS_ROUTE_MIDDLEWARE=null
|
||||
|
||||
PROMETHEUS_STORAGE_ADAPTER=memory
|
||||
|
||||
REDIS_HOST=localhost
|
||||
REDIS_PORT=6379
|
||||
PROMETHEUS_REDIS_PREFIX=PROMETHEUS_
|
||||
```
|
||||
|
||||
To customize the configuration file, publish the package configuration using Artisan.
|
||||
```bash
|
||||
php artisan vendor:publish --provider="Superbalist\LaravelPrometheusExporter\PrometheusServiceProvider"
|
||||
```
|
||||
|
||||
You can then edit the generated config at `app/config/prometheus.php`.
|
||||
|
||||
// TODO:
|
||||
|
||||
## Usage
|
||||
|
||||
```php
|
||||
// TODO:
|
||||
```
|
5
changelog.md
Normal file
5
changelog.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Changelog
|
||||
|
||||
## 1.0.0 - ?
|
||||
|
||||
* Initial release
|
32
composer.json
Normal file
32
composer.json
Normal file
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"name": "superbalist/laravel-prometheus-exporter",
|
||||
"description": "A prometheus exporter for Laravel",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Superbalist.com a division of Takealot Online (Pty) Ltd",
|
||||
"email": "info@superbalist.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.6.0",
|
||||
"illuminate/support": "^5.3",
|
||||
"illuminate/routing": "^5.3",
|
||||
"jimdo/prometheus_client_php": "^0.9.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Superbalist\\LaravelPrometheusExporter\\": "src/",
|
||||
"Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0-dev"
|
||||
}
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^5.5",
|
||||
"mockery/mockery": "^0.9.5"
|
||||
}
|
||||
}
|
107
config/prometheus.php
Normal file
107
config/prometheus.php
Normal file
|
@ -0,0 +1,107 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Namespace
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The namespace to use as a prefix for all metrics.
|
||||
|
|
||||
| This will typically be the name of your project, eg: 'search'.
|
||||
|
|
||||
*/
|
||||
|
||||
'namespace' => env('PROMETHEUS_NAMESPACE', 'app'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Metrics Route Enabled?
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| If enabled, a /metrics route will be registered to export prometheus
|
||||
| metrics.
|
||||
|
|
||||
*/
|
||||
|
||||
'metrics_route_enabled' => env('PROMETHEUS_METRICS_ROUTE_ENABLED', true),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Metrics Route Path
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The path at which prometheus metrics are exported.
|
||||
|
|
||||
| This is only applicable if metrics_route_enabled is set to true.
|
||||
|
|
||||
*/
|
||||
|
||||
'metrics_route_path' => env('PROMETHEUS_METRICS_ROUTE_PATH', 'metrics'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Metrics Route Middleware
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The middleware to assign to the metrics route.
|
||||
|
|
||||
| This can be used to protect the /metrics end-point to authenticated users,
|
||||
| a specific ip address, etc.
|
||||
| You are responsible for writing the middleware and implementing any
|
||||
| business logic needed by your application.
|
||||
|
|
||||
*/
|
||||
|
||||
'metrics_route_middleware' => env('PROMETHEUS_METRICS_ROUTE_MIDDLEWARE'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Storage Adapter
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The storage adapter to use.
|
||||
|
|
||||
| Supported: "memory", "redis", "apc"
|
||||
|
|
||||
*/
|
||||
|
||||
'storage_adapter' => env('PROMETHEUS_STORAGE_ADAPTER', 'memory'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Storage Adapters
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The storage adapter configs.
|
||||
|
|
||||
*/
|
||||
|
||||
'storage_adapters' => [
|
||||
|
||||
'redis' => [
|
||||
'host' => env('REDIS_HOST', 'localhost'),
|
||||
'port' => env('REDIS_PORT', 6379),
|
||||
'timeout' => 0.1,
|
||||
'read_timeout' => 10,
|
||||
'persistent_connections' => false,
|
||||
'prefix' => env('PROMETHEUS_REDIS_PREFIX', 'PROMETHEUS_'),
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Collectors
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The collectors specified here will be auto-registered in the exporter.
|
||||
|
|
||||
*/
|
||||
|
||||
'collectors' => [
|
||||
// \Your\ExporterClass::class,
|
||||
],
|
||||
|
||||
];
|
3
phpunit.php
Normal file
3
phpunit.php
Normal file
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
|
||||
include __DIR__ . '/vendor/autoload.php';
|
29
phpunit.xml
Normal file
29
phpunit.xml
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
bootstrap="./phpunit.php"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false"
|
||||
syntaxCheck="true"
|
||||
verbose="true"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="laravel-prometheus-exporter/tests">
|
||||
<directory suffix=".php">./tests/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory suffix=".php">./src/</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
<logging>
|
||||
<log type="coverage-text" target="php://stdout" showUncoveredFiles="true"/>
|
||||
<log type="coverage-html" target="coverage" showUncoveredFiles="true"/>
|
||||
<log type="coverage-clover" target="coverage.xml" showUncoveredFiles="true"/>
|
||||
</logging>
|
||||
</phpunit>
|
34
src/CollectorInterface.php
Normal file
34
src/CollectorInterface.php
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace Superbalist\LaravelPrometheusExporter;
|
||||
|
||||
interface CollectorInterface
|
||||
{
|
||||
/**
|
||||
* Return the name of the collector.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName();
|
||||
|
||||
/**
|
||||
* Register all metrics associated with the collector.
|
||||
*
|
||||
* The metrics needs to be registered on the exporter object.
|
||||
* eg:
|
||||
* ```php
|
||||
* $exporter->registerCounter('search_requests_total', 'The total number of search requests.');
|
||||
* ```
|
||||
*
|
||||
* @param PrometheusExporter $exporter
|
||||
*/
|
||||
public function registerMetrics(PrometheusExporter $exporter);
|
||||
|
||||
/**
|
||||
* Collect metrics data, if need be, before exporting.
|
||||
*
|
||||
* As an example, this may be used to perform time consuming database queries and set the value of a counter
|
||||
* or gauge.
|
||||
*/
|
||||
public function collect();
|
||||
}
|
41
src/MetricsController.php
Normal file
41
src/MetricsController.php
Normal file
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace Superbalist\LaravelPrometheusExporter;
|
||||
|
||||
use Illuminate\Routing\Controller;
|
||||
use Prometheus\RenderTextFormat;
|
||||
|
||||
class MetricsController extends Controller
|
||||
{
|
||||
/**
|
||||
* @var $prometheusExporter
|
||||
*/
|
||||
protected $prometheusExporter;
|
||||
|
||||
/**
|
||||
* @param PrometheusExporter $prometheusExporter
|
||||
*/
|
||||
public function __construct(PrometheusExporter $prometheusExporter)
|
||||
{
|
||||
$this->prometheusExporter = $prometheusExporter;
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /metrics
|
||||
*
|
||||
* The route path is configurable in the prometheus.metrics_route_path config var, or the
|
||||
* PROMETHEUS_METRICS_ROUTE_PATH env var.
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function getMetrics()
|
||||
{
|
||||
$metrics = $this->prometheusExporter->export();
|
||||
|
||||
$renderer = new RenderTextFormat();
|
||||
$result = $renderer->render($metrics);
|
||||
|
||||
return response($result)
|
||||
->header('Content-Type', RenderTextFormat::MIME_TYPE);
|
||||
}
|
||||
}
|
235
src/PrometheusExporter.php
Normal file
235
src/PrometheusExporter.php
Normal file
|
@ -0,0 +1,235 @@
|
|||
<?php
|
||||
|
||||
namespace Superbalist\LaravelPrometheusExporter;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Prometheus\CollectorRegistry;
|
||||
|
||||
class PrometheusExporter
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $namespace;
|
||||
|
||||
/**
|
||||
* @var CollectorRegistry
|
||||
*/
|
||||
protected $prometheus;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $collectors = [];
|
||||
|
||||
/**
|
||||
* @param string $namespace
|
||||
* @param CollectorRegistry $prometheus
|
||||
* @param array $collectors
|
||||
*/
|
||||
public function __construct($namespace, CollectorRegistry $prometheus, array $collectors = [])
|
||||
{
|
||||
$this->namespace = $namespace;
|
||||
$this->prometheus = $prometheus;
|
||||
|
||||
foreach ($collectors as $collector) {
|
||||
/** @var CollectorInterface $collector */
|
||||
$this->registerCollector($collector);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the metric namespace.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
return $this->namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the CollectorRegistry.
|
||||
*
|
||||
* @return CollectorRegistry
|
||||
*/
|
||||
public function getPrometheus()
|
||||
{
|
||||
return $this->prometheus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a collector.
|
||||
*
|
||||
* @param CollectorInterface $collector
|
||||
*/
|
||||
public function registerCollector(CollectorInterface $collector)
|
||||
{
|
||||
$name = $collector->getName();
|
||||
|
||||
if (!isset($this->collectors[$name])) {
|
||||
$this->collectors[$name] = $collector;
|
||||
|
||||
$collector->registerMetrics($this->prometheus);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all collectors.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCollectors()
|
||||
{
|
||||
return $this->collectors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a collector by name.
|
||||
*
|
||||
* @param string $name
|
||||
* @return CollectorInterface
|
||||
*/
|
||||
public function getCollector($name)
|
||||
{
|
||||
if (!isset($this->collectors[$name])) {
|
||||
throw new InvalidArgumentException(sprintf('The collector "%s" is not registered.', $name));
|
||||
}
|
||||
|
||||
return $this->collectors[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a counter.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $help
|
||||
* @param array $labels
|
||||
* @return \Prometheus\Counter
|
||||
* @see https://prometheus.io/docs/concepts/metric_types/#counter
|
||||
*/
|
||||
public function registerCounter($name, $help, $labels = [])
|
||||
{
|
||||
return $this->prometheus->registerCounter($this->namespace, $name, $help, $labels);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a counter.
|
||||
*
|
||||
* @param string $name
|
||||
* @return \Prometheus\Counter
|
||||
*/
|
||||
public function getCounter($name)
|
||||
{
|
||||
return $this->prometheus->getCounter($this->namespace, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return or register a counter.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $help
|
||||
* @param array $labels
|
||||
* @return \Prometheus\Counter
|
||||
* @see https://prometheus.io/docs/concepts/metric_types/#counter
|
||||
*/
|
||||
public function getOrRegisterCounter($name, $help, $labels = [])
|
||||
{
|
||||
return $this->prometheus->getOrRegisterCounter($this->namespace, $name, $help, $labels);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a gauge.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $help
|
||||
* @param array $labels
|
||||
* @return \Prometheus\Gauge
|
||||
* @see https://prometheus.io/docs/concepts/metric_types/#gauge
|
||||
*/
|
||||
public function registerGauge($name, $help, $labels = [])
|
||||
{
|
||||
return $this->prometheus->registerGauge($this->namespace, $name, $help, $labels);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a gauge.
|
||||
*
|
||||
* @param string $name
|
||||
* @return \Prometheus\Counter
|
||||
*/
|
||||
public function getGauge($name)
|
||||
{
|
||||
return $this->prometheus->getCounter($this->namespace, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return or register a gauge.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $help
|
||||
* @param array $labels
|
||||
* @return \Prometheus\Gauge
|
||||
* @see https://prometheus.io/docs/concepts/metric_types/#gauge
|
||||
*/
|
||||
public function getOrRegisterGauge($name, $help, $labels = [])
|
||||
{
|
||||
return $this->prometheus->getOrRegisterGauge($this->namespace, $name, $help, $labels);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a histogram.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $help
|
||||
* @param array $labels
|
||||
* @param array $buckets
|
||||
* @return \Prometheus\Histogram
|
||||
* @see https://prometheus.io/docs/concepts/metric_types/#histogram
|
||||
*/
|
||||
public function registerHistogram($name, $help, $labels = [], $buckets = null)
|
||||
{
|
||||
return $this->prometheus->registerHistogram($this->namespace, $name, $help, $labels, $buckets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a histogram.
|
||||
*
|
||||
* @param string $name
|
||||
* @return \Prometheus\Histogram
|
||||
*/
|
||||
public function getHistogram($name)
|
||||
{
|
||||
return $this->prometheus->getHistogram($this->namespace, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return or register a histogram.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $help
|
||||
* @param array $labels
|
||||
* @param array $buckets
|
||||
* @return \Prometheus\Histogram
|
||||
* @see https://prometheus.io/docs/concepts/metric_types/#histogram
|
||||
*/
|
||||
public function getOrRegisterHistogram($name, $help, $labels = [], $buckets = null)
|
||||
{
|
||||
return $this->prometheus->getOrRegisterHistogram($this->namespace, $name, $help, $labels, $buckets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Export the metrics from all collectors.
|
||||
*
|
||||
* @return \Prometheus\MetricFamilySamples[]
|
||||
*/
|
||||
public function export()
|
||||
{
|
||||
foreach ($this->collectors as $collector) {
|
||||
/** @var CollectorInterface $collector */
|
||||
$collector->collect();
|
||||
}
|
||||
|
||||
return $this->prometheus->getMetricFamilySamples();
|
||||
}
|
||||
}
|
18
src/PrometheusFacade.php
Normal file
18
src/PrometheusFacade.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace Superbalist\LaravelPrometheusExporter;
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
class PrometheusFacade extends Facade
|
||||
{
|
||||
/**
|
||||
* Get the registered name of the component.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeAccessor()
|
||||
{
|
||||
return 'prometheus';
|
||||
}
|
||||
}
|
72
src/PrometheusServiceProvider.php
Normal file
72
src/PrometheusServiceProvider.php
Normal file
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
namespace Superbalist\LaravelPrometheusExporter;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Prometheus\CollectorRegistry;
|
||||
use Prometheus\Storage\Adapter;
|
||||
|
||||
class PrometheusServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Perform post-registration booting of services.
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->publishes([
|
||||
__DIR__ . '/../config/prometheus.php' => config_path('prometheus.php'),
|
||||
]);
|
||||
|
||||
if (config('prometheus.metrics_route_enabled')) {
|
||||
$this->loadRoutesFrom(__DIR__ . '/routes.php');
|
||||
}
|
||||
|
||||
$exporter = $this->app->make(PrometheusExporter::class); /** @var PrometheusExporter $exporter */
|
||||
foreach (config('prometheus.collectors') as $class) {
|
||||
$collector = $this->app->make($class);
|
||||
$exporter->registerCollector($collector);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register bindings in the container.
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
$this->mergeConfigFrom(__DIR__ . '/../config/prometheus.php', 'prometheus');
|
||||
|
||||
$this->app->singleton(PrometheusExporter::class, function ($app) {
|
||||
$adapter = $app['prometheus.storage_adapter'];
|
||||
$prometheus = new CollectorRegistry($adapter);
|
||||
return new PrometheusExporter(config('prometheus.namespace'), $prometheus);
|
||||
});
|
||||
$this->app->alias(PrometheusExporter::class, 'prometheus');
|
||||
|
||||
$this->app->bind('prometheus.storage_adapter_factory', function ($app) {
|
||||
return new StorageAdapterFactory($app);
|
||||
});
|
||||
|
||||
$this->app->bind(Adapter::class, function ($app) {
|
||||
$factory = $app['prometheus.storage_adapter_factory']; /** @var StorageAdapterFactory $factory */
|
||||
$driver = config('prometheus.storage_adapter');
|
||||
$configs = config('storage_adapters');
|
||||
$config = array_get($configs, $driver, []);
|
||||
return $factory->make($driver, $config);
|
||||
});
|
||||
$this->app->alias(Adapter::class, 'prometheus.storage_adapter');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the services provided by the provider.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function provides()
|
||||
{
|
||||
return [
|
||||
'prometheus',
|
||||
'prometheus.storage_adapter_factory',
|
||||
'prometheus.storage_adapter',
|
||||
];
|
||||
}
|
||||
}
|
61
src/StorageAdapterFactory.php
Normal file
61
src/StorageAdapterFactory.php
Normal file
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
namespace Superbalist\LaravelPrometheusExporter;
|
||||
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
use InvalidArgumentException;
|
||||
use Prometheus\Storage\Adapter;
|
||||
use Prometheus\Storage\APC;
|
||||
use Prometheus\Storage\InMemory;
|
||||
use Prometheus\Storage\Redis;
|
||||
|
||||
class StorageAdapterFactory
|
||||
{
|
||||
/**
|
||||
* @var Container
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* @param Container $container
|
||||
*/
|
||||
public function __construct(Container $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory a storage adapter.
|
||||
*
|
||||
* @param string $driver
|
||||
* @param array $config
|
||||
* @return Adapter
|
||||
*/
|
||||
public function make($driver, array $config = [])
|
||||
{
|
||||
switch ($driver) {
|
||||
case 'memory':
|
||||
return new InMemory();
|
||||
case 'redis':
|
||||
return $this->makeRedisAdapter($config);
|
||||
case 'apc':
|
||||
return new APC();
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException(sprintf('The driver [%s] is not supported.', $driver));
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory a redis storage adapter.
|
||||
*
|
||||
* @param array $config
|
||||
* @return Redis
|
||||
*/
|
||||
protected function makeRedisAdapter(array $config)
|
||||
{
|
||||
if (isset($config['prefix'])) {
|
||||
Redis::setPrefix($config['prefix']);
|
||||
}
|
||||
return new Redis($config);
|
||||
}
|
||||
}
|
5
src/routes.php
Normal file
5
src/routes.php
Normal file
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
|
||||
Route::get(config('prometheus.metrics_route_path'), 'MetricsController@getMetrics')
|
||||
->middleware(config('prometheus.metrics_route_middleware'))
|
||||
->name('metrics');
|
Loading…
Reference in a new issue