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

Commit 3e1a9a0

Browse files
authored
Add MetricProducerManager to keep track of all MetricProducers (#253)
* Add MetricProducerManager to keep set of MetricProducer * fix review comments * fix review comments * Fix JSDoc and change copyright 2018 -> 2019 * Fix JSDoc comments
1 parent fed0ad4 commit 3e1a9a0

10 files changed

Lines changed: 289 additions & 18 deletions

File tree

packages/opencensus-core/src/metrics/export/metric-producer.ts renamed to packages/opencensus-core/src/metrics/export/base-metric-producer.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@
1414
* limitations under the License.
1515
*/
1616

17-
import {Metric} from './types';
17+
import {Metric, MetricProducer} from './types';
1818

1919
/**
2020
* A MetricProducer producer that can be registered for exporting using
2121
* MetricProducerManager.
2222
*/
23-
export abstract class MetricProducer {
23+
export abstract class BaseMetricProducer implements MetricProducer {
2424
/**
2525
* Gets a collection of produced Metric`s to be exported.
2626
* @returns {Metric[]} List of metrics
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/**
2+
* Copyright 2019, OpenCensus 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+
* http://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 {validateNotNull} from '../../common/validations';
18+
import {MetricProducer, MetricProducerManager} from './types';
19+
20+
/**
21+
* Keeps a set of MetricProducer that is used by exporters to determine the
22+
* metrics that need to be exported.
23+
*/
24+
class BaseMetricProducerManager implements MetricProducerManager {
25+
private metricProducers: Set<MetricProducer> = new Set<MetricProducer>();
26+
27+
/**
28+
* Adds the MetricProducer to the manager if it is not already present.
29+
*
30+
* @param {MetricProducer} The MetricProducer to be added to the manager.
31+
*/
32+
add(metricProducer: MetricProducer): void {
33+
validateNotNull(metricProducer, 'metricProducer');
34+
if (!this.metricProducers.has(metricProducer)) {
35+
this.metricProducers.add(metricProducer);
36+
}
37+
}
38+
39+
/**
40+
* Removes the MetricProducer to the manager if it is present.
41+
*
42+
* @param {MetricProducer} The MetricProducer to be removed from the manager.
43+
*/
44+
remove(metricProducer: MetricProducer): void {
45+
validateNotNull(metricProducer, 'metricProducer');
46+
this.metricProducers.delete(metricProducer);
47+
}
48+
49+
/**
50+
* Clears all MetricProducers.
51+
*/
52+
removeAll(): void {
53+
this.metricProducers.clear();
54+
}
55+
56+
/**
57+
* Returns all registered MetricProducers that should be exported.
58+
*
59+
* This method should be used by any metrics exporter that automatically
60+
* exports data for MetricProducer registered with the MetricProducerManager.
61+
*
62+
* @return {Set<MetricProducer>} The Set of MetricProducers.
63+
*/
64+
getAllMetricProducer(): Set<MetricProducer> {
65+
return this.metricProducers;
66+
}
67+
}
68+
69+
export const metricProducerManagerInstance = new BaseMetricProducerManager();

packages/opencensus-core/src/metrics/export/types.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,3 +326,27 @@ export interface Timestamp {
326326
*/
327327
nanos: number|null;
328328
}
329+
330+
/**
331+
* Keeps a set of MetricProducer that is used by exporters to determine the
332+
* metrics that need to be exported.
333+
*/
334+
export interface MetricProducerManager {
335+
/** Adds the MetricProducer to the manager */
336+
add(metricProducer: MetricProducer): void;
337+
/** Removes the MetricProducer to the manager */
338+
remove(metricProducer: MetricProducer): void;
339+
/** Clears all MetricProducers */
340+
removeAll(): void;
341+
/** Gets all registered MetricProducers that should be exported */
342+
getAllMetricProducer(): Set<MetricProducer>;
343+
}
344+
345+
/**
346+
* A MetricProducer producer that can be registered for exporting using
347+
* MetricProducerManager.
348+
*/
349+
export interface MetricProducer {
350+
/** Gets a collection of produced Metric`s to be exported */
351+
getMetrics(): Metric[];
352+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* Copyright 2019, OpenCensus 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+
* http://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 {metricProducerManagerInstance} from './export/metric-producer-manager';
18+
import {MetricRegistry} from './metric-registry';
19+
20+
/**
21+
* Class that holds the implementation instance for MetricRegistry.
22+
*/
23+
export class MetricsComponent {
24+
private metricRegistry: MetricRegistry;
25+
26+
constructor() {
27+
this.metricRegistry = new MetricRegistry();
28+
29+
// Register the MetricRegistry's MetricProducer to the global
30+
// MetricProducerManager.
31+
metricProducerManagerInstance.add(this.metricRegistry.getMetricProducer());
32+
}
33+
34+
/**
35+
* Returns the MetricRegistry.
36+
*
37+
* @return {MetricRegistry}.
38+
*/
39+
getMetricRegistry(): MetricRegistry {
40+
return this.metricRegistry;
41+
}
42+
}

packages/opencensus-core/src/metrics/metric-registry.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515
*/
1616

1717
import {validateArrayElementsNotNull, validateNotNull} from '../common/validations';
18-
import {MeasureUnit} from '../stats/types';
18+
import {MeasureUnit,} from '../stats/types';
1919

20-
import {MetricProducer} from './export/metric-producer';
21-
import {LabelKey, Metric, MetricDescriptorType} from './export/types';
20+
import {BaseMetricProducer} from './export/base-metric-producer';
21+
import {LabelKey, Metric, MetricDescriptorType, MetricProducer} from './export/types';
2222
import {DerivedGauge} from './gauges/derived-gauge';
2323
import {Gauge} from './gauges/gauge';
2424
import {Meter} from './gauges/types';
@@ -184,7 +184,7 @@ export class MetricRegistry {
184184
* MetricProducer that is used by exporters to determine the metrics that
185185
* need to be exported.
186186
*/
187-
class MetricProducerForRegistry extends MetricProducer {
187+
class MetricProducerForRegistry extends BaseMetricProducer {
188188
private registeredMetrics: Map<string, Meter>;
189189

190190
constructor(registeredMetrics: Map<string, Meter>) {

packages/opencensus-core/src/metrics/metrics.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,24 @@
1414
* limitations under the License.
1515
*/
1616

17+
import {metricProducerManagerInstance} from './export/metric-producer-manager';
18+
import {MetricProducerManager} from './export/types';
19+
import {MetricsComponent} from './metric-component';
1720
import {MetricRegistry} from './metric-registry';
1821

22+
/**
23+
* Class for accessing the default MetricsComponent.
24+
*/
1925
export class Metrics {
20-
private static readonly METRIC_REGISTRY = Metrics.newMetricRegistry();
26+
private static readonly METRIC_COMPONENT = new MetricsComponent();
2127

22-
/**
23-
* Returns the global MetricRegistry.
24-
*
25-
* @return {MetricRegistry}.
26-
*/
27-
static getMetricRegistry(): MetricRegistry {
28-
return Metrics.METRIC_REGISTRY;
28+
/** @return {MetricProducerManager} The global MetricProducerManager. */
29+
static getMetricProducerManager(): MetricProducerManager {
30+
return metricProducerManagerInstance;
2931
}
3032

31-
private static newMetricRegistry(): MetricRegistry {
32-
return new MetricRegistry();
33+
/** @return {MetricRegistry} The global MetricRegistry. */
34+
static getMetricRegistry(): MetricRegistry {
35+
return Metrics.METRIC_COMPONENT.getMetricRegistry();
3336
}
3437
}

packages/opencensus-core/src/stats/metric-producer.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
import {MetricProducer} from '../metrics/export/metric-producer';
17+
import {BaseMetricProducer} from '../metrics/export/base-metric-producer';
1818
import {Metric} from '../metrics/export/types';
1919

2020
import {Stats} from './stats';
@@ -23,7 +23,7 @@ import {Stats} from './stats';
2323
* A MetricProducer producer that can be registered for exporting using
2424
* MetricProducerManager.
2525
*/
26-
export class MetricProducerForStats extends MetricProducer {
26+
export class MetricProducerForStats extends BaseMetricProducer {
2727
private statsManager: Stats;
2828

2929
/**

packages/opencensus-core/src/stats/stats.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ export class Stats {
3636
*/
3737
constructor(logger = defaultLogger) {
3838
this.logger = logger.logger();
39+
40+
// TODO (mayurkale): Decide how to inject MetricProducerForStats.
41+
// It should be something like below, but looks like not the right place.
42+
43+
// Create a new MetricProducerForStats and register it to
44+
// MetricProducerManager when Stats is initialized.
45+
// const metricProducer: MetricProducer = new MetricProducerForStats(this);
46+
// Metrics.getMetricProducerManager().add(metricProducer);
3947
}
4048

4149
/**
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* Copyright 2019, OpenCensus 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+
* http://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 {metricProducerManagerInstance} from '../src/metrics/export/metric-producer-manager';
19+
import {MetricsComponent} from '../src/metrics/metric-component';
20+
import {MetricRegistry} from '../src/metrics/metric-registry';
21+
22+
describe('MetricsComponent()', () => {
23+
const metricsComponent: MetricsComponent = new MetricsComponent();
24+
25+
it('should return a MetricRegistry instance', () => {
26+
assert.ok(metricsComponent.getMetricRegistry() instanceof MetricRegistry);
27+
});
28+
29+
it('should register metricRegistry to MetricProducerManger', () => {
30+
assert.equal(metricProducerManagerInstance.getAllMetricProducer().size, 1);
31+
assert.ok(metricProducerManagerInstance.getAllMetricProducer().has(
32+
metricsComponent.getMetricRegistry().getMetricProducer()));
33+
});
34+
});
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/**
2+
* Copyright 2019, OpenCensus 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+
* http://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 {metricProducerManagerInstance} from '../src/metrics/export/metric-producer-manager';
19+
import {MetricRegistry} from '../src/metrics/metric-registry';
20+
21+
describe('MetricProducerManager()', () => {
22+
const registry: MetricRegistry = new MetricRegistry();
23+
const metricProducer = registry.getMetricProducer();
24+
const registryOther: MetricRegistry = new MetricRegistry();
25+
const metricProducerOther = registryOther.getMetricProducer();
26+
27+
beforeEach(() => {
28+
metricProducerManagerInstance.removeAll();
29+
});
30+
31+
describe('add()', () => {
32+
it('should throw an error when the metricproducer is null', () => {
33+
assert.throws(() => {
34+
metricProducerManagerInstance.add(null);
35+
}, /^Error: Missing mandatory metricProducer parameter$/);
36+
});
37+
38+
it('add metricproducer', () => {
39+
metricProducerManagerInstance.add(metricProducer);
40+
const metricProducerList =
41+
metricProducerManagerInstance.getAllMetricProducer();
42+
43+
assert.notDeepEqual(metricProducerList, null);
44+
assert.equal(metricProducerList.size, 1);
45+
});
46+
47+
it('should not add same metricproducer metricProducerManagerInstance',
48+
() => {
49+
metricProducerManagerInstance.add(metricProducer);
50+
metricProducerManagerInstance.add(metricProducer);
51+
metricProducerManagerInstance.add(metricProducer);
52+
const metricProducerList =
53+
metricProducerManagerInstance.getAllMetricProducer();
54+
55+
assert.equal(metricProducerList.size, 1);
56+
assert.ok(metricProducerList.has(metricProducer));
57+
});
58+
59+
it('should add different metricproducer metricProducerManagerInstance',
60+
() => {
61+
metricProducerManagerInstance.add(metricProducer);
62+
metricProducerManagerInstance.add(metricProducerOther);
63+
const metricProducerList =
64+
metricProducerManagerInstance.getAllMetricProducer();
65+
66+
assert.equal(metricProducerList.size, 2);
67+
assert.ok(metricProducerList.has(metricProducer));
68+
assert.ok(metricProducerList.has(metricProducerOther));
69+
});
70+
});
71+
72+
describe('remove()', () => {
73+
it('should throw an error when the metricproducer is null', () => {
74+
assert.throws(() => {
75+
metricProducerManagerInstance.add(null);
76+
}, /^Error: Missing mandatory metricProducer parameter$/);
77+
});
78+
79+
it('remove metricproducer', () => {
80+
metricProducerManagerInstance.add(metricProducer);
81+
82+
const metricProducerList =
83+
metricProducerManagerInstance.getAllMetricProducer();
84+
assert.equal(metricProducerList.size, 1);
85+
assert.ok(metricProducerList.has(metricProducer));
86+
87+
metricProducerManagerInstance.remove(metricProducer);
88+
assert.equal(metricProducerList.size, 0);
89+
});
90+
});
91+
});

0 commit comments

Comments
 (0)