1
|
|
|
import metrics from '../metrics'; |
2
|
|
|
|
3
|
|
|
const metricsSpecs = [ |
4
|
|
|
{ |
5
|
|
|
name: 'serverRestart', |
6
|
|
|
type: 'counter', |
7
|
|
|
help: `the number of times server(node instance) restarted, an unexpected high number indicates crash loop`, |
8
|
|
|
}, |
9
|
|
|
{ |
10
|
|
|
name: 'dbConnect_timer', |
11
|
|
|
type: 'summary', |
12
|
|
|
help: `the time to create db connection to monitor upstream service health`, |
13
|
|
|
labelNames: ['envId'], |
14
|
|
|
}, |
15
|
|
|
{ |
16
|
|
|
name: 'dbConnect_error', |
17
|
|
|
type: 'counter', |
18
|
|
|
help: `the number of db connection errors`, |
19
|
|
|
labelNames: ['envId'], |
20
|
|
|
}, |
21
|
|
|
{ |
22
|
|
|
name: 'orderValue', |
23
|
|
|
type: 'histogram', |
24
|
|
|
help: 'price summary of shopping orders', |
25
|
|
|
buckets: [10, 100, 1000, 10000, 100000], |
26
|
|
|
labelNames: ['envId', 'length'], |
27
|
|
|
}, |
28
|
|
|
]; |
29
|
|
|
|
30
|
|
|
describe('metrics', () => { |
31
|
|
|
beforeEach(() => { |
32
|
|
|
metrics.load(metricsSpecs); |
33
|
|
|
}); |
34
|
|
|
|
35
|
|
|
afterEach(() => { |
36
|
|
|
metrics.reset(); |
37
|
|
|
}); |
38
|
|
|
|
39
|
|
|
it('is an object with the following methods', () => { |
40
|
|
|
expect(typeof metrics).toBe('object'); |
41
|
|
|
expect(metrics).toHaveProperty('load'); |
42
|
|
|
expect(metrics).toHaveProperty('add'); |
43
|
|
|
expect(metrics).toHaveProperty('find'); |
44
|
|
|
}); |
45
|
|
|
|
46
|
|
|
it('.load() can create a list of metrics unit', () => { |
47
|
|
|
metrics.reset(); |
48
|
|
|
metrics.load(metricsSpecs); |
49
|
|
|
const units = metrics.list(); |
50
|
|
|
expect(Object.keys(units)).toHaveLength(4); |
51
|
|
|
}); |
52
|
|
|
|
53
|
|
|
it('.load() throws an error if invalid metrics type was specified', () => { |
54
|
|
|
metrics.reset(); |
55
|
|
|
const invalidSpecs = [ |
56
|
|
|
{ |
57
|
|
|
name: 'someName', |
58
|
|
|
type: 'randomType', |
59
|
|
|
}, |
60
|
|
|
]; |
61
|
|
|
try { |
62
|
|
|
metrics.load(invalidSpecs); |
63
|
|
|
} catch (e) { |
64
|
|
|
expect(e).toBeDefined(); |
65
|
|
|
} |
66
|
|
|
}); |
67
|
|
|
|
68
|
|
|
it('.find() can find a metrics unit', () => { |
69
|
|
|
const dbConnectTimer = metrics.find({ action: 'dbConnect', type: 'timer' }); |
70
|
|
|
expect(dbConnectTimer).toBeDefined(); |
71
|
|
|
}); |
72
|
|
|
|
73
|
|
|
it('.find() throws an error if no unit found', () => { |
74
|
|
|
try { |
75
|
|
|
metrics.find({ action: 'dbConnect', type: 'invalid' }); |
76
|
|
|
} catch (e) { |
77
|
|
|
expect(e).toBeDefined(); |
78
|
|
|
} |
79
|
|
|
}); |
80
|
|
|
|
81
|
|
|
it('counter.count() with excessive labels', () => { |
82
|
|
|
const counter = metrics.find({ name: 'dbConnect_error' }); |
83
|
|
|
counter.count({ envId: 'test', foo: 'bar' }); |
84
|
|
|
counter.count({ envId: 'test', foo: 'bar' }, 2); |
85
|
|
|
expect(counter.value()).toBe(3); |
86
|
|
|
}); |
87
|
|
|
|
88
|
|
|
it('counter.value() to get the current total count with optional filter', () => { |
89
|
|
|
const counter = metrics.find({ name: 'dbConnect_error' }); |
90
|
|
|
expect(counter.value()).toBe(0); |
91
|
|
|
counter.count(); |
92
|
|
|
expect(counter.value()).toBe(1); |
93
|
|
|
counter.count({ envId: 'test' }); |
94
|
|
|
counter.count({ envId: 'prod' }); |
95
|
|
|
expect(counter.value({ envId: 'test' })).toBe(1); |
96
|
|
|
expect(counter.value({ envId: 'prod' })).toBe(1); |
97
|
|
|
}); |
98
|
|
|
|
99
|
|
|
it('counter.stats() to get distribution of all values of a label', () => { |
100
|
|
|
const counter = metrics.find({ name: 'dbConnect_error' }); |
101
|
|
|
expect(counter.value()).toBe(0); |
102
|
|
|
counter.count(); |
103
|
|
|
counter.count({ envId: 'test' }); |
104
|
|
|
counter.count({ envId: 'test' }); |
105
|
|
|
counter.count({ envId: 'prod' }); |
106
|
|
|
expect(counter.stats('envId')).toMatchSnapshot(); |
107
|
|
|
}); |
108
|
|
|
}); |
109
|
|
|
|