Skip to content

Commit 818c061

Browse files
author
Christian Häusler
authored
Merge pull request #3 from bexiocom/histogram
Add Histogram type
2 parents 221c713 + 9375ff9 commit 818c061

17 files changed

+995
-132
lines changed

.codeclimate.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ engines:
1515
enabled: true
1616
config:
1717
languages:
18-
- php:
18+
php:
19+
mass_threshold: 50
1920

2021
ratings:
2122
paths:

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ by the [golang client](https://github.com/prometheus/client_golang).
1818

1919
## Features
2020

21-
- Counter and Gauge metric types.
21+
- Counter, Gauge and Histogram metric types.
2222
- Redis and in memory storage.
2323
- Rendering to text format.
2424

2525
## Missing features
2626

27-
- Histogram and Summary metric types.
27+
- Summary metric types.
2828
- Ability to submit metric samples to a PushGateway.
2929
- Storage utilising filesystem, Memcached and APC.
3030
- Rendering to Protocol buffer format

src/Action/Observe.php

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
/**
3+
* @file
4+
* Contains Bexio\PrometheusPHP\Action\Add.
5+
*/
6+
7+
namespace Bexio\PrometheusPHP\Action;
8+
9+
use Bexio\PrometheusPHP\Action;
10+
use Bexio\PrometheusPHP\StorageAdapter;
11+
use Bexio\PrometheusPHP\Type\Addable;
12+
use Bexio\PrometheusPHP\Type\Observable;
13+
14+
/**
15+
* Observe action.
16+
*
17+
* Observe the given number and updates the according bucket/quantile of the metric.
18+
*/
19+
class Observe implements Action
20+
{
21+
/**
22+
* @var Addable
23+
*/
24+
private $metric;
25+
26+
/**
27+
* @var float
28+
*/
29+
private $value;
30+
31+
/**
32+
* @param Observable $metric
33+
* @param float $value
34+
*
35+
* @return Observe
36+
*/
37+
public static function createFromValue(Observable $metric, $value)
38+
{
39+
return new Observe($metric, $value);
40+
}
41+
42+
/**
43+
* Constructor.
44+
*
45+
* @param Observable $metric
46+
* @param float $value
47+
*/
48+
private function __construct(Observable $metric, $value)
49+
{
50+
$this->metric = $metric;
51+
$this->value = $value;
52+
}
53+
54+
/**
55+
* {@inheritdoc}
56+
*/
57+
public function execute(StorageAdapter $storage)
58+
{
59+
$storage->observe($this->metric, $this->value);
60+
}
61+
}

src/Metric/Histogram.php

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
/**
3+
* @file
4+
* Contains Bexio\PrometheusPHP\Metric\Histogram.
5+
*/
6+
7+
namespace Bexio\PrometheusPHP\Metric;
8+
9+
use Bexio\PrometheusPHP\Action\Observe;
10+
use Bexio\PrometheusPHP\Metric;
11+
use Bexio\PrometheusPHP\Type\Observable;
12+
13+
/**
14+
* Histogram Metric
15+
*
16+
* A Histogram counts individual observations from an event or sample stream in configurable buckets. Similar to a
17+
* summary, it also provides a sum of observations and an observation count.
18+
*
19+
* On the Prometheus server, quantiles can be calculated from a Histogram using the histogram_quantile function in the
20+
* query language.
21+
*
22+
* Note that Histograms, in contrast to Summaries, can be aggregated with the Prometheus query language (see the
23+
* documentation for detailed procedures). However, Histograms require the user to pre-define suitable buckets, and
24+
* they are in general less accurate. The Observe method of a Histogram has a very low performance overhead in
25+
* comparison with the Observe method of a Summary.
26+
*/
27+
class Histogram extends Metric implements Observable
28+
{
29+
/**
30+
* @param string $name The metric name
31+
* @param string $help The help information for this metric.
32+
* @param float[] $buckets The buckets upper including bounds.
33+
* @param string $namespace (optional) The metric namespace.
34+
* @param string $subsystem (optional) The metric subsystem.
35+
* @param string[] $labels (optional) Key value pairs of static metric labels.
36+
*
37+
* @return Histogram
38+
*/
39+
public static function createFromValues(
40+
$name,
41+
$help,
42+
array $buckets = null,
43+
$namespace = null,
44+
$subsystem = null,
45+
array $labels = array()
46+
) {
47+
$options = new HistogramOptions($name, $help, $buckets, $namespace, $subsystem, $labels);
48+
49+
return new Histogram($options);
50+
}
51+
52+
/**
53+
* @param HistogramOptions $options
54+
*
55+
* @return Histogram
56+
*/
57+
public static function createFromOptions(HistogramOptions $options)
58+
{
59+
return new Histogram($options);
60+
}
61+
62+
/**
63+
* Observes a value.
64+
*
65+
* @param float $value
66+
*/
67+
public function observe($value)
68+
{
69+
$this->actions[] = Observe::createFromValue($this, $value);
70+
}
71+
72+
/**
73+
* The metric type identifier.
74+
*
75+
* @return string
76+
*/
77+
public function getType()
78+
{
79+
return 'histogram';
80+
}
81+
}

src/Metric/HistogramCollection.php

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
/**
3+
* @file
4+
* Contains Bexio\PrometheusPHP\Metric\HistogramCollection.
5+
*/
6+
7+
namespace Bexio\PrometheusPHP\Metric;
8+
9+
use Bexio\PrometheusPHP\MetricCollection;
10+
use Bexio\PrometheusPHP\MetricType;
11+
use Bexio\PrometheusPHP\MetricTypeCollection;
12+
use Bexio\PrometheusPHP\Options;
13+
14+
/**
15+
* Collection of Histogram metrics sharing the same set of labels.
16+
*/
17+
class HistogramCollection extends MetricCollection implements MetricTypeCollection
18+
{
19+
/**
20+
* @param string $name The metric name.
21+
* @param string $help The help information for this metric.
22+
* @param string[] $labelNames The names of the label set for this collection.
23+
* @param float[] $buckets The buckets upper including bounds.
24+
* @param string $namespace (optional) The metric namespace.
25+
* @param string $subsystem (optional) The metric subsystem.
26+
* @param string[] $labels (optional) Key value pairs of static metric labels.
27+
*
28+
* @return HistogramCollection
29+
*/
30+
public static function createFromValues(
31+
$name,
32+
$help,
33+
array $labelNames,
34+
array $buckets,
35+
$namespace = null,
36+
$subsystem = null,
37+
array $labels = array()
38+
) {
39+
$options = new HistogramOptions($name, $help, $buckets, $namespace, $subsystem, $labels);
40+
41+
return new HistogramCollection($options, $labelNames);
42+
}
43+
44+
/**
45+
* @param HistogramOptions $options
46+
* @param string[] $labels The names ot the label set for this collection.
47+
*
48+
* @return HistogramCollection
49+
*/
50+
public static function createFromOptions(HistogramOptions $options, array $labels)
51+
{
52+
return new HistogramCollection($options, $labels);
53+
}
54+
55+
/**
56+
* Metric factory.
57+
*
58+
* @param Options $options
59+
*
60+
* @return MetricType
61+
*/
62+
protected function createMetricFromOptions(Options $options)
63+
{
64+
return Histogram::createFromOptions($options);
65+
}
66+
67+
/**
68+
* The metric type identifier.
69+
*
70+
* @return string
71+
*/
72+
public function getType()
73+
{
74+
return 'histogram';
75+
}
76+
}

src/Metric/HistogramOptions.php

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
/**
3+
* @file
4+
* Contains Bexio\PrometheusPHP\Metric\HistogramOptions.
5+
*/
6+
7+
namespace Bexio\PrometheusPHP\Metric;
8+
9+
use Bexio\PrometheusPHP\Options;
10+
11+
/**
12+
* @see Options
13+
*/
14+
class HistogramOptions extends Options
15+
{
16+
/**
17+
* Bucket boundaries.
18+
*
19+
* Buckets defines the buckets into which observations are counted. Each element in the slice is the upper inclusive
20+
* bound of a bucket. There is no need to add a highest bucket with +Inf bound, it will be added implicitly.
21+
*
22+
* @var float[]
23+
*/
24+
private $buckets;
25+
26+
/**
27+
* {@inheritdoc}
28+
* @param float[] $buckets The upper including bucket boundaries.
29+
*/
30+
public function __construct(
31+
$name,
32+
$help,
33+
array $buckets = null,
34+
$namespace = null,
35+
$subsystem = null,
36+
$constantLabels = array()
37+
) {
38+
parent::__construct($name, $help, $namespace, $subsystem, $constantLabels);
39+
$buckets = null === $buckets ? $this->getDefaultBuckets() : $buckets;
40+
sort($buckets);
41+
$this->buckets = $buckets;
42+
}
43+
44+
/**
45+
* @return \float[]
46+
*/
47+
public function getBuckets()
48+
{
49+
return $this->buckets;
50+
}
51+
52+
/**
53+
* The default buckets.
54+
*
55+
* @return float[]
56+
*/
57+
public function getDefaultBuckets()
58+
{
59+
return array(0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10);
60+
}
61+
}

src/MetricCollection.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
abstract class MetricCollection implements MetricTypeCollection
1919
{
2020
/**
21-
* @var CounterOptions
21+
* @var Options
2222
*/
2323
protected $options;
2424
/**
@@ -33,10 +33,10 @@ abstract class MetricCollection implements MetricTypeCollection
3333
/**
3434
* Constructor.
3535
*
36-
* @param CounterOptions $options
36+
* @param Options $options
3737
* @param \string[] $labels
3838
*/
39-
protected function __construct(CounterOptions $options, array $labels)
39+
protected function __construct(Options $options, array $labels)
4040
{
4141
$this->options = $options;
4242
$this->labels = $labels;

src/Sample.php

+19-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
namespace Bexio\PrometheusPHP;
88

9+
use Bexio\PrometheusPHP\Metric\HistogramOptions;
10+
911
class Sample
1012
{
1113
/**
@@ -23,6 +25,18 @@ class Sample
2325
*/
2426
private $value;
2527

28+
/**
29+
* @param string $name
30+
* @param string[] $labels
31+
* @param float $value
32+
*
33+
* @return Sample
34+
*/
35+
public static function createFromValues($name, array $labels, $value)
36+
{
37+
return new Sample($name, $labels, $value);
38+
}
39+
2640
/**
2741
* @param Options $options
2842
* @param float $value
@@ -31,7 +45,11 @@ class Sample
3145
*/
3246
public static function createFromOptions(Options $options, $value)
3347
{
34-
return new Sample($options->getFullyQualifiedName(), $options->getLabels(), $value);
48+
$name = $options->getFullyQualifiedName();
49+
if ($options instanceof HistogramOptions && array_key_exists('le', $options->getLabels())) {
50+
$name .= '_bucket';
51+
}
52+
return new Sample($name, $options->getLabels(), $value);
3553
}
3654

3755
/**

0 commit comments

Comments
 (0)