@emartech/aggregate-metric-logger 1.0.1 → 2.0.0
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/package.json +2 -3
- package/src/metric-logger.js +3 -19
- package/src/metric-logger.spec.js +20 -36
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@emartech/aggregate-metric-logger",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "aggregate metrics in memory for logging",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -32,8 +32,7 @@
|
|
|
32
32
|
"@emartech/json-logger": "^3.1.0",
|
|
33
33
|
"date-fns": "^2.3.0",
|
|
34
34
|
"json-stable-stringify": "^1.0.1",
|
|
35
|
-
"lodash": "^4.17.15"
|
|
36
|
-
"uuid": "8.3.2"
|
|
35
|
+
"lodash": "^4.17.15"
|
|
37
36
|
},
|
|
38
37
|
"devDependencies": {
|
|
39
38
|
"@sinonjs/fake-timers": "9.1.1",
|
package/src/metric-logger.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const { v4: uuid } = require('uuid');
|
|
4
3
|
const loggerFactory = require('@emartech/json-logger');
|
|
5
4
|
const { getSeconds, startOfMinute, addSeconds } = require('date-fns');
|
|
6
5
|
const { omit, pick, fromPairs, toPairs } = require('lodash');
|
|
@@ -9,22 +8,16 @@ const util = require('util');
|
|
|
9
8
|
|
|
10
9
|
module.exports = ({
|
|
11
10
|
enabled = true,
|
|
12
|
-
namespace = 'aggregate-metric-logger'
|
|
13
|
-
inProgressMeasurementWarningLimit = 10000
|
|
11
|
+
namespace = 'aggregate-metric-logger'
|
|
14
12
|
} = {}) => {
|
|
15
13
|
const logger = loggerFactory(namespace);
|
|
16
14
|
|
|
17
15
|
const thresholdsByTag = {};
|
|
18
|
-
let measurements = {};
|
|
19
16
|
let metrics = {};
|
|
20
17
|
let initialized = false;
|
|
21
18
|
|
|
22
19
|
const flush = () => {
|
|
23
20
|
logMetrics();
|
|
24
|
-
const inProgressMeasurementCount = Object.keys(measurements).length;
|
|
25
|
-
if (inProgressMeasurementCount > inProgressMeasurementWarningLimit) {
|
|
26
|
-
logger.warn('too-many-in-progress-metric-log-measurements', { count: inProgressMeasurementCount });
|
|
27
|
-
}
|
|
28
21
|
metrics = {};
|
|
29
22
|
setupNextFlush();
|
|
30
23
|
};
|
|
@@ -124,22 +117,13 @@ module.exports = ({
|
|
|
124
117
|
addMeasurement({ method: 'fatal', tag, params, value: 1, countOnly: true });
|
|
125
118
|
},
|
|
126
119
|
start(tag, params = {}) {
|
|
127
|
-
|
|
128
|
-
measurements[id] = { tag, params, start: Date.now() };
|
|
129
|
-
return id;
|
|
120
|
+
return { tag, params, start: Date.now() };
|
|
130
121
|
},
|
|
131
|
-
stop(
|
|
132
|
-
const measurement = measurements[measurementId];
|
|
133
|
-
if (!measurement) return;
|
|
134
|
-
|
|
122
|
+
stop(measurement) {
|
|
135
123
|
addMeasurement({
|
|
136
124
|
...pick(measurement, ['tag', 'params']),
|
|
137
125
|
value: Date.now() - measurement.start
|
|
138
126
|
});
|
|
139
|
-
delete measurements[measurementId];
|
|
140
|
-
},
|
|
141
|
-
cancel(measurementId) {
|
|
142
|
-
delete measurements[measurementId];
|
|
143
127
|
}
|
|
144
128
|
};
|
|
145
129
|
};
|
|
@@ -15,7 +15,7 @@ beforeEach(() => {
|
|
|
15
15
|
afterEach(() => clock.uninstall());
|
|
16
16
|
|
|
17
17
|
describe('metricLogger', () => {
|
|
18
|
-
describe('measure', () => {
|
|
18
|
+
describe('#measure', () => {
|
|
19
19
|
it('should log a single measurement at the next flush period', () => {
|
|
20
20
|
metricLogger.measure('elfogyasztot-tap', 4);
|
|
21
21
|
|
|
@@ -124,6 +124,17 @@ describe('metricLogger', () => {
|
|
|
124
124
|
});
|
|
125
125
|
});
|
|
126
126
|
|
|
127
|
+
describe('#start', () => {
|
|
128
|
+
it('should return a measurement object with the given tag, params and start time', () => {
|
|
129
|
+
const fakeCurrentTimestamp = 2323434543;
|
|
130
|
+
clock.setSystemTime(fakeCurrentTimestamp);
|
|
131
|
+
|
|
132
|
+
const measurement = metricLogger.start('test-tag', { foo: 'bar' });
|
|
133
|
+
|
|
134
|
+
expect(measurement).toEqual({ tag: 'test-tag', params: { foo: 'bar' }, start: fakeCurrentTimestamp });
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
|
|
127
138
|
describe('start/stop', () => {
|
|
128
139
|
it('should log min, max, count and sum when log was called only once', () => {
|
|
129
140
|
const measurementId = metricLogger.start('utlegeles');
|
|
@@ -142,12 +153,12 @@ describe('metricLogger', () => {
|
|
|
142
153
|
});
|
|
143
154
|
|
|
144
155
|
it('should aggregate metrics for two measurements and log after a timeout', () => {
|
|
145
|
-
const
|
|
146
|
-
const
|
|
156
|
+
const measurement1 = metricLogger.start('utlegeles');
|
|
157
|
+
const measurement2 = metricLogger.start('utlegeles');
|
|
147
158
|
clock.tick(50);
|
|
148
|
-
metricLogger.stop(
|
|
159
|
+
metricLogger.stop(measurement1);
|
|
149
160
|
clock.tick(20);
|
|
150
|
-
metricLogger.stop(
|
|
161
|
+
metricLogger.stop(measurement2);
|
|
151
162
|
|
|
152
163
|
clock.tick(60 * 1000);
|
|
153
164
|
expect(Logger.prototype.info).toBeCalledWith('utlegeles', {
|
|
@@ -160,24 +171,9 @@ describe('metricLogger', () => {
|
|
|
160
171
|
});
|
|
161
172
|
});
|
|
162
173
|
|
|
163
|
-
it('should not count a measurment if it is cancelled with cancel', () => {
|
|
164
|
-
const measurement1Id = metricLogger.start('utlegeles');
|
|
165
|
-
const measurement2Id = metricLogger.start('utlegeles');
|
|
166
|
-
clock.tick(50);
|
|
167
|
-
metricLogger.stop(measurement1Id);
|
|
168
|
-
clock.tick(20);
|
|
169
|
-
metricLogger.cancel(measurement2Id);
|
|
170
|
-
metricLogger.stop(measurement2Id);
|
|
171
|
-
|
|
172
|
-
clock.tick(60 * 1000);
|
|
173
|
-
expect(Logger.prototype.info).toBeCalledWith('utlegeles', expect.objectContaining({
|
|
174
|
-
count: 1
|
|
175
|
-
}));
|
|
176
|
-
});
|
|
177
|
-
|
|
178
174
|
it('should flush results at the closes minute:30', () => {
|
|
179
|
-
const
|
|
180
|
-
metricLogger.stop(
|
|
175
|
+
const measurement = metricLogger.start('utlegeles');
|
|
176
|
+
metricLogger.stop(measurement);
|
|
181
177
|
|
|
182
178
|
clock.tick(29 * 1000 + 999);
|
|
183
179
|
expect(Logger.prototype.info).not.toBeCalled();
|
|
@@ -187,8 +183,8 @@ describe('metricLogger', () => {
|
|
|
187
183
|
|
|
188
184
|
it('should flush at next minute:30 if we are after 30 in current minute', () => {
|
|
189
185
|
clock.tick(45 * 1000);
|
|
190
|
-
const
|
|
191
|
-
metricLogger.stop(
|
|
186
|
+
const measurement = metricLogger.start('utlegeles');
|
|
187
|
+
metricLogger.stop(measurement);
|
|
192
188
|
|
|
193
189
|
clock.tick(44 * 1000);
|
|
194
190
|
expect(Logger.prototype.info).not.toBeCalled();
|
|
@@ -253,18 +249,6 @@ describe('metricLogger', () => {
|
|
|
253
249
|
is_metric: true
|
|
254
250
|
});
|
|
255
251
|
});
|
|
256
|
-
|
|
257
|
-
it('should log warning if there are too many measurements in progress', () => {
|
|
258
|
-
jest.spyOn(Logger.prototype, 'warn');
|
|
259
|
-
const metricLogger = metricLoggerFactory({ inProgressMeasurementWarningLimit: 1 });
|
|
260
|
-
|
|
261
|
-
metricLogger.measure('kacsa');
|
|
262
|
-
metricLogger.start('nyavogas');
|
|
263
|
-
metricLogger.start('nyavogas');
|
|
264
|
-
clock.tick(60 * 1000);
|
|
265
|
-
|
|
266
|
-
expect(Logger.prototype.warn).toBeCalledWith('too-many-in-progress-metric-log-measurements', { count: 2 });
|
|
267
|
-
});
|
|
268
252
|
});
|
|
269
253
|
|
|
270
254
|
describe('simple count one log methods', () => {
|