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

Commit 3454bbb

Browse files
authored
Add metric registry and validations util (#203)
* Add metric registry * Add more tests for empty and undefined inputs * fix reviews
1 parent bf85a7b commit 3454bbb

File tree

3 files changed

+391
-0
lines changed

3 files changed

+391
-0
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/**
2+
* Copyright 2018, 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+
/**
18+
* Validates that an object reference passed as a parameter to the calling
19+
* method is not null.
20+
*
21+
* @param {T} reference An object reference.
22+
* @param {string} errorMessage The exception message to use if the check fails.
23+
* @returns {T} An object reference.
24+
*/
25+
export function validateNotNull<T>(reference: T, errorMessage: string): T {
26+
if (reference === null || reference === undefined) {
27+
throw new Error(`Missing mandatory ${errorMessage} parameter`);
28+
}
29+
return reference;
30+
}
31+
32+
/**
33+
* Validates that an array passed as a parameter doesn't contain null element.
34+
*
35+
* @param {T} list The argument list to check for null.
36+
* @param {string} errorMessage The exception message to use if the check fails.
37+
*/
38+
export function validateArrayElementsNotNull<T>(
39+
array: T[], errorMessage: string) {
40+
if (array.every(
41+
element => element !== null || typeof element !== 'undefined')) {
42+
throw new Error(`${errorMessage} elements should not be a NULL`);
43+
}
44+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/**
2+
* Copyright 2018, 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 {validateArrayElementsNotNull, validateNotNull} from '../common/validations';
18+
import {MeasureUnit} from '../stats/types';
19+
import {LabelKey} from './export/types';
20+
21+
/**
22+
* Creates and manages application's set of metrics.
23+
*/
24+
export class MetricRegistry {
25+
/**
26+
* Builds a new Int64 gauge to be added to the registry. This is more
27+
* convenient form when you want to manually increase and decrease values as
28+
* per your service requirements.
29+
*
30+
* @param {string} name The name of the metric.
31+
* @param {string} description The description of the metric.
32+
* @param {MeasureUnit} unit The unit of the metric.
33+
* @param {LabelKey[]} labelKeys The list of the label keys.
34+
*/
35+
addInt64Gauge(
36+
name: string, description: string, unit: MeasureUnit,
37+
labelKeys: LabelKey[]): void {
38+
validateNotNull(name, 'name');
39+
validateNotNull(description, 'description');
40+
validateNotNull(unit, 'unit');
41+
validateArrayElementsNotNull(
42+
validateNotNull(labelKeys, 'labelKeys'), 'labelKey');
43+
// TODO(mayurkale): Add Int64Gauge.
44+
}
45+
46+
/**
47+
* Builds a new double gauge to be added to the registry. This is more
48+
* convenient form when you want to manually increase and decrease values as
49+
* per your service requirements.
50+
*
51+
* @param {string} name The name of the metric.
52+
* @param {string} description The description of the metric.
53+
* @param {MeasureUnit} unit The unit of the metric.
54+
* @param {LabelKey[]} labelKeys The list of the label keys.
55+
*/
56+
addDoubleGauge(
57+
name: string, description: string, unit: MeasureUnit,
58+
labelKeys: LabelKey[]): void {
59+
validateNotNull(name, 'name');
60+
validateNotNull(description, 'description');
61+
validateNotNull(unit, 'unit');
62+
validateArrayElementsNotNull(
63+
validateNotNull(labelKeys, 'labelKeys'), 'labelKey');
64+
// TODO(mayurkale): Add DoubleGauge.
65+
}
66+
67+
/**
68+
* Builds a new derived Int64 gauge to be added to the registry. This is more
69+
* convenient form when you want to manually increase and decrease values as
70+
* per your service requirements.
71+
*
72+
* @param {string} name The name of the metric.
73+
* @param {string} description The description of the metric.
74+
* @param {MeasureUnit} unit The unit of the metric.
75+
* @param {LabelKey[]} labelKeys The list of the label keys.
76+
*/
77+
addDerivedInt64Gauge(
78+
name: string, description: string, unit: MeasureUnit,
79+
labelKeys: LabelKey[]): void {
80+
validateNotNull(name, 'name');
81+
validateNotNull(description, 'description');
82+
validateNotNull(unit, 'unit');
83+
validateArrayElementsNotNull(
84+
validateNotNull(labelKeys, 'labelKeys'), 'labelKey');
85+
// TODO(mayurkale): Add Derived Int64Gauge.
86+
}
87+
88+
/**
89+
* Builds a new derived double gauge to be added to the registry. This is more
90+
* convenient form when you want to manually increase and decrease values as
91+
* per your service requirements.
92+
*
93+
* @param {string} name The name of the metric.
94+
* @param {string} description The description of the metric.
95+
* @param {MeasureUnit} unit The unit of the metric.
96+
* @param {LabelKey[]} labelKeys The list of the label keys.
97+
*/
98+
addDerivedDoubleGauge(
99+
name: string, description: string, unit: MeasureUnit,
100+
labelKeys: LabelKey[]): void {
101+
validateNotNull(name, 'name');
102+
validateNotNull(description, 'description');
103+
validateNotNull(unit, 'unit');
104+
validateArrayElementsNotNull(
105+
validateNotNull(labelKeys, 'labelKeys'), 'labelKey');
106+
// TODO(mayurkale): Add Derived DoubleGauge.
107+
}
108+
}
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
/**
2+
* Copyright 2018, 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 {LabelKey} from '../src/metrics/export/types';
19+
import {MetricRegistry} from '../src/metrics/metric-registry';
20+
import {MeasureUnit} from '../src/stats/types';
21+
22+
const METRIC_NAME = 'metric-name';
23+
const METRIC_DESCRIPTION = 'metric-description';
24+
const UNIT = MeasureUnit.UNIT;
25+
const LABEL_KEYS: LabelKey[] = [{key: 'code', description: 'desc'}];
26+
const LABEL_KEYS_WITH_NULL: LabelKey[] =
27+
[{key: 'code', description: 'desc'}, null];
28+
29+
const registry = new MetricRegistry();
30+
31+
describe('addInt64Gauge', () => {
32+
it('should throw an error when the name is null', () => {
33+
assert.throws(() => {
34+
registry.addInt64Gauge(null, METRIC_DESCRIPTION, UNIT, LABEL_KEYS);
35+
}, /^Error: Missing mandatory name parameter$/);
36+
});
37+
it('should throw an error when the name is undefined', () => {
38+
assert.throws(() => {
39+
registry.addInt64Gauge(undefined, METRIC_DESCRIPTION, UNIT, LABEL_KEYS);
40+
}, /^Error: Missing mandatory name parameter$/);
41+
});
42+
it('should throw an error when the description is null', () => {
43+
assert.throws(() => {
44+
registry.addInt64Gauge(METRIC_NAME, null, UNIT, LABEL_KEYS);
45+
}, /^Error: Missing mandatory description parameter$/);
46+
});
47+
it('should throw an error when the description is undefined', () => {
48+
assert.throws(() => {
49+
registry.addInt64Gauge(METRIC_NAME, undefined, UNIT, LABEL_KEYS);
50+
}, /^Error: Missing mandatory description parameter$/);
51+
});
52+
it('should throw an error when the unit is null', () => {
53+
assert.throws(() => {
54+
registry.addInt64Gauge(METRIC_NAME, METRIC_DESCRIPTION, null, LABEL_KEYS);
55+
}, /^Error: Missing mandatory unit parameter$/);
56+
});
57+
it('should throw an error when the unit is undefined', () => {
58+
assert.throws(() => {
59+
registry.addInt64Gauge(
60+
METRIC_NAME, METRIC_DESCRIPTION, undefined, LABEL_KEYS);
61+
}, /^Error: Missing mandatory unit parameter$/);
62+
});
63+
it('should throw an error when the labelKeys is null', () => {
64+
assert.throws(() => {
65+
registry.addInt64Gauge(METRIC_NAME, METRIC_DESCRIPTION, UNIT, null);
66+
}, /^Error: Missing mandatory labelKeys parameter$/);
67+
});
68+
it('should throw an error when the labelKeys is undefined', () => {
69+
assert.throws(() => {
70+
registry.addInt64Gauge(METRIC_NAME, METRIC_DESCRIPTION, UNIT, undefined);
71+
}, /^Error: Missing mandatory labelKeys parameter$/);
72+
});
73+
it('should throw an error when the labelKey elements are NULL', () => {
74+
assert.throws(() => {
75+
registry.addInt64Gauge(
76+
METRIC_NAME, METRIC_DESCRIPTION, UNIT, LABEL_KEYS_WITH_NULL);
77+
}, /^Error: labelKey elements should not be a NULL$/);
78+
});
79+
});
80+
81+
describe('addDoubleGauge', () => {
82+
it('should throw an error when the name is null', () => {
83+
assert.throws(() => {
84+
registry.addDoubleGauge(null, METRIC_DESCRIPTION, UNIT, LABEL_KEYS);
85+
}, /^Error: Missing mandatory name parameter$/);
86+
});
87+
it('should throw an error when the name is undefined', () => {
88+
assert.throws(() => {
89+
registry.addDoubleGauge(undefined, METRIC_DESCRIPTION, UNIT, LABEL_KEYS);
90+
}, /^Error: Missing mandatory name parameter$/);
91+
});
92+
it('should throw an error when the description is null', () => {
93+
assert.throws(() => {
94+
registry.addDoubleGauge(METRIC_NAME, null, UNIT, LABEL_KEYS);
95+
}, /^Error: Missing mandatory description parameter$/);
96+
});
97+
it('should throw an error when the description is undefined', () => {
98+
assert.throws(() => {
99+
registry.addDoubleGauge(METRIC_NAME, undefined, UNIT, LABEL_KEYS);
100+
}, /^Error: Missing mandatory description parameter$/);
101+
});
102+
it('should throw an error when the unit is null', () => {
103+
assert.throws(() => {
104+
registry.addDoubleGauge(
105+
METRIC_NAME, METRIC_DESCRIPTION, null, LABEL_KEYS);
106+
}, /^Error: Missing mandatory unit parameter$/);
107+
});
108+
it('should throw an error when the unit is undefined', () => {
109+
assert.throws(() => {
110+
registry.addDoubleGauge(
111+
METRIC_NAME, METRIC_DESCRIPTION, undefined, LABEL_KEYS);
112+
}, /^Error: Missing mandatory unit parameter$/);
113+
});
114+
it('should throw an error when the labelKeys is null', () => {
115+
assert.throws(() => {
116+
registry.addDoubleGauge(METRIC_NAME, METRIC_DESCRIPTION, UNIT, null);
117+
}, /^Error: Missing mandatory labelKeys parameter$/);
118+
});
119+
it('should throw an error when the labelKeys is undefined', () => {
120+
assert.throws(() => {
121+
registry.addDoubleGauge(METRIC_NAME, METRIC_DESCRIPTION, UNIT, undefined);
122+
}, /^Error: Missing mandatory labelKeys parameter$/);
123+
});
124+
it('should throw an error when the labelKey elements are NULL', () => {
125+
assert.throws(() => {
126+
registry.addDoubleGauge(
127+
METRIC_NAME, METRIC_DESCRIPTION, UNIT, LABEL_KEYS_WITH_NULL);
128+
}, /^Error: labelKey elements should not be a NULL$/);
129+
});
130+
});
131+
132+
describe('addDerivedInt64Gauge', () => {
133+
it('should throw an error when the name is null', () => {
134+
assert.throws(() => {
135+
registry.addDerivedInt64Gauge(null, METRIC_DESCRIPTION, UNIT, LABEL_KEYS);
136+
}, /^Error: Missing mandatory name parameter$/);
137+
});
138+
it('should throw an error when the name is undefined', () => {
139+
assert.throws(() => {
140+
registry.addDerivedInt64Gauge(
141+
undefined, METRIC_DESCRIPTION, UNIT, LABEL_KEYS);
142+
}, /^Error: Missing mandatory name parameter$/);
143+
});
144+
it('should throw an error when the description is null', () => {
145+
assert.throws(() => {
146+
registry.addDerivedInt64Gauge(METRIC_NAME, null, UNIT, LABEL_KEYS);
147+
}, /^Error: Missing mandatory description parameter$/);
148+
});
149+
it('should throw an error when the description is undefined', () => {
150+
assert.throws(() => {
151+
registry.addDerivedInt64Gauge(METRIC_NAME, undefined, UNIT, LABEL_KEYS);
152+
}, /^Error: Missing mandatory description parameter$/);
153+
});
154+
it('should throw an error when the unit is null', () => {
155+
assert.throws(() => {
156+
registry.addDerivedInt64Gauge(
157+
METRIC_NAME, METRIC_DESCRIPTION, null, LABEL_KEYS);
158+
}, /^Error: Missing mandatory unit parameter$/);
159+
});
160+
it('should throw an error when the unit is undefined', () => {
161+
assert.throws(() => {
162+
registry.addDerivedInt64Gauge(
163+
METRIC_NAME, METRIC_DESCRIPTION, undefined, LABEL_KEYS);
164+
}, /^Error: Missing mandatory unit parameter$/);
165+
});
166+
it('should throw an error when the labelKeys is null', () => {
167+
assert.throws(() => {
168+
registry.addDerivedInt64Gauge(
169+
METRIC_NAME, METRIC_DESCRIPTION, UNIT, null);
170+
}, /^Error: Missing mandatory labelKeys parameter$/);
171+
});
172+
it('should throw an error when the labelKeys is undefined', () => {
173+
assert.throws(() => {
174+
registry.addDerivedInt64Gauge(
175+
METRIC_NAME, METRIC_DESCRIPTION, UNIT, undefined);
176+
}, /^Error: Missing mandatory labelKeys parameter$/);
177+
});
178+
it('should throw an error when the labelKey elements are NULL', () => {
179+
assert.throws(() => {
180+
registry.addDerivedInt64Gauge(
181+
METRIC_NAME, METRIC_DESCRIPTION, UNIT, LABEL_KEYS_WITH_NULL);
182+
}, /^Error: labelKey elements should not be a NULL$/);
183+
});
184+
});
185+
186+
describe('addDerivedDoubleGauge', () => {
187+
it('should throw an error when the name is null', () => {
188+
assert.throws(() => {
189+
registry.addDerivedDoubleGauge(
190+
null, METRIC_DESCRIPTION, UNIT, LABEL_KEYS);
191+
}, /^Error: Missing mandatory name parameter$/);
192+
});
193+
it('should throw an error when the name is undefined', () => {
194+
assert.throws(() => {
195+
registry.addDerivedDoubleGauge(
196+
undefined, METRIC_DESCRIPTION, UNIT, LABEL_KEYS);
197+
}, /^Error: Missing mandatory name parameter$/);
198+
});
199+
it('should throw an error when the description is null', () => {
200+
assert.throws(() => {
201+
registry.addDerivedDoubleGauge(METRIC_NAME, null, UNIT, LABEL_KEYS);
202+
}, /^Error: Missing mandatory description parameter$/);
203+
});
204+
it('should throw an error when the description is undefined', () => {
205+
assert.throws(() => {
206+
registry.addDerivedDoubleGauge(METRIC_NAME, undefined, UNIT, LABEL_KEYS);
207+
}, /^Error: Missing mandatory description parameter$/);
208+
});
209+
it('should throw an error when the unit is null', () => {
210+
assert.throws(() => {
211+
registry.addDerivedDoubleGauge(
212+
METRIC_NAME, METRIC_DESCRIPTION, null, LABEL_KEYS);
213+
}, /^Error: Missing mandatory unit parameter$/);
214+
});
215+
it('should throw an error when the unit is undefined', () => {
216+
assert.throws(() => {
217+
registry.addDerivedDoubleGauge(
218+
METRIC_NAME, METRIC_DESCRIPTION, undefined, LABEL_KEYS);
219+
}, /^Error: Missing mandatory unit parameter$/);
220+
});
221+
it('should throw an error when the labelKeys is null', () => {
222+
assert.throws(() => {
223+
registry.addDerivedDoubleGauge(
224+
METRIC_NAME, METRIC_DESCRIPTION, UNIT, null);
225+
}, /^Error: Missing mandatory labelKeys parameter$/);
226+
});
227+
it('should throw an error when the labelKeys is undefined', () => {
228+
assert.throws(() => {
229+
registry.addDerivedDoubleGauge(
230+
METRIC_NAME, METRIC_DESCRIPTION, UNIT, undefined);
231+
}, /^Error: Missing mandatory labelKeys parameter$/);
232+
});
233+
it('should throw an error when the labelKey elements are NULL', () => {
234+
assert.throws(() => {
235+
registry.addDerivedDoubleGauge(
236+
METRIC_NAME, METRIC_DESCRIPTION, UNIT, LABEL_KEYS_WITH_NULL);
237+
}, /^Error: labelKey elements should not be a NULL$/);
238+
});
239+
});

0 commit comments

Comments
 (0)