@tramvai/module-metrics 2.70.0 → 2.72.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/lib/browser.js +5 -156
- package/lib/constants.es.js +3 -0
- package/lib/constants.js +7 -0
- package/lib/instantMetrics/browser.browser.js +70 -0
- package/lib/instantMetrics/server.es.js +97 -0
- package/lib/instantMetrics/server.js +103 -0
- package/lib/instantMetrics/shared.browser.js +12 -0
- package/lib/instantMetrics/shared.es.js +12 -0
- package/lib/instantMetrics/shared.js +16 -0
- package/lib/instantMetrics/store.browser.js +8 -0
- package/lib/instantMetrics/store.es.js +8 -0
- package/lib/instantMetrics/store.js +13 -0
- package/lib/metrics/commandLine.es.js +22 -0
- package/lib/metrics/commandLine.js +26 -0
- package/lib/metrics/eventLoop.es.js +23 -0
- package/lib/metrics/eventLoop.js +27 -0
- package/lib/performance-devtools/PerfMetrics.browser.js +56 -0
- package/lib/performance-devtools/startMeasure.browser.js +14 -0
- package/lib/performance-devtools/supportsUserTiming.browser.js +7 -0
- package/lib/performance-devtools/uniqueId.browser.js +7 -0
- package/lib/request/MetricsServicesRegistry.es.js +56 -0
- package/lib/request/MetricsServicesRegistry.js +64 -0
- package/lib/request/PrefixTree.es.js +48 -0
- package/lib/request/PrefixTree.js +52 -0
- package/lib/request/createRequestWithMetrics.es.js +123 -0
- package/lib/request/createRequestWithMetrics.js +128 -0
- package/lib/request/index.es.js +57 -0
- package/lib/request/index.js +65 -0
- package/lib/request/initRequestsMetrics.es.js +53 -0
- package/lib/request/initRequestsMetrics.js +61 -0
- package/lib/server.es.js +9 -469
- package/lib/server.js +9 -475
- package/package.json +19 -20
package/lib/browser.js
CHANGED
|
@@ -1,164 +1,13 @@
|
|
|
1
1
|
import { __decorate } from 'tslib';
|
|
2
|
-
import { Module,
|
|
3
|
-
import {
|
|
2
|
+
import { Module, Scope, commandLineListTokens } from '@tramvai/core';
|
|
3
|
+
import { LOGGER_TOKEN } from '@tramvai/tokens-common';
|
|
4
4
|
import { METRICS_MODULE_TOKEN } from '@tramvai/tokens-metrics';
|
|
5
5
|
export * from '@tramvai/tokens-metrics';
|
|
6
6
|
import { browserTimings } from '@tinkoff/browser-timings';
|
|
7
|
-
import {
|
|
7
|
+
import { Counter, Gauge, Histogram, Summary } from '@tinkoff/metrics-noop';
|
|
8
8
|
import { PAGE_SERVICE_TOKEN } from '@tramvai/tokens-router';
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { createEvent, createReducer } from '@tramvai/state';
|
|
12
|
-
|
|
13
|
-
const setInstantMetrics = createEvent('set instant metrics map');
|
|
14
|
-
const MetricsStore = createReducer('instantMetrics', { instantMetricsMap: {} }).on(setInstantMetrics, (_prevState, nextState) => {
|
|
15
|
-
return nextState;
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
const sharedProviders = [
|
|
19
|
-
{
|
|
20
|
-
provide: COMBINE_REDUCERS,
|
|
21
|
-
multi: true,
|
|
22
|
-
useValue: [MetricsStore],
|
|
23
|
-
},
|
|
24
|
-
];
|
|
25
|
-
|
|
26
|
-
let InstantMetricsModule = class InstantMetricsModule {
|
|
27
|
-
};
|
|
28
|
-
InstantMetricsModule = __decorate([
|
|
29
|
-
Module({
|
|
30
|
-
providers: [
|
|
31
|
-
...sharedProviders,
|
|
32
|
-
{
|
|
33
|
-
// При такой схеме подключения отправка instant метрик заработает только после этого
|
|
34
|
-
// провайдера, но подлючить через LOGGER_INIT_HOOK не представляется возможным потому что
|
|
35
|
-
// возникает циклическая зависимость контекст -> логгер -> хук метрик -> контекст
|
|
36
|
-
provide: commandLineListTokens.init,
|
|
37
|
-
scope: Scope.SINGLETON,
|
|
38
|
-
multi: true,
|
|
39
|
-
useFactory({ logger, papiService, context, }) {
|
|
40
|
-
if (!papiService) {
|
|
41
|
-
return () => { };
|
|
42
|
-
}
|
|
43
|
-
const validMetricsMap = context.getStore('instantMetrics').getState().instantMetricsMap;
|
|
44
|
-
const instantMetricsReporter = new RemoteReporter({
|
|
45
|
-
requestCount: 1,
|
|
46
|
-
emitLevels: {
|
|
47
|
-
trace: true,
|
|
48
|
-
debug: true,
|
|
49
|
-
info: true,
|
|
50
|
-
warn: true,
|
|
51
|
-
error: true,
|
|
52
|
-
fatal: true,
|
|
53
|
-
},
|
|
54
|
-
makeRequest(logObject) {
|
|
55
|
-
if (validMetricsMap[logObject.event]) {
|
|
56
|
-
return papiService
|
|
57
|
-
.request({
|
|
58
|
-
path: `metrics/${logObject.event}`,
|
|
59
|
-
method: 'post',
|
|
60
|
-
payload: logObject.value
|
|
61
|
-
? {
|
|
62
|
-
value: logObject.value,
|
|
63
|
-
}
|
|
64
|
-
: {},
|
|
65
|
-
})
|
|
66
|
-
.then(({ payload }) => payload);
|
|
67
|
-
}
|
|
68
|
-
return Promise.resolve();
|
|
69
|
-
},
|
|
70
|
-
});
|
|
71
|
-
return () => {
|
|
72
|
-
logger.addBeforeReporter(instantMetricsReporter);
|
|
73
|
-
};
|
|
74
|
-
},
|
|
75
|
-
deps: {
|
|
76
|
-
papiService: {
|
|
77
|
-
token: PAPI_SERVICE,
|
|
78
|
-
optional: true,
|
|
79
|
-
},
|
|
80
|
-
context: CONTEXT_TOKEN,
|
|
81
|
-
logger: LOGGER_TOKEN,
|
|
82
|
-
},
|
|
83
|
-
},
|
|
84
|
-
],
|
|
85
|
-
})
|
|
86
|
-
], InstantMetricsModule);
|
|
87
|
-
|
|
88
|
-
function startMeasure(markName, uniqueMarkId) {
|
|
89
|
-
const uniqueMarkName = `${markName}:${uniqueMarkId}`;
|
|
90
|
-
performance.mark(uniqueMarkName);
|
|
91
|
-
function endMeasure(measureName) {
|
|
92
|
-
try {
|
|
93
|
-
performance.measure(measureName || markName, uniqueMarkName);
|
|
94
|
-
}
|
|
95
|
-
catch (e) { }
|
|
96
|
-
performance.clearMarks(uniqueMarkName);
|
|
97
|
-
}
|
|
98
|
-
return endMeasure;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const supportsUserTiming = typeof performance !== 'undefined' &&
|
|
102
|
-
typeof performance.mark === 'function' &&
|
|
103
|
-
typeof performance.clearMarks === 'function' &&
|
|
104
|
-
typeof performance.measure === 'function' &&
|
|
105
|
-
typeof performance.clearMeasures === 'function';
|
|
106
|
-
|
|
107
|
-
let idCounter = 0;
|
|
108
|
-
function uniqueId() {
|
|
109
|
-
// eslint-disable-next-line no-plusplus
|
|
110
|
-
return ++idCounter;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function startMeasurePerformance(name, startLabels = {}) {
|
|
114
|
-
if (!supportsUserTiming) {
|
|
115
|
-
return () => { };
|
|
116
|
-
}
|
|
117
|
-
const endMeasure = startMeasure(name, uniqueId());
|
|
118
|
-
return (endLabels = {}) => {
|
|
119
|
-
const labels = { ...startLabels, ...endLabels };
|
|
120
|
-
const labelsNames = Object.keys(labels)
|
|
121
|
-
.map((key) => `${key}="${labels[key]}"`)
|
|
122
|
-
.join(',');
|
|
123
|
-
endMeasure(labelsNames && `${name}{${labelsNames}}`);
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
class PerfHistogram extends Histogram {
|
|
127
|
-
constructor(configurator) {
|
|
128
|
-
super(configurator);
|
|
129
|
-
this.name = configurator.name;
|
|
130
|
-
}
|
|
131
|
-
startTimer(startLabels) {
|
|
132
|
-
const endMeasure = startMeasurePerformance(this.name, startLabels);
|
|
133
|
-
return (endLabels) => {
|
|
134
|
-
endMeasure(endLabels);
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
class PerfSummary extends Summary {
|
|
139
|
-
constructor(configurator) {
|
|
140
|
-
super(configurator);
|
|
141
|
-
this.name = configurator.name;
|
|
142
|
-
}
|
|
143
|
-
startTimer() {
|
|
144
|
-
const endMeasure = startMeasurePerformance(this.name);
|
|
145
|
-
return (endLabels) => {
|
|
146
|
-
endMeasure(endLabels);
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
class PerfGauge extends Gauge {
|
|
151
|
-
constructor(configurator) {
|
|
152
|
-
super(configurator);
|
|
153
|
-
this.name = configurator.name;
|
|
154
|
-
}
|
|
155
|
-
startTimer(startLabels) {
|
|
156
|
-
const endMeasure = startMeasurePerformance(this.name, startLabels);
|
|
157
|
-
return (endLabels) => {
|
|
158
|
-
endMeasure(endLabels);
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
}
|
|
9
|
+
import { InstantMetricsModule } from './instantMetrics/browser.browser.js';
|
|
10
|
+
import { PerfGauge, PerfHistogram, PerfSummary } from './performance-devtools/PerfMetrics.browser.js';
|
|
162
11
|
|
|
163
12
|
let MetricsModule = class MetricsModule {
|
|
164
13
|
};
|
package/lib/constants.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { __decorate } from 'tslib';
|
|
2
|
+
import { Module, commandLineListTokens, Scope } from '@tramvai/core';
|
|
3
|
+
import { CONTEXT_TOKEN, LOGGER_TOKEN } from '@tramvai/tokens-common';
|
|
4
|
+
import { PAPI_SERVICE } from '@tramvai/tokens-http-client';
|
|
5
|
+
import { RemoteReporter } from '@tinkoff/logger';
|
|
6
|
+
import { sharedProviders } from './shared.browser.js';
|
|
7
|
+
|
|
8
|
+
let InstantMetricsModule = class InstantMetricsModule {
|
|
9
|
+
};
|
|
10
|
+
InstantMetricsModule = __decorate([
|
|
11
|
+
Module({
|
|
12
|
+
providers: [
|
|
13
|
+
...sharedProviders,
|
|
14
|
+
{
|
|
15
|
+
// При такой схеме подключения отправка instant метрик заработает только после этого
|
|
16
|
+
// провайдера, но подлючить через LOGGER_INIT_HOOK не представляется возможным потому что
|
|
17
|
+
// возникает циклическая зависимость контекст -> логгер -> хук метрик -> контекст
|
|
18
|
+
provide: commandLineListTokens.init,
|
|
19
|
+
scope: Scope.SINGLETON,
|
|
20
|
+
multi: true,
|
|
21
|
+
useFactory({ logger, papiService, context, }) {
|
|
22
|
+
if (!papiService) {
|
|
23
|
+
return () => { };
|
|
24
|
+
}
|
|
25
|
+
const validMetricsMap = context.getStore('instantMetrics').getState().instantMetricsMap;
|
|
26
|
+
const instantMetricsReporter = new RemoteReporter({
|
|
27
|
+
requestCount: 1,
|
|
28
|
+
emitLevels: {
|
|
29
|
+
trace: true,
|
|
30
|
+
debug: true,
|
|
31
|
+
info: true,
|
|
32
|
+
warn: true,
|
|
33
|
+
error: true,
|
|
34
|
+
fatal: true,
|
|
35
|
+
},
|
|
36
|
+
makeRequest(logObject) {
|
|
37
|
+
if (validMetricsMap[logObject.event]) {
|
|
38
|
+
return papiService
|
|
39
|
+
.request({
|
|
40
|
+
path: `metrics/${logObject.event}`,
|
|
41
|
+
method: 'post',
|
|
42
|
+
payload: logObject.value
|
|
43
|
+
? {
|
|
44
|
+
value: logObject.value,
|
|
45
|
+
}
|
|
46
|
+
: {},
|
|
47
|
+
})
|
|
48
|
+
.then(({ payload }) => payload);
|
|
49
|
+
}
|
|
50
|
+
return Promise.resolve();
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
return () => {
|
|
54
|
+
logger.addBeforeReporter(instantMetricsReporter);
|
|
55
|
+
};
|
|
56
|
+
},
|
|
57
|
+
deps: {
|
|
58
|
+
papiService: {
|
|
59
|
+
token: PAPI_SERVICE,
|
|
60
|
+
optional: true,
|
|
61
|
+
},
|
|
62
|
+
context: CONTEXT_TOKEN,
|
|
63
|
+
logger: LOGGER_TOKEN,
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
})
|
|
68
|
+
], InstantMetricsModule);
|
|
69
|
+
|
|
70
|
+
export { InstantMetricsModule };
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { __decorate } from 'tslib';
|
|
2
|
+
import { Module, commandLineListTokens } from '@tramvai/core';
|
|
3
|
+
import { SERVER_MODULE_PAPI_PUBLIC_ROUTE } from '@tramvai/tokens-server';
|
|
4
|
+
import { createPapiMethod } from '@tramvai/papi';
|
|
5
|
+
import { METRICS_MODULE_TOKEN, REGISTER_INSTANT_METRIC_TOKEN } from '@tramvai/tokens-metrics';
|
|
6
|
+
import { LOGGER_TOKEN, CONTEXT_TOKEN } from '@tramvai/tokens-common';
|
|
7
|
+
import fromPairs from '@tinkoff/utils/object/fromPairs';
|
|
8
|
+
import { sharedProviders } from './shared.es.js';
|
|
9
|
+
import { setInstantMetrics } from './store.es.js';
|
|
10
|
+
|
|
11
|
+
let InstantMetricsModule = class InstantMetricsModule {
|
|
12
|
+
};
|
|
13
|
+
InstantMetricsModule = __decorate([
|
|
14
|
+
Module({
|
|
15
|
+
providers: [
|
|
16
|
+
...sharedProviders,
|
|
17
|
+
{
|
|
18
|
+
provide: SERVER_MODULE_PAPI_PUBLIC_ROUTE,
|
|
19
|
+
multi: true,
|
|
20
|
+
useFactory({ metrics, logger, instantMetrics, }) {
|
|
21
|
+
const log = logger('instantmetrics:papi');
|
|
22
|
+
const instantMetricsMap = fromPairs(instantMetrics || []);
|
|
23
|
+
return createPapiMethod({
|
|
24
|
+
method: 'post',
|
|
25
|
+
path: '/metrics/:metric',
|
|
26
|
+
options: {
|
|
27
|
+
schema: {
|
|
28
|
+
body: {
|
|
29
|
+
type: 'object',
|
|
30
|
+
properties: {
|
|
31
|
+
value: {
|
|
32
|
+
type: 'number',
|
|
33
|
+
minimum: 0,
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
additionalProperties: false,
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
async handler({ params: { metric }, body, responseManager }) {
|
|
41
|
+
if (!instantMetricsMap[metric]) {
|
|
42
|
+
log.error({
|
|
43
|
+
event: 'client-instant-metric-mismatch',
|
|
44
|
+
metricName: metric,
|
|
45
|
+
error: new Error(`No instant metric instance found with name: ${metric}`),
|
|
46
|
+
});
|
|
47
|
+
responseManager.setStatus(404);
|
|
48
|
+
responseManager.setBody({
|
|
49
|
+
resultCode: 'NOT_FOUND',
|
|
50
|
+
errorMessage: 'metric not found',
|
|
51
|
+
});
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
instantMetricsMap[metric].inc(body === null || body === void 0 ? void 0 : body.value);
|
|
55
|
+
return { status: 'ok' };
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
},
|
|
59
|
+
deps: {
|
|
60
|
+
metrics: METRICS_MODULE_TOKEN,
|
|
61
|
+
logger: LOGGER_TOKEN,
|
|
62
|
+
instantMetrics: {
|
|
63
|
+
token: REGISTER_INSTANT_METRIC_TOKEN,
|
|
64
|
+
multi: true,
|
|
65
|
+
optional: true,
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
provide: commandLineListTokens.customerStart,
|
|
71
|
+
multi: true,
|
|
72
|
+
useFactory({ instantMetrics, context, }) {
|
|
73
|
+
return async () => {
|
|
74
|
+
if (!instantMetrics) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const instantMetricsMap = instantMetrics.reduce((acc, [metricName]) => {
|
|
78
|
+
acc[metricName] = true;
|
|
79
|
+
return acc;
|
|
80
|
+
}, {});
|
|
81
|
+
await context.dispatch(setInstantMetrics({ instantMetricsMap }));
|
|
82
|
+
};
|
|
83
|
+
},
|
|
84
|
+
deps: {
|
|
85
|
+
context: CONTEXT_TOKEN,
|
|
86
|
+
instantMetrics: {
|
|
87
|
+
token: REGISTER_INSTANT_METRIC_TOKEN,
|
|
88
|
+
multi: true,
|
|
89
|
+
optional: true,
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
})
|
|
95
|
+
], InstantMetricsModule);
|
|
96
|
+
|
|
97
|
+
export { InstantMetricsModule };
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var tslib = require('tslib');
|
|
6
|
+
var core = require('@tramvai/core');
|
|
7
|
+
var tokensServer = require('@tramvai/tokens-server');
|
|
8
|
+
var papi = require('@tramvai/papi');
|
|
9
|
+
var tokensMetrics = require('@tramvai/tokens-metrics');
|
|
10
|
+
var tokensCommon = require('@tramvai/tokens-common');
|
|
11
|
+
var fromPairs = require('@tinkoff/utils/object/fromPairs');
|
|
12
|
+
var shared = require('./shared.js');
|
|
13
|
+
var store = require('./store.js');
|
|
14
|
+
|
|
15
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
16
|
+
|
|
17
|
+
var fromPairs__default = /*#__PURE__*/_interopDefaultLegacy(fromPairs);
|
|
18
|
+
|
|
19
|
+
exports.InstantMetricsModule = class InstantMetricsModule {
|
|
20
|
+
};
|
|
21
|
+
exports.InstantMetricsModule = tslib.__decorate([
|
|
22
|
+
core.Module({
|
|
23
|
+
providers: [
|
|
24
|
+
...shared.sharedProviders,
|
|
25
|
+
{
|
|
26
|
+
provide: tokensServer.SERVER_MODULE_PAPI_PUBLIC_ROUTE,
|
|
27
|
+
multi: true,
|
|
28
|
+
useFactory({ metrics, logger, instantMetrics, }) {
|
|
29
|
+
const log = logger('instantmetrics:papi');
|
|
30
|
+
const instantMetricsMap = fromPairs__default["default"](instantMetrics || []);
|
|
31
|
+
return papi.createPapiMethod({
|
|
32
|
+
method: 'post',
|
|
33
|
+
path: '/metrics/:metric',
|
|
34
|
+
options: {
|
|
35
|
+
schema: {
|
|
36
|
+
body: {
|
|
37
|
+
type: 'object',
|
|
38
|
+
properties: {
|
|
39
|
+
value: {
|
|
40
|
+
type: 'number',
|
|
41
|
+
minimum: 0,
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
additionalProperties: false,
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
async handler({ params: { metric }, body, responseManager }) {
|
|
49
|
+
if (!instantMetricsMap[metric]) {
|
|
50
|
+
log.error({
|
|
51
|
+
event: 'client-instant-metric-mismatch',
|
|
52
|
+
metricName: metric,
|
|
53
|
+
error: new Error(`No instant metric instance found with name: ${metric}`),
|
|
54
|
+
});
|
|
55
|
+
responseManager.setStatus(404);
|
|
56
|
+
responseManager.setBody({
|
|
57
|
+
resultCode: 'NOT_FOUND',
|
|
58
|
+
errorMessage: 'metric not found',
|
|
59
|
+
});
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
instantMetricsMap[metric].inc(body === null || body === void 0 ? void 0 : body.value);
|
|
63
|
+
return { status: 'ok' };
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
},
|
|
67
|
+
deps: {
|
|
68
|
+
metrics: tokensMetrics.METRICS_MODULE_TOKEN,
|
|
69
|
+
logger: tokensCommon.LOGGER_TOKEN,
|
|
70
|
+
instantMetrics: {
|
|
71
|
+
token: tokensMetrics.REGISTER_INSTANT_METRIC_TOKEN,
|
|
72
|
+
multi: true,
|
|
73
|
+
optional: true,
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
provide: core.commandLineListTokens.customerStart,
|
|
79
|
+
multi: true,
|
|
80
|
+
useFactory({ instantMetrics, context, }) {
|
|
81
|
+
return async () => {
|
|
82
|
+
if (!instantMetrics) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const instantMetricsMap = instantMetrics.reduce((acc, [metricName]) => {
|
|
86
|
+
acc[metricName] = true;
|
|
87
|
+
return acc;
|
|
88
|
+
}, {});
|
|
89
|
+
await context.dispatch(store.setInstantMetrics({ instantMetricsMap }));
|
|
90
|
+
};
|
|
91
|
+
},
|
|
92
|
+
deps: {
|
|
93
|
+
context: tokensCommon.CONTEXT_TOKEN,
|
|
94
|
+
instantMetrics: {
|
|
95
|
+
token: tokensMetrics.REGISTER_INSTANT_METRIC_TOKEN,
|
|
96
|
+
multi: true,
|
|
97
|
+
optional: true,
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
})
|
|
103
|
+
], exports.InstantMetricsModule);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { COMBINE_REDUCERS } from '@tramvai/tokens-common';
|
|
2
|
+
import { MetricsStore } from './store.browser.js';
|
|
3
|
+
|
|
4
|
+
const sharedProviders = [
|
|
5
|
+
{
|
|
6
|
+
provide: COMBINE_REDUCERS,
|
|
7
|
+
multi: true,
|
|
8
|
+
useValue: [MetricsStore],
|
|
9
|
+
},
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
export { sharedProviders };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { COMBINE_REDUCERS } from '@tramvai/tokens-common';
|
|
2
|
+
import { MetricsStore } from './store.es.js';
|
|
3
|
+
|
|
4
|
+
const sharedProviders = [
|
|
5
|
+
{
|
|
6
|
+
provide: COMBINE_REDUCERS,
|
|
7
|
+
multi: true,
|
|
8
|
+
useValue: [MetricsStore],
|
|
9
|
+
},
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
export { sharedProviders };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var tokensCommon = require('@tramvai/tokens-common');
|
|
6
|
+
var store = require('./store.js');
|
|
7
|
+
|
|
8
|
+
const sharedProviders = [
|
|
9
|
+
{
|
|
10
|
+
provide: tokensCommon.COMBINE_REDUCERS,
|
|
11
|
+
multi: true,
|
|
12
|
+
useValue: [store.MetricsStore],
|
|
13
|
+
},
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
exports.sharedProviders = sharedProviders;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { createEvent, createReducer } from '@tramvai/state';
|
|
2
|
+
|
|
3
|
+
const setInstantMetrics = createEvent('set instant metrics map');
|
|
4
|
+
const MetricsStore = createReducer('instantMetrics', { instantMetricsMap: {} }).on(setInstantMetrics, (_prevState, nextState) => {
|
|
5
|
+
return nextState;
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
export { MetricsStore, setInstantMetrics };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { createEvent, createReducer } from '@tramvai/state';
|
|
2
|
+
|
|
3
|
+
const setInstantMetrics = createEvent('set instant metrics map');
|
|
4
|
+
const MetricsStore = createReducer('instantMetrics', { instantMetricsMap: {} }).on(setInstantMetrics, (_prevState, nextState) => {
|
|
5
|
+
return nextState;
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
export { MetricsStore, setInstantMetrics };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var state = require('@tramvai/state');
|
|
6
|
+
|
|
7
|
+
const setInstantMetrics = state.createEvent('set instant metrics map');
|
|
8
|
+
const MetricsStore = state.createReducer('instantMetrics', { instantMetricsMap: {} }).on(setInstantMetrics, (_prevState, nextState) => {
|
|
9
|
+
return nextState;
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
exports.MetricsStore = MetricsStore;
|
|
13
|
+
exports.setInstantMetrics = setInstantMetrics;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { DEFAULT_BUCKETS } from '../constants.es.js';
|
|
2
|
+
|
|
3
|
+
const commandLineMetrics = (metrics) => {
|
|
4
|
+
const metricsInstance = metrics.histogram({
|
|
5
|
+
name: `command_line_runner_execution_time`,
|
|
6
|
+
help: 'Command line processing duration',
|
|
7
|
+
labelNames: ['line'],
|
|
8
|
+
buckets: DEFAULT_BUCKETS,
|
|
9
|
+
});
|
|
10
|
+
return (di, type, status, timingInfo) => {
|
|
11
|
+
for (const line in timingInfo) {
|
|
12
|
+
const info = timingInfo[line];
|
|
13
|
+
if (info.end) {
|
|
14
|
+
const durationInMs = info.end - info.start;
|
|
15
|
+
const durationInSec = durationInMs / 1000;
|
|
16
|
+
metricsInstance.observe({ line }, durationInSec);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export { commandLineMetrics };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var constants = require('../constants.js');
|
|
6
|
+
|
|
7
|
+
const commandLineMetrics = (metrics) => {
|
|
8
|
+
const metricsInstance = metrics.histogram({
|
|
9
|
+
name: `command_line_runner_execution_time`,
|
|
10
|
+
help: 'Command line processing duration',
|
|
11
|
+
labelNames: ['line'],
|
|
12
|
+
buckets: constants.DEFAULT_BUCKETS,
|
|
13
|
+
});
|
|
14
|
+
return (di, type, status, timingInfo) => {
|
|
15
|
+
for (const line in timingInfo) {
|
|
16
|
+
const info = timingInfo[line];
|
|
17
|
+
if (info.end) {
|
|
18
|
+
const durationInMs = info.end - info.start;
|
|
19
|
+
const durationInSec = durationInMs / 1000;
|
|
20
|
+
metricsInstance.observe({ line }, durationInSec);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
exports.commandLineMetrics = commandLineMetrics;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const NODEJS_EVENTLOOP_LAG = 'nodejs_eventloop_setinterval_lag_seconds';
|
|
2
|
+
function startEventLoopLagMeasure(histogram) {
|
|
3
|
+
let start = process.hrtime();
|
|
4
|
+
const interval = 100;
|
|
5
|
+
setInterval(() => {
|
|
6
|
+
const delta = process.hrtime(start);
|
|
7
|
+
const nanosec = delta[0] * 1e9 + delta[1];
|
|
8
|
+
const ms = nanosec / 1e6;
|
|
9
|
+
const lag = ms - interval;
|
|
10
|
+
histogram.observe(lag / 1e3);
|
|
11
|
+
start = process.hrtime();
|
|
12
|
+
}, interval).unref();
|
|
13
|
+
}
|
|
14
|
+
const eventLoopMetrics = (metrics) => {
|
|
15
|
+
const histogram = metrics.histogram({
|
|
16
|
+
name: NODEJS_EVENTLOOP_LAG,
|
|
17
|
+
help: 'Lag of event loop in seconds (setInterval based).',
|
|
18
|
+
buckets: [0.02, 0.1, 0.2, 0.5, 1, 3, 5, 7.5, 10],
|
|
19
|
+
});
|
|
20
|
+
startEventLoopLagMeasure(histogram);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export { eventLoopMetrics };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
const NODEJS_EVENTLOOP_LAG = 'nodejs_eventloop_setinterval_lag_seconds';
|
|
6
|
+
function startEventLoopLagMeasure(histogram) {
|
|
7
|
+
let start = process.hrtime();
|
|
8
|
+
const interval = 100;
|
|
9
|
+
setInterval(() => {
|
|
10
|
+
const delta = process.hrtime(start);
|
|
11
|
+
const nanosec = delta[0] * 1e9 + delta[1];
|
|
12
|
+
const ms = nanosec / 1e6;
|
|
13
|
+
const lag = ms - interval;
|
|
14
|
+
histogram.observe(lag / 1e3);
|
|
15
|
+
start = process.hrtime();
|
|
16
|
+
}, interval).unref();
|
|
17
|
+
}
|
|
18
|
+
const eventLoopMetrics = (metrics) => {
|
|
19
|
+
const histogram = metrics.histogram({
|
|
20
|
+
name: NODEJS_EVENTLOOP_LAG,
|
|
21
|
+
help: 'Lag of event loop in seconds (setInterval based).',
|
|
22
|
+
buckets: [0.02, 0.1, 0.2, 0.5, 1, 3, 5, 7.5, 10],
|
|
23
|
+
});
|
|
24
|
+
startEventLoopLagMeasure(histogram);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
exports.eventLoopMetrics = eventLoopMetrics;
|