Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
83.78% covered (warning)
83.78%
31 / 37
84.62% covered (warning)
84.62%
11 / 13
CRAP
0.00% covered (danger)
0.00%
0 / 1
MetricTrait
83.78% covered (warning)
83.78%
31 / 37
84.62% covered (warning)
84.62%
11 / 13
22.88
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getComponent
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSamples
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSampleCount
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSampleRate
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setSampleRate
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 getLabelKeys
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
2.06
 setLabel
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 setLabels
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 copyToStatsdAt
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 fresh
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 isHistogram
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2/**
3 * @license GPL-2.0-or-later
4 * @file
5 */
6
7declare( strict_types=1 );
8
9namespace Wikimedia\Stats\Metrics;
10
11use InvalidArgumentException;
12use Psr\Log\LoggerInterface;
13use Wikimedia\Stats\Exceptions\IllegalOperationException;
14
15/**
16 * Implementation code common to all metric types.
17 *
18 * @internal
19 * @since 1.43
20 */
21trait MetricTrait {
22
23    private BaseMetricInterface $baseMetric;
24    private LoggerInterface $logger;
25    private ?string $bucket = null;
26
27    /** @inheritDoc */
28    public function __construct( $baseMetric, $logger ) {
29        $this->baseMetric = $baseMetric;
30        $this->logger = $logger;
31    }
32
33    /** @inheritDoc */
34    public function getName(): string {
35        return $this->baseMetric->getName();
36    }
37
38    /** @inheritDoc */
39    public function getComponent(): string {
40        return $this->baseMetric->getComponent();
41    }
42
43    /** @inheritDoc */
44    public function getSamples(): array {
45        return $this->baseMetric->getSamples();
46    }
47
48    /** @inheritDoc */
49    public function getSampleCount(): int {
50        return $this->baseMetric->getSampleCount();
51    }
52
53    /** @inheritDoc */
54    public function getSampleRate(): float {
55        return $this->baseMetric->getSampleRate();
56    }
57
58    /** @inheritDoc */
59    public function setSampleRate( float $sampleRate ) {
60        try {
61            $this->baseMetric->setSampleRate( $sampleRate );
62        } catch ( IllegalOperationException | InvalidArgumentException $ex ) {
63            // Log the condition and give the caller something that will absorb calls.
64            trigger_error( "Stats: ({$this->getName()}{$ex->getMessage()}", E_USER_WARNING );
65            return new NullMetric;
66        }
67        return $this;
68    }
69
70    /** @inheritDoc */
71    public function getLabelKeys(): array {
72        $labelKeys = $this->baseMetric->getLabelKeys();
73        if ( $this->bucket ) {
74            $labelKeys[] = 'le';
75        }
76        return $labelKeys;
77    }
78
79    /** @inheritDoc */
80    public function setLabel( string $key, string $value ) {
81        if ( strcasecmp( $key, 'le' ) === 0 ) {
82            trigger_error( "Stats: ({$this->getName()}) 'le' cannot be used as a label key", E_USER_WARNING );
83            return new NullMetric();
84        }
85        try {
86            $this->baseMetric->addLabel( $key, $value );
87        } catch ( IllegalOperationException | InvalidArgumentException $ex ) {
88            // Log the condition and give the caller something that will absorb calls.
89            trigger_error( "Stats: ({$this->getName()}{$ex->getMessage()}", E_USER_WARNING );
90            return new NullMetric;
91        }
92        return $this;
93    }
94
95    /** @inheritDoc */
96    public function setLabels( array $labels ) {
97        foreach ( $labels as $key => $value ) {
98            $metric = $this->setLabel( $key, $value );
99            if ( $metric instanceof NullMetric ) {
100                return $metric;
101            }
102        }
103        return $this;
104    }
105
106    /** @inheritDoc */
107    public function copyToStatsdAt( $statsdNamespaces ) {
108        try {
109            $this->baseMetric->setStatsdNamespaces( $statsdNamespaces );
110        } catch ( InvalidArgumentException $ex ) {
111            // Log the condition and give the caller something that will absorb calls.
112            trigger_error( "Stats: ({$this->getName()}{$ex->getMessage()}", E_USER_WARNING );
113            return new NullMetric;
114        }
115        return $this;
116    }
117
118    /** @inheritDoc */
119    public function fresh(): self {
120        $this->baseMetric->clearLabels();
121        return $this;
122    }
123
124    /** @inheritDoc */
125    public function isHistogram(): bool {
126        return ( $this instanceof CounterMetric && $this->bucket !== null );
127    }
128}