Skip to content

Commit a9df567

Browse files
authored
feat(metrics): adds NoopMeter implementation (open-telemetry#278)
* feat(metrics): adds NoopMeter implementation Resolves open-telemetry/opentelemetry-js#264 * yarn fix * rename test file * fix the build attempt 1 * respond to comments * fix the build part 2 * yarn fix
1 parent b58965c commit a9df567

File tree

3 files changed

+230
-0
lines changed

3 files changed

+230
-0
lines changed

packages/opentelemetry-core/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,4 @@ export * from './trace/sampler/ProbabilitySampler';
3232
export * from './trace/spancontext-utils';
3333
export * from './trace/TracerDelegate';
3434
export * from './trace/TraceState';
35+
export * from './metrics/NoopMeter';
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
/*!
2+
* Copyright 2019, OpenTelemetry Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import {
18+
CounterHandle,
19+
DistributedContext,
20+
GaugeHandle,
21+
Meter,
22+
Metric,
23+
MetricOptions,
24+
MeasureHandle,
25+
SpanContext,
26+
} from '@opentelemetry/types';
27+
28+
/**
29+
* NoopMeter is a noop implementation of the {@link Meter} interface. It reuses constant
30+
* NoopMetrics for all of its methods.
31+
*/
32+
export class NoopMeter implements Meter {
33+
constructor() {}
34+
35+
/**
36+
* Returns constant noop measure.
37+
* @param name the name of the metric.
38+
* @param [options] the metric options.
39+
*/
40+
createMeasure(name: string, options?: MetricOptions): Metric<MeasureHandle> {
41+
return NOOP_MEASURE_METRIC;
42+
}
43+
44+
/**
45+
* Returns a constant noop counter.
46+
* @param name the name of the metric.
47+
* @param [options] the metric options.
48+
*/
49+
createCounter(name: string, options?: MetricOptions): Metric<CounterHandle> {
50+
return NOOP_COUNTER_METRIC;
51+
}
52+
53+
/**
54+
* Returns a constant gauge metric.
55+
* @param name the name of the metric.
56+
* @param [options] the metric options.
57+
*/
58+
createGauge(name: string, options?: MetricOptions): Metric<GaugeHandle> {
59+
return NOOP_GAUGE_METRIC;
60+
}
61+
}
62+
63+
export class NoopMetric<T> implements Metric<T> {
64+
private readonly _handle: T;
65+
66+
constructor(handle: T) {
67+
this._handle = handle;
68+
}
69+
/**
70+
* Returns a Handle associated with specified label values.
71+
* It is recommended to keep a reference to the Handle instead of always
72+
* calling this method for every operations.
73+
* @param labelValues the list of label values.
74+
*/
75+
getHandle(labelValues: string[]): T {
76+
return this._handle;
77+
}
78+
79+
/**
80+
* Returns a Handle for a metric with all labels not set.
81+
*/
82+
getDefaultHandle(): T {
83+
return this._handle;
84+
}
85+
86+
/**
87+
* Removes the Handle from the metric, if it is present.
88+
* @param labelValues the list of label values.
89+
*/
90+
removeHandle(labelValues: string[]): void {
91+
return;
92+
}
93+
94+
/**
95+
* Clears all timeseries from the Metric.
96+
*/
97+
clear(): void {
98+
return;
99+
}
100+
101+
setCallback(fn: () => void): void {
102+
return;
103+
}
104+
}
105+
106+
export class NoopCounterHandle implements CounterHandle {
107+
add(value: number): void {
108+
return;
109+
}
110+
}
111+
112+
export class NoopGaugeHandle implements GaugeHandle {
113+
set(value: number): void {
114+
return;
115+
}
116+
}
117+
118+
export class NoopMeasureHandle implements MeasureHandle {
119+
record(
120+
value: number,
121+
distContext?: DistributedContext,
122+
spanContext?: SpanContext
123+
): void {
124+
return;
125+
}
126+
}
127+
128+
export const NOOP_GAUGE_HANDLE = new NoopGaugeHandle();
129+
export const NOOP_GAUGE_METRIC = new NoopMetric<GaugeHandle>(NOOP_GAUGE_HANDLE);
130+
131+
export const NOOP_COUNTER_HANDLE = new NoopCounterHandle();
132+
export const NOOP_COUNTER_METRIC = new NoopMetric<CounterHandle>(
133+
NOOP_COUNTER_HANDLE
134+
);
135+
136+
export const NOOP_MEASURE_HANDLE = new NoopMeasureHandle();
137+
export const NOOP_MEASURE_METRIC = new NoopMetric<MeasureHandle>(
138+
NOOP_MEASURE_HANDLE
139+
);
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*!
2+
* Copyright 2019, OpenTelemetry Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import * as assert from 'assert';
18+
import {
19+
NoopMeter,
20+
NOOP_GAUGE_HANDLE,
21+
NOOP_GAUGE_METRIC,
22+
NOOP_COUNTER_HANDLE,
23+
NOOP_COUNTER_METRIC,
24+
NOOP_MEASURE_HANDLE,
25+
NOOP_MEASURE_METRIC,
26+
} from '../../src/metrics/NoopMeter';
27+
28+
describe('NoopMeter', () => {
29+
it('should not crash', () => {
30+
const meter = new NoopMeter();
31+
const counter = meter.createCounter('some-name');
32+
// ensure NoopMetric does not crash.
33+
counter.setCallback(() => {
34+
assert.fail('callback occurred');
35+
});
36+
counter.getHandle(['val1', 'val2']).add(1);
37+
counter.getDefaultHandle().add(1);
38+
counter.removeHandle(['val1', 'val2']);
39+
40+
// ensure the correct noop const is returned
41+
assert.strictEqual(counter, NOOP_COUNTER_METRIC);
42+
assert.strictEqual(
43+
counter.getHandle(['val1', 'val2']),
44+
NOOP_COUNTER_HANDLE
45+
);
46+
assert.strictEqual(counter.getDefaultHandle(), NOOP_COUNTER_HANDLE);
47+
counter.clear();
48+
49+
const measure = meter.createMeasure('some-name');
50+
measure.getDefaultHandle().record(1);
51+
measure.getDefaultHandle().record(1, { key: { value: 'value' } });
52+
measure.getDefaultHandle().record(
53+
1,
54+
{ key: { value: 'value' } },
55+
{
56+
traceId: 'a3cda95b652f4a1592b449d5929fda1b',
57+
spanId: '5e0c63257de34c92',
58+
}
59+
);
60+
61+
// ensure the correct noop const is returned
62+
assert.strictEqual(measure, NOOP_MEASURE_METRIC);
63+
assert.strictEqual(measure.getDefaultHandle(), NOOP_MEASURE_HANDLE);
64+
assert.strictEqual(
65+
measure.getHandle(['val1', 'val2']),
66+
NOOP_MEASURE_HANDLE
67+
);
68+
69+
const gauge = meter.createGauge('some-name');
70+
gauge.getDefaultHandle().set(1);
71+
72+
// ensure the correct noop const is returned
73+
assert.strictEqual(gauge, NOOP_GAUGE_METRIC);
74+
assert.strictEqual(gauge.getDefaultHandle(), NOOP_GAUGE_HANDLE);
75+
assert.strictEqual(gauge.getHandle(['val1', 'val2']), NOOP_GAUGE_HANDLE);
76+
77+
const options = {
78+
component: 'tests',
79+
description: 'the testing package',
80+
labelKeys: ['key1', 'key2'],
81+
};
82+
83+
const measureWithOptions = meter.createMeasure('some-name', options);
84+
assert.strictEqual(measureWithOptions, NOOP_MEASURE_METRIC);
85+
const counterWithOptions = meter.createCounter('some-name', options);
86+
assert.strictEqual(counterWithOptions, NOOP_COUNTER_METRIC);
87+
const gaugeWithOptions = meter.createGauge('some-name', options);
88+
assert.strictEqual(gaugeWithOptions, NOOP_GAUGE_METRIC);
89+
});
90+
});

0 commit comments

Comments
 (0)