@oino-ts/common 0.20.2 → 0.21.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/OINOBenchmark.js +75 -8
- package/dist/esm/OINOBenchmark.js +75 -8
- package/dist/types/OINOBenchmark.d.ts +38 -7
- package/package.json +2 -2
- package/src/OINOBenchmark.ts +84 -10
|
@@ -13,6 +13,8 @@ exports.OINOMemoryBenchmark = exports.OINOBenchmark = void 0;
|
|
|
13
13
|
class OINOBenchmark {
|
|
14
14
|
static _instance;
|
|
15
15
|
static _enabled = {};
|
|
16
|
+
static _healthBenchmarks = [];
|
|
17
|
+
static _healthLateRatio = 0;
|
|
16
18
|
/**
|
|
17
19
|
* Create a new OINOBenchmark instance.
|
|
18
20
|
*
|
|
@@ -39,6 +41,44 @@ class OINOBenchmark {
|
|
|
39
41
|
static getInstance() {
|
|
40
42
|
return OINOBenchmark._instance;
|
|
41
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Add benchmark to be used for service health monitoring.
|
|
46
|
+
* @param module of the benchmark
|
|
47
|
+
* @param method of the benchmark
|
|
48
|
+
*/
|
|
49
|
+
static addHealthBenchmark(module, method) {
|
|
50
|
+
const name = module + "." + method;
|
|
51
|
+
if (!OINOBenchmark._healthBenchmarks.includes(name)) {
|
|
52
|
+
OINOBenchmark._healthBenchmarks.push(name);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Remove benchmark from being used for service health monitoring.
|
|
57
|
+
* @param module of the benchmark
|
|
58
|
+
* @param method of the benchmark
|
|
59
|
+
*/
|
|
60
|
+
static removeHealthBenchmark(module, method) {
|
|
61
|
+
const name = module + "." + method;
|
|
62
|
+
const index = OINOBenchmark._healthBenchmarks.indexOf(name);
|
|
63
|
+
if (index !== -1) {
|
|
64
|
+
OINOBenchmark._healthBenchmarks.splice(index, 1);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Set late ratio threshold for health monitoring. If a request takes this many times longer than the average duration, it is considered late and a health failure.
|
|
69
|
+
* @param lateRatio of health benchmarks, e.g. 2.0 means requests that take 2 times longer than the average
|
|
70
|
+
*/
|
|
71
|
+
static setHealthLateRatio(lateRatio) {
|
|
72
|
+
OINOBenchmark._healthLateRatio = lateRatio;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get service health based on the configured health benchmark.
|
|
76
|
+
*
|
|
77
|
+
* @returns service health as 0-1
|
|
78
|
+
*/
|
|
79
|
+
static getHealth() {
|
|
80
|
+
return OINOBenchmark._instance ? OINOBenchmark._instance._getHealth() : 1;
|
|
81
|
+
}
|
|
42
82
|
/**
|
|
43
83
|
* Reset benchmark data (but not what is enabled).
|
|
44
84
|
*
|
|
@@ -71,9 +111,10 @@ class OINOBenchmark {
|
|
|
71
111
|
*
|
|
72
112
|
* @param module of the benchmark
|
|
73
113
|
* @param method of the benchmark
|
|
114
|
+
* @param success indicates if the benchmark was successful
|
|
74
115
|
*/
|
|
75
|
-
static endMetric(module, method) {
|
|
76
|
-
OINOBenchmark._instance?._endMetric(module, method);
|
|
116
|
+
static endMetric(module, method, success = true) {
|
|
117
|
+
OINOBenchmark._instance?._endMetric(module, method, success);
|
|
77
118
|
}
|
|
78
119
|
/**
|
|
79
120
|
* Get given benchmark data.
|
|
@@ -98,11 +139,11 @@ class OINOBenchmark {
|
|
|
98
139
|
* @param module of the metric
|
|
99
140
|
* @param method of the metric
|
|
100
141
|
* @param value of the metric
|
|
101
|
-
*
|
|
142
|
+
* @param success indicates if the metric was successful
|
|
102
143
|
*/
|
|
103
|
-
static trackMetric(module, method, value) {
|
|
144
|
+
static trackMetric(module, method, value, success = true) {
|
|
104
145
|
if (OINOBenchmark._enabled[module]) {
|
|
105
|
-
OINOBenchmark._instance?._trackMetric(module, method, value);
|
|
146
|
+
OINOBenchmark._instance?._trackMetric(module, method, value, success);
|
|
106
147
|
}
|
|
107
148
|
}
|
|
108
149
|
/**
|
|
@@ -137,6 +178,8 @@ class OINOMemoryBenchmark extends OINOBenchmark {
|
|
|
137
178
|
_benchmarkCount = {};
|
|
138
179
|
_benchmarkData = {};
|
|
139
180
|
_benchmarkStart = {};
|
|
181
|
+
_healthRequests = 0;
|
|
182
|
+
_healthFailures = 0;
|
|
140
183
|
_exceptions = [];
|
|
141
184
|
/**
|
|
142
185
|
* Reset benchmark data (but not what is enabled).
|
|
@@ -145,6 +188,8 @@ class OINOMemoryBenchmark extends OINOBenchmark {
|
|
|
145
188
|
_reset() {
|
|
146
189
|
this._benchmarkData = {};
|
|
147
190
|
this._benchmarkCount = {};
|
|
191
|
+
this._healthRequests = 0;
|
|
192
|
+
this._healthFailures = 0;
|
|
148
193
|
}
|
|
149
194
|
/**
|
|
150
195
|
* Start benchmark timing.
|
|
@@ -163,14 +208,15 @@ class OINOMemoryBenchmark extends OINOBenchmark {
|
|
|
163
208
|
*
|
|
164
209
|
* @param module of the benchmark
|
|
165
210
|
* @param method of the benchmark
|
|
211
|
+
* @param success indicates if the benchmark was successful
|
|
166
212
|
*/
|
|
167
|
-
_endMetric(module, method) {
|
|
213
|
+
_endMetric(module, method, success = true) {
|
|
168
214
|
const name = module + "." + method;
|
|
169
215
|
let result = 0;
|
|
170
216
|
if (OINOBenchmark._enabled[module] && (this._benchmarkStart[name] > 0)) { // if benchmark is started, end it
|
|
171
217
|
const duration = performance.now() - this._benchmarkStart[name];
|
|
172
218
|
this._benchmarkStart[name] = 0;
|
|
173
|
-
this._trackMetric(module, method, duration);
|
|
219
|
+
this._trackMetric(module, method, duration, success);
|
|
174
220
|
}
|
|
175
221
|
return;
|
|
176
222
|
}
|
|
@@ -201,7 +247,7 @@ class OINOMemoryBenchmark extends OINOBenchmark {
|
|
|
201
247
|
}
|
|
202
248
|
return result;
|
|
203
249
|
}
|
|
204
|
-
_trackMetric(module, method, value) {
|
|
250
|
+
_trackMetric(module, method, value, success = true) {
|
|
205
251
|
const name = module + "." + method;
|
|
206
252
|
if (this._benchmarkCount[name] == undefined) {
|
|
207
253
|
this._benchmarkCount[name] = 1;
|
|
@@ -211,6 +257,19 @@ class OINOMemoryBenchmark extends OINOBenchmark {
|
|
|
211
257
|
this._benchmarkCount[name] += 1;
|
|
212
258
|
this._benchmarkData[name] += value;
|
|
213
259
|
}
|
|
260
|
+
if (OINOBenchmark._healthBenchmarks.includes(name)) {
|
|
261
|
+
// console.log(`Health benchmark ${name}: value=${value.toFixed(2)}ms, average=${(this._benchmarkData[name] / this._benchmarkCount[name]).toFixed(2)}ms, late=${late_ratio>=OINOBenchmark._healthLateRatio}, success=${success}`)
|
|
262
|
+
this._healthRequests += 1;
|
|
263
|
+
if (!success) {
|
|
264
|
+
this._healthFailures += 1;
|
|
265
|
+
}
|
|
266
|
+
else if (OINOBenchmark._healthLateRatio > 0) {
|
|
267
|
+
const late_ratio = value / (this._benchmarkData[name] / this._benchmarkCount[name]);
|
|
268
|
+
if ((late_ratio > OINOBenchmark._healthLateRatio)) {
|
|
269
|
+
this._healthFailures += 1;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
214
273
|
}
|
|
215
274
|
_trackException(module, method, name, message, stack) {
|
|
216
275
|
const exception = { module, method, name, message, stack, timestamp: Date.now() };
|
|
@@ -219,5 +278,13 @@ class OINOMemoryBenchmark extends OINOBenchmark {
|
|
|
219
278
|
_getExceptions() {
|
|
220
279
|
return this._exceptions;
|
|
221
280
|
}
|
|
281
|
+
_getHealth() {
|
|
282
|
+
if ((OINOBenchmark._healthBenchmarks.length == 0) || (this._healthRequests == 0)) {
|
|
283
|
+
return 1.0;
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
return (this._healthRequests - this._healthFailures) / this._healthRequests;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
222
289
|
}
|
|
223
290
|
exports.OINOMemoryBenchmark = OINOMemoryBenchmark;
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
export class OINOBenchmark {
|
|
11
11
|
static _instance;
|
|
12
12
|
static _enabled = {};
|
|
13
|
+
static _healthBenchmarks = [];
|
|
14
|
+
static _healthLateRatio = 0;
|
|
13
15
|
/**
|
|
14
16
|
* Create a new OINOBenchmark instance.
|
|
15
17
|
*
|
|
@@ -36,6 +38,44 @@ export class OINOBenchmark {
|
|
|
36
38
|
static getInstance() {
|
|
37
39
|
return OINOBenchmark._instance;
|
|
38
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Add benchmark to be used for service health monitoring.
|
|
43
|
+
* @param module of the benchmark
|
|
44
|
+
* @param method of the benchmark
|
|
45
|
+
*/
|
|
46
|
+
static addHealthBenchmark(module, method) {
|
|
47
|
+
const name = module + "." + method;
|
|
48
|
+
if (!OINOBenchmark._healthBenchmarks.includes(name)) {
|
|
49
|
+
OINOBenchmark._healthBenchmarks.push(name);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Remove benchmark from being used for service health monitoring.
|
|
54
|
+
* @param module of the benchmark
|
|
55
|
+
* @param method of the benchmark
|
|
56
|
+
*/
|
|
57
|
+
static removeHealthBenchmark(module, method) {
|
|
58
|
+
const name = module + "." + method;
|
|
59
|
+
const index = OINOBenchmark._healthBenchmarks.indexOf(name);
|
|
60
|
+
if (index !== -1) {
|
|
61
|
+
OINOBenchmark._healthBenchmarks.splice(index, 1);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Set late ratio threshold for health monitoring. If a request takes this many times longer than the average duration, it is considered late and a health failure.
|
|
66
|
+
* @param lateRatio of health benchmarks, e.g. 2.0 means requests that take 2 times longer than the average
|
|
67
|
+
*/
|
|
68
|
+
static setHealthLateRatio(lateRatio) {
|
|
69
|
+
OINOBenchmark._healthLateRatio = lateRatio;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Get service health based on the configured health benchmark.
|
|
73
|
+
*
|
|
74
|
+
* @returns service health as 0-1
|
|
75
|
+
*/
|
|
76
|
+
static getHealth() {
|
|
77
|
+
return OINOBenchmark._instance ? OINOBenchmark._instance._getHealth() : 1;
|
|
78
|
+
}
|
|
39
79
|
/**
|
|
40
80
|
* Reset benchmark data (but not what is enabled).
|
|
41
81
|
*
|
|
@@ -68,9 +108,10 @@ export class OINOBenchmark {
|
|
|
68
108
|
*
|
|
69
109
|
* @param module of the benchmark
|
|
70
110
|
* @param method of the benchmark
|
|
111
|
+
* @param success indicates if the benchmark was successful
|
|
71
112
|
*/
|
|
72
|
-
static endMetric(module, method) {
|
|
73
|
-
OINOBenchmark._instance?._endMetric(module, method);
|
|
113
|
+
static endMetric(module, method, success = true) {
|
|
114
|
+
OINOBenchmark._instance?._endMetric(module, method, success);
|
|
74
115
|
}
|
|
75
116
|
/**
|
|
76
117
|
* Get given benchmark data.
|
|
@@ -95,11 +136,11 @@ export class OINOBenchmark {
|
|
|
95
136
|
* @param module of the metric
|
|
96
137
|
* @param method of the metric
|
|
97
138
|
* @param value of the metric
|
|
98
|
-
*
|
|
139
|
+
* @param success indicates if the metric was successful
|
|
99
140
|
*/
|
|
100
|
-
static trackMetric(module, method, value) {
|
|
141
|
+
static trackMetric(module, method, value, success = true) {
|
|
101
142
|
if (OINOBenchmark._enabled[module]) {
|
|
102
|
-
OINOBenchmark._instance?._trackMetric(module, method, value);
|
|
143
|
+
OINOBenchmark._instance?._trackMetric(module, method, value, success);
|
|
103
144
|
}
|
|
104
145
|
}
|
|
105
146
|
/**
|
|
@@ -133,6 +174,8 @@ export class OINOMemoryBenchmark extends OINOBenchmark {
|
|
|
133
174
|
_benchmarkCount = {};
|
|
134
175
|
_benchmarkData = {};
|
|
135
176
|
_benchmarkStart = {};
|
|
177
|
+
_healthRequests = 0;
|
|
178
|
+
_healthFailures = 0;
|
|
136
179
|
_exceptions = [];
|
|
137
180
|
/**
|
|
138
181
|
* Reset benchmark data (but not what is enabled).
|
|
@@ -141,6 +184,8 @@ export class OINOMemoryBenchmark extends OINOBenchmark {
|
|
|
141
184
|
_reset() {
|
|
142
185
|
this._benchmarkData = {};
|
|
143
186
|
this._benchmarkCount = {};
|
|
187
|
+
this._healthRequests = 0;
|
|
188
|
+
this._healthFailures = 0;
|
|
144
189
|
}
|
|
145
190
|
/**
|
|
146
191
|
* Start benchmark timing.
|
|
@@ -159,14 +204,15 @@ export class OINOMemoryBenchmark extends OINOBenchmark {
|
|
|
159
204
|
*
|
|
160
205
|
* @param module of the benchmark
|
|
161
206
|
* @param method of the benchmark
|
|
207
|
+
* @param success indicates if the benchmark was successful
|
|
162
208
|
*/
|
|
163
|
-
_endMetric(module, method) {
|
|
209
|
+
_endMetric(module, method, success = true) {
|
|
164
210
|
const name = module + "." + method;
|
|
165
211
|
let result = 0;
|
|
166
212
|
if (OINOBenchmark._enabled[module] && (this._benchmarkStart[name] > 0)) { // if benchmark is started, end it
|
|
167
213
|
const duration = performance.now() - this._benchmarkStart[name];
|
|
168
214
|
this._benchmarkStart[name] = 0;
|
|
169
|
-
this._trackMetric(module, method, duration);
|
|
215
|
+
this._trackMetric(module, method, duration, success);
|
|
170
216
|
}
|
|
171
217
|
return;
|
|
172
218
|
}
|
|
@@ -197,7 +243,7 @@ export class OINOMemoryBenchmark extends OINOBenchmark {
|
|
|
197
243
|
}
|
|
198
244
|
return result;
|
|
199
245
|
}
|
|
200
|
-
_trackMetric(module, method, value) {
|
|
246
|
+
_trackMetric(module, method, value, success = true) {
|
|
201
247
|
const name = module + "." + method;
|
|
202
248
|
if (this._benchmarkCount[name] == undefined) {
|
|
203
249
|
this._benchmarkCount[name] = 1;
|
|
@@ -207,6 +253,19 @@ export class OINOMemoryBenchmark extends OINOBenchmark {
|
|
|
207
253
|
this._benchmarkCount[name] += 1;
|
|
208
254
|
this._benchmarkData[name] += value;
|
|
209
255
|
}
|
|
256
|
+
if (OINOBenchmark._healthBenchmarks.includes(name)) {
|
|
257
|
+
// console.log(`Health benchmark ${name}: value=${value.toFixed(2)}ms, average=${(this._benchmarkData[name] / this._benchmarkCount[name]).toFixed(2)}ms, late=${late_ratio>=OINOBenchmark._healthLateRatio}, success=${success}`)
|
|
258
|
+
this._healthRequests += 1;
|
|
259
|
+
if (!success) {
|
|
260
|
+
this._healthFailures += 1;
|
|
261
|
+
}
|
|
262
|
+
else if (OINOBenchmark._healthLateRatio > 0) {
|
|
263
|
+
const late_ratio = value / (this._benchmarkData[name] / this._benchmarkCount[name]);
|
|
264
|
+
if ((late_ratio > OINOBenchmark._healthLateRatio)) {
|
|
265
|
+
this._healthFailures += 1;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
210
269
|
}
|
|
211
270
|
_trackException(module, method, name, message, stack) {
|
|
212
271
|
const exception = { module, method, name, message, stack, timestamp: Date.now() };
|
|
@@ -215,4 +274,12 @@ export class OINOMemoryBenchmark extends OINOBenchmark {
|
|
|
215
274
|
_getExceptions() {
|
|
216
275
|
return this._exceptions;
|
|
217
276
|
}
|
|
277
|
+
_getHealth() {
|
|
278
|
+
if ((OINOBenchmark._healthBenchmarks.length == 0) || (this._healthRequests == 0)) {
|
|
279
|
+
return 1.0;
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
return (this._healthRequests - this._healthFailures) / this._healthRequests;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
218
285
|
}
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
export declare abstract class OINOBenchmark {
|
|
6
6
|
protected static _instance: OINOBenchmark;
|
|
7
7
|
protected static _enabled: Record<string, boolean>;
|
|
8
|
+
protected static _healthBenchmarks: string[];
|
|
9
|
+
protected static _healthLateRatio: number;
|
|
8
10
|
/**
|
|
9
11
|
* Create a new OINOBenchmark instance.
|
|
10
12
|
*
|
|
@@ -23,6 +25,30 @@ export declare abstract class OINOBenchmark {
|
|
|
23
25
|
*
|
|
24
26
|
*/
|
|
25
27
|
static getInstance(): OINOBenchmark;
|
|
28
|
+
/**
|
|
29
|
+
* Add benchmark to be used for service health monitoring.
|
|
30
|
+
* @param module of the benchmark
|
|
31
|
+
* @param method of the benchmark
|
|
32
|
+
*/
|
|
33
|
+
static addHealthBenchmark(module: string, method: string): void;
|
|
34
|
+
/**
|
|
35
|
+
* Remove benchmark from being used for service health monitoring.
|
|
36
|
+
* @param module of the benchmark
|
|
37
|
+
* @param method of the benchmark
|
|
38
|
+
*/
|
|
39
|
+
static removeHealthBenchmark(module: string, method: string): void;
|
|
40
|
+
/**
|
|
41
|
+
* Set late ratio threshold for health monitoring. If a request takes this many times longer than the average duration, it is considered late and a health failure.
|
|
42
|
+
* @param lateRatio of health benchmarks, e.g. 2.0 means requests that take 2 times longer than the average
|
|
43
|
+
*/
|
|
44
|
+
static setHealthLateRatio(lateRatio: number): void;
|
|
45
|
+
/**
|
|
46
|
+
* Get service health based on the configured health benchmark.
|
|
47
|
+
*
|
|
48
|
+
* @returns service health as 0-1
|
|
49
|
+
*/
|
|
50
|
+
static getHealth(): number;
|
|
51
|
+
protected abstract _getHealth(): number;
|
|
26
52
|
protected abstract _reset(): void;
|
|
27
53
|
/**
|
|
28
54
|
* Reset benchmark data (but not what is enabled).
|
|
@@ -43,14 +69,15 @@ export declare abstract class OINOBenchmark {
|
|
|
43
69
|
* @param method of the benchmark
|
|
44
70
|
*/
|
|
45
71
|
static startMetric(module: string, method: string): void;
|
|
46
|
-
protected abstract _endMetric(module: string, method: string): void;
|
|
72
|
+
protected abstract _endMetric(module: string, method: string, success: boolean): void;
|
|
47
73
|
/**
|
|
48
74
|
* Complete benchmark timing
|
|
49
75
|
*
|
|
50
76
|
* @param module of the benchmark
|
|
51
77
|
* @param method of the benchmark
|
|
78
|
+
* @param success indicates if the benchmark was successful
|
|
52
79
|
*/
|
|
53
|
-
static endMetric(module: string, method: string): void;
|
|
80
|
+
static endMetric(module: string, method: string, success?: boolean): void;
|
|
54
81
|
protected abstract _getMetric(module: string, method: string): number;
|
|
55
82
|
/**
|
|
56
83
|
* Get given benchmark data.
|
|
@@ -66,16 +93,16 @@ export declare abstract class OINOBenchmark {
|
|
|
66
93
|
*
|
|
67
94
|
*/
|
|
68
95
|
static getMetrics(): Record<string, number>;
|
|
69
|
-
protected abstract _trackMetric(module: string, method: string, value: number): void;
|
|
96
|
+
protected abstract _trackMetric(module: string, method: string, value: number, success: boolean): void;
|
|
70
97
|
/**
|
|
71
98
|
* Track a metric value
|
|
72
99
|
*
|
|
73
100
|
* @param module of the metric
|
|
74
101
|
* @param method of the metric
|
|
75
102
|
* @param value of the metric
|
|
76
|
-
*
|
|
103
|
+
* @param success indicates if the metric was successful
|
|
77
104
|
*/
|
|
78
|
-
static trackMetric(module: string, method: string, value: number): void;
|
|
105
|
+
static trackMetric(module: string, method: string, value: number, success?: boolean): void;
|
|
79
106
|
protected abstract _trackException(module: string, method: string, name: string, message: string, stack: string): void;
|
|
80
107
|
/**
|
|
81
108
|
* Track an exception
|
|
@@ -103,6 +130,8 @@ export declare class OINOMemoryBenchmark extends OINOBenchmark {
|
|
|
103
130
|
protected _benchmarkCount: Record<string, number>;
|
|
104
131
|
protected _benchmarkData: Record<string, number>;
|
|
105
132
|
protected _benchmarkStart: Record<string, number>;
|
|
133
|
+
protected _healthRequests: number;
|
|
134
|
+
protected _healthFailures: number;
|
|
106
135
|
protected _exceptions: any[];
|
|
107
136
|
/**
|
|
108
137
|
* Reset benchmark data (but not what is enabled).
|
|
@@ -121,8 +150,9 @@ export declare class OINOMemoryBenchmark extends OINOBenchmark {
|
|
|
121
150
|
*
|
|
122
151
|
* @param module of the benchmark
|
|
123
152
|
* @param method of the benchmark
|
|
153
|
+
* @param success indicates if the benchmark was successful
|
|
124
154
|
*/
|
|
125
|
-
protected _endMetric(module: string, method: string): void;
|
|
155
|
+
protected _endMetric(module: string, method: string, success?: boolean): void;
|
|
126
156
|
/**
|
|
127
157
|
* Get given benchmark data.
|
|
128
158
|
*
|
|
@@ -136,7 +166,8 @@ export declare class OINOMemoryBenchmark extends OINOBenchmark {
|
|
|
136
166
|
*
|
|
137
167
|
*/
|
|
138
168
|
protected _getMetrics(): Record<string, number>;
|
|
139
|
-
protected _trackMetric(module: string, method: string, value: number): void;
|
|
169
|
+
protected _trackMetric(module: string, method: string, value: number, success?: boolean): void;
|
|
140
170
|
protected _trackException(module: string, method: string, name: string, message: string, stack: string): void;
|
|
141
171
|
protected _getExceptions(): any[];
|
|
172
|
+
protected _getHealth(): number;
|
|
142
173
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oino-ts/common",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.1",
|
|
4
4
|
"description": "OINO TS package for common classes.",
|
|
5
5
|
"author": "Matias Kiviniemi (pragmatta)",
|
|
6
6
|
"license": "MPL-2.0",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"dependencies": {
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"@oino-ts/types": "0.
|
|
22
|
+
"@oino-ts/types": "0.21.1",
|
|
23
23
|
"@types/node": "^22.0.0",
|
|
24
24
|
"typescript": "~5.9.0"
|
|
25
25
|
},
|
package/src/OINOBenchmark.ts
CHANGED
|
@@ -12,6 +12,8 @@ export abstract class OINOBenchmark {
|
|
|
12
12
|
|
|
13
13
|
protected static _instance:OINOBenchmark
|
|
14
14
|
protected static _enabled:Record<string, boolean> = {}
|
|
15
|
+
protected static _healthBenchmarks: string[] = []
|
|
16
|
+
protected static _healthLateRatio: number = 0
|
|
15
17
|
|
|
16
18
|
/**
|
|
17
19
|
* Create a new OINOBenchmark instance.
|
|
@@ -42,6 +44,50 @@ export abstract class OINOBenchmark {
|
|
|
42
44
|
return OINOBenchmark._instance
|
|
43
45
|
}
|
|
44
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Add benchmark to be used for service health monitoring.
|
|
49
|
+
* @param module of the benchmark
|
|
50
|
+
* @param method of the benchmark
|
|
51
|
+
*/
|
|
52
|
+
static addHealthBenchmark(module: string, method: string): void {
|
|
53
|
+
const name = module + "." + method
|
|
54
|
+
if (!OINOBenchmark._healthBenchmarks.includes(name)) {
|
|
55
|
+
OINOBenchmark._healthBenchmarks.push(name)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Remove benchmark from being used for service health monitoring.
|
|
61
|
+
* @param module of the benchmark
|
|
62
|
+
* @param method of the benchmark
|
|
63
|
+
*/
|
|
64
|
+
static removeHealthBenchmark(module: string, method: string): void {
|
|
65
|
+
const name = module + "." + method
|
|
66
|
+
const index = OINOBenchmark._healthBenchmarks.indexOf(name)
|
|
67
|
+
if (index !== -1) {
|
|
68
|
+
OINOBenchmark._healthBenchmarks.splice(index, 1)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Set late ratio threshold for health monitoring. If a request takes this many times longer than the average duration, it is considered late and a health failure.
|
|
74
|
+
* @param lateRatio of health benchmarks, e.g. 2.0 means requests that take 2 times longer than the average
|
|
75
|
+
*/
|
|
76
|
+
static setHealthLateRatio(lateRatio: number): void {
|
|
77
|
+
OINOBenchmark._healthLateRatio = lateRatio
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Get service health based on the configured health benchmark.
|
|
82
|
+
*
|
|
83
|
+
* @returns service health as 0-1
|
|
84
|
+
*/
|
|
85
|
+
static getHealth(): number {
|
|
86
|
+
return OINOBenchmark._instance? OINOBenchmark._instance._getHealth() : 1
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
protected abstract _getHealth(): number
|
|
90
|
+
|
|
45
91
|
protected abstract _reset():void
|
|
46
92
|
/**
|
|
47
93
|
* Reset benchmark data (but not what is enabled).
|
|
@@ -74,15 +120,16 @@ export abstract class OINOBenchmark {
|
|
|
74
120
|
OINOBenchmark._instance?._startMetric(module, method)
|
|
75
121
|
}
|
|
76
122
|
|
|
77
|
-
protected abstract _endMetric(module:string, method:string):void
|
|
123
|
+
protected abstract _endMetric(module:string, method:string, success:boolean):void
|
|
78
124
|
/**
|
|
79
125
|
* Complete benchmark timing
|
|
80
126
|
*
|
|
81
127
|
* @param module of the benchmark
|
|
82
128
|
* @param method of the benchmark
|
|
129
|
+
* @param success indicates if the benchmark was successful
|
|
83
130
|
*/
|
|
84
|
-
static endMetric(module:string, method:string):void {
|
|
85
|
-
OINOBenchmark._instance?._endMetric(module, method)
|
|
131
|
+
static endMetric(module:string, method:string, success:boolean = true):void {
|
|
132
|
+
OINOBenchmark._instance?._endMetric(module, method, success)
|
|
86
133
|
}
|
|
87
134
|
|
|
88
135
|
protected abstract _getMetric(module:string, method:string):number
|
|
@@ -106,18 +153,18 @@ export abstract class OINOBenchmark {
|
|
|
106
153
|
return OINOBenchmark._instance?._getMetrics()
|
|
107
154
|
}
|
|
108
155
|
|
|
109
|
-
protected abstract _trackMetric(module:string, method:string, value:number):void
|
|
156
|
+
protected abstract _trackMetric(module:string, method:string, value:number, success:boolean):void
|
|
110
157
|
/**
|
|
111
158
|
* Track a metric value
|
|
112
159
|
*
|
|
113
160
|
* @param module of the metric
|
|
114
161
|
* @param method of the metric
|
|
115
162
|
* @param value of the metric
|
|
116
|
-
*
|
|
163
|
+
* @param success indicates if the metric was successful
|
|
117
164
|
*/
|
|
118
|
-
static trackMetric(module:string, method:string, value:number):void {
|
|
165
|
+
static trackMetric(module:string, method:string, value:number, success:boolean = true):void {
|
|
119
166
|
if (OINOBenchmark._enabled[module]) {
|
|
120
|
-
OINOBenchmark._instance?._trackMetric(module, method, value)
|
|
167
|
+
OINOBenchmark._instance?._trackMetric(module, method, value, success)
|
|
121
168
|
}
|
|
122
169
|
}
|
|
123
170
|
|
|
@@ -157,6 +204,8 @@ export class OINOMemoryBenchmark extends OINOBenchmark {
|
|
|
157
204
|
protected _benchmarkCount:Record<string, number> = {}
|
|
158
205
|
protected _benchmarkData:Record<string, number> = {}
|
|
159
206
|
protected _benchmarkStart:Record<string, number> = {}
|
|
207
|
+
protected _healthRequests: number = 0
|
|
208
|
+
protected _healthFailures: number = 0
|
|
160
209
|
|
|
161
210
|
protected _exceptions:any[] = []
|
|
162
211
|
|
|
@@ -167,6 +216,8 @@ export class OINOMemoryBenchmark extends OINOBenchmark {
|
|
|
167
216
|
protected _reset():void {
|
|
168
217
|
this._benchmarkData = {}
|
|
169
218
|
this._benchmarkCount = {}
|
|
219
|
+
this._healthRequests = 0
|
|
220
|
+
this._healthFailures = 0
|
|
170
221
|
}
|
|
171
222
|
|
|
172
223
|
/**
|
|
@@ -187,14 +238,15 @@ export class OINOMemoryBenchmark extends OINOBenchmark {
|
|
|
187
238
|
*
|
|
188
239
|
* @param module of the benchmark
|
|
189
240
|
* @param method of the benchmark
|
|
241
|
+
* @param success indicates if the benchmark was successful
|
|
190
242
|
*/
|
|
191
|
-
protected _endMetric(module:string, method:string):void {
|
|
243
|
+
protected _endMetric(module:string, method:string, success:boolean = true):void {
|
|
192
244
|
const name:string = module + "." + method
|
|
193
245
|
let result:number = 0
|
|
194
246
|
if (OINOBenchmark._enabled[module] && (this._benchmarkStart[name] > 0)) { // if benchmark is started, end it
|
|
195
247
|
const duration = performance.now() - this._benchmarkStart[name]
|
|
196
248
|
this._benchmarkStart[name] = 0
|
|
197
|
-
this._trackMetric(module, method, duration)
|
|
249
|
+
this._trackMetric(module, method, duration, success)
|
|
198
250
|
}
|
|
199
251
|
return
|
|
200
252
|
}
|
|
@@ -228,7 +280,7 @@ export class OINOMemoryBenchmark extends OINOBenchmark {
|
|
|
228
280
|
return result
|
|
229
281
|
}
|
|
230
282
|
|
|
231
|
-
protected _trackMetric(module:string, method:string, value:number):void {
|
|
283
|
+
protected _trackMetric(module:string, method:string, value:number, success:boolean = true):void {
|
|
232
284
|
const name:string = module + "." + method
|
|
233
285
|
if (this._benchmarkCount[name] == undefined) {
|
|
234
286
|
this._benchmarkCount[name] = 1
|
|
@@ -237,6 +289,19 @@ export class OINOMemoryBenchmark extends OINOBenchmark {
|
|
|
237
289
|
this._benchmarkCount[name] += 1
|
|
238
290
|
this._benchmarkData[name] += value
|
|
239
291
|
}
|
|
292
|
+
if (OINOBenchmark._healthBenchmarks.includes(name)) {
|
|
293
|
+
// console.log(`Health benchmark ${name}: value=${value.toFixed(2)}ms, average=${(this._benchmarkData[name] / this._benchmarkCount[name]).toFixed(2)}ms, late=${late_ratio>=OINOBenchmark._healthLateRatio}, success=${success}`)
|
|
294
|
+
this._healthRequests += 1
|
|
295
|
+
if (!success) {
|
|
296
|
+
this._healthFailures += 1
|
|
297
|
+
|
|
298
|
+
} else if (OINOBenchmark._healthLateRatio > 0) {
|
|
299
|
+
const late_ratio = value / (this._benchmarkData[name] / this._benchmarkCount[name])
|
|
300
|
+
if ((late_ratio > OINOBenchmark._healthLateRatio)) {
|
|
301
|
+
this._healthFailures += 1
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
240
305
|
}
|
|
241
306
|
|
|
242
307
|
protected _trackException(module:string, method:string, name:string, message:string, stack:string):void {
|
|
@@ -247,4 +312,13 @@ export class OINOMemoryBenchmark extends OINOBenchmark {
|
|
|
247
312
|
protected _getExceptions():any[] {
|
|
248
313
|
return this._exceptions
|
|
249
314
|
}
|
|
315
|
+
|
|
316
|
+
protected _getHealth(): number {
|
|
317
|
+
if ((OINOBenchmark._healthBenchmarks.length == 0) || (this._healthRequests == 0)) {
|
|
318
|
+
return 1.0
|
|
319
|
+
|
|
320
|
+
} else {
|
|
321
|
+
return (this._healthRequests - this._healthFailures) / this._healthRequests
|
|
322
|
+
}
|
|
323
|
+
}
|
|
250
324
|
}
|