@rsdk/core 4.1.0 → 4.2.0-next.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/CHANGELOG.md +12 -0
- package/dist/app-metadata/app-metadata.const.d.ts +1 -0
- package/dist/app-metadata/app-metadata.const.js +2 -1
- package/dist/app-metadata/app-metadata.const.js.map +1 -1
- package/dist/app-metadata/app-metadata.module.js +4 -0
- package/dist/app-metadata/app-metadata.module.js.map +1 -1
- package/dist/app-metadata/app-name.const.js +1 -1
- package/dist/app-metadata/app-name.const.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/platform.context.js +12 -4
- package/dist/platform.context.js.map +1 -1
- package/dist/platform.module.js +6 -1
- package/dist/platform.module.js.map +1 -1
- package/dist/tracing/auto-instrumentations.config.js +2 -3
- package/dist/tracing/auto-instrumentations.config.js.map +1 -1
- package/dist/tracing/grpc.headers.d.ts +11 -0
- package/dist/tracing/grpc.headers.js +24 -0
- package/dist/tracing/grpc.headers.js.map +1 -0
- package/dist/tracing/http.headers.d.ts +11 -0
- package/dist/tracing/http.headers.js +22 -0
- package/dist/tracing/http.headers.js.map +1 -0
- package/dist/tracing/index.d.ts +0 -1
- package/dist/tracing/index.js +0 -1
- package/dist/tracing/index.js.map +1 -1
- package/dist/tracing/open-telemetry.interceptor.d.ts +5 -0
- package/dist/tracing/open-telemetry.interceptor.js +83 -0
- package/dist/tracing/open-telemetry.interceptor.js.map +1 -0
- package/dist/tracing/request-metadata.module.js +1 -5
- package/dist/tracing/request-metadata.module.js.map +1 -1
- package/dist/tracing/services/instrumentation.service.d.ts +0 -1
- package/dist/tracing/services/instrumentation.service.js +0 -7
- package/dist/tracing/services/instrumentation.service.js.map +1 -1
- package/dist/tracing/services/request-id.provider.d.ts +11 -0
- package/dist/tracing/services/request-id.provider.js +13 -0
- package/dist/tracing/services/request-id.provider.js.map +1 -0
- package/dist/tracing/services/trace.injector.d.ts +4 -4
- package/dist/tracing/services/trace.injector.js +1 -132
- package/dist/tracing/services/trace.injector.js.map +1 -1
- package/dist/tracing/tracing.interceptor.d.ts +6 -5
- package/dist/tracing/tracing.interceptor.js +92 -7
- package/dist/tracing/tracing.interceptor.js.map +1 -1
- package/dist/tracing/tracing.module.d.ts +2 -2
- package/dist/tracing/tracing.module.js +8 -9
- package/dist/tracing/tracing.module.js.map +1 -1
- package/dist/types/options.d.ts +3 -1
- package/package.json +11 -10
- package/src/app-metadata/app-metadata.const.ts +1 -0
- package/src/app-metadata/app-metadata.module.ts +10 -1
- package/src/app-metadata/app-name.const.ts +1 -1
- package/src/index.ts +3 -3
- package/src/platform.context.ts +9 -1
- package/src/platform.module.ts +7 -1
- package/src/tracing/auto-instrumentations.config.ts +2 -3
- package/src/tracing/grpc.headers.ts +29 -0
- package/src/tracing/http.headers.ts +32 -0
- package/src/tracing/index.ts +0 -1
- package/src/tracing/open-telemetry.interceptor.ts +114 -0
- package/src/tracing/request-metadata.module.ts +1 -6
- package/src/tracing/services/instrumentation.service.ts +0 -11
- package/src/tracing/services/request-id.provider.ts +21 -0
- package/src/tracing/services/trace.injector.ts +4 -170
- package/src/tracing/tracing.interceptor.ts +131 -5
- package/src/tracing/tracing.module.ts +10 -12
- package/src/types/options.ts +2 -1
- package/dist/tracing/services/request-metadata.injector.d.ts +0 -6
- package/dist/tracing/services/request-metadata.injector.js +0 -123
- package/dist/tracing/services/request-metadata.injector.js.map +0 -1
- package/dist/tracing/services/request-metadata.storage.d.ts +0 -32
- package/dist/tracing/services/request-metadata.storage.js +0 -64
- package/dist/tracing/services/request-metadata.storage.js.map +0 -1
- package/src/tracing/services/request-metadata.injector.ts +0 -157
- package/src/tracing/services/request-metadata.storage.ts +0 -69
|
@@ -5,9 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.TraceInjector = void 0;
|
|
7
7
|
const api_1 = require("@opentelemetry/api");
|
|
8
|
-
const propagator_b3_1 = require("@opentelemetry/propagator-b3");
|
|
9
8
|
const sdk_node_1 = require("@opentelemetry/sdk-node");
|
|
10
|
-
const semantic_conventions_1 = require("@opentelemetry/semantic-conventions");
|
|
11
9
|
const common_1 = require("@rsdk/common");
|
|
12
10
|
const decorators_1 = require("@rsdk/decorators");
|
|
13
11
|
const logging_1 = require("@rsdk/logging");
|
|
@@ -55,139 +53,19 @@ class TraceInjector {
|
|
|
55
53
|
}
|
|
56
54
|
return 'data is undefined';
|
|
57
55
|
}
|
|
58
|
-
static createWrapper(original, spanName,
|
|
56
|
+
static createWrapper(original, spanName, _isTracingInterceptor) {
|
|
59
57
|
return {
|
|
60
58
|
[original.name](...args) {
|
|
61
59
|
const tracer = api_1.trace.getTracer('@rsdk/open-telemetry', '1.0.0');
|
|
62
|
-
const executionContext = args[0];
|
|
63
60
|
/**
|
|
64
61
|
* Переменный для хранения значений которые получаем для опен телеметрии
|
|
65
62
|
*/
|
|
66
63
|
let traceId;
|
|
67
64
|
let spanId;
|
|
68
|
-
let parentSpanId;
|
|
69
|
-
/**
|
|
70
|
-
* Этот флаг нужен для детекта первого входа и старта трейсинга, логика использования ниже в контексте
|
|
71
|
-
*/
|
|
72
|
-
let hasParentSpanId = false;
|
|
73
|
-
/**
|
|
74
|
-
* Переменная для хранения Request/виртуального рекRequestвеста
|
|
75
|
-
*/
|
|
76
|
-
let req;
|
|
77
|
-
/**
|
|
78
|
-
* Первый вход обычно происходит в глобальном интерцепторе
|
|
79
|
-
* он оборачивается в некий свой интернал тип спана который и передает этот флаг isTracingInterceptor=true
|
|
80
|
-
*/
|
|
81
|
-
if (isTracingInterceptor) {
|
|
82
|
-
if (executionContext.getType() === 'rpc') {
|
|
83
|
-
const metadata = executionContext.switchToRpc().getContext();
|
|
84
|
-
/**
|
|
85
|
-
* Если мы пришли в GRPC и у нас есть методы для работы с Metadata
|
|
86
|
-
* то мы конвертируем Metadata в некий виртуальный request с заголовками (заголовки выбраны как общий стандарт проброса мета информации)
|
|
87
|
-
*/
|
|
88
|
-
if (metadata?.get) {
|
|
89
|
-
req = {
|
|
90
|
-
headers: {
|
|
91
|
-
/**
|
|
92
|
-
* Пробрасываем текущий трейс ид запроса
|
|
93
|
-
*/
|
|
94
|
-
...(metadata.get(propagator_b3_1.X_B3_TRACE_ID).length > 0
|
|
95
|
-
? {
|
|
96
|
-
[propagator_b3_1.X_B3_TRACE_ID]: metadata.get(propagator_b3_1.X_B3_TRACE_ID)[0],
|
|
97
|
-
}
|
|
98
|
-
: {}),
|
|
99
|
-
/**
|
|
100
|
-
* Пробрасываем текущий спан ид, он нужен чтобы установить цепочку с парентами и могли видеть правильную вложенность в графане
|
|
101
|
-
*/
|
|
102
|
-
...(metadata.get(propagator_b3_1.X_B3_SPAN_ID).length > 0
|
|
103
|
-
? {
|
|
104
|
-
[propagator_b3_1.X_B3_SPAN_ID]: metadata.get(propagator_b3_1.X_B3_SPAN_ID)[0],
|
|
105
|
-
}
|
|
106
|
-
: {}),
|
|
107
|
-
/**
|
|
108
|
-
* Вот это не обычная переменная, она нужна для определения общего входа и детекта рутового спан ид,
|
|
109
|
-
* эта переменная нужна для работы флага hasParentSpanId
|
|
110
|
-
*/
|
|
111
|
-
...(metadata.get(propagator_b3_1.X_B3_PARENT_SPAN_ID).length > 0
|
|
112
|
-
? {
|
|
113
|
-
[propagator_b3_1.X_B3_PARENT_SPAN_ID]: metadata.get(propagator_b3_1.X_B3_PARENT_SPAN_ID)[0],
|
|
114
|
-
}
|
|
115
|
-
: {}),
|
|
116
|
-
},
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
if (executionContext.getType() === 'http') {
|
|
121
|
-
req = executionContext.switchToHttp().getRequest();
|
|
122
|
-
}
|
|
123
|
-
if (executionContext.getType() === 'graphql') {
|
|
124
|
-
req = executionContext.getArgs()[2]?.req; // аналог GqlExecutionContext.create(executionContext).getContext().req
|
|
125
|
-
if (req.connectionInitReceived) {
|
|
126
|
-
/**
|
|
127
|
-
* При работе с сабскрипшен через веб сокет, заголовки передаются в опции подключения к сабскрипшен в переменную connectionParams
|
|
128
|
-
* и мы перегоняем эти данные в request заголовки
|
|
129
|
-
*/
|
|
130
|
-
req.headers = {
|
|
131
|
-
...req?.headers,
|
|
132
|
-
...Object.entries(req?.connectionParams?.headers || {}).reduce((acc, [key, value]) => {
|
|
133
|
-
acc[key] = value;
|
|
134
|
-
return acc;
|
|
135
|
-
}, {}),
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
if (req?.headers) {
|
|
141
|
-
/**
|
|
142
|
-
* Мы приводим все ключи заголовков к одному **lower_case** регистру, так как у разных транспортов разные регистры в именовании ключей для заголовков
|
|
143
|
-
*/
|
|
144
|
-
req.headers = {
|
|
145
|
-
...Object.entries(req.headers).reduce((acc, [key, value]) => {
|
|
146
|
-
acc[key.toLowerCase()] =
|
|
147
|
-
req.headers[key.toLowerCase()] || value;
|
|
148
|
-
return acc;
|
|
149
|
-
}, {}),
|
|
150
|
-
};
|
|
151
|
-
/**
|
|
152
|
-
* Трейс ид - входящий рутовый идентификатор, он по всем цепочкам идет
|
|
153
|
-
*/
|
|
154
|
-
traceId = req.headers[propagator_b3_1.X_B3_TRACE_ID];
|
|
155
|
-
/**
|
|
156
|
-
* Спан ид - идентификатор который нужен для построения цепочки вызовов
|
|
157
|
-
*/
|
|
158
|
-
spanId = req.headers[propagator_b3_1.X_B3_SPAN_ID];
|
|
159
|
-
/**
|
|
160
|
-
* Флаг определяет находимся ли мы на рутовой позиции (самая первая точка входа)
|
|
161
|
-
* определяется просто - если с клиента не передали заголовок X_B3_PARENT_SPAN_ID то значит мы в точке входа,
|
|
162
|
-
* иначе мы являемся частью другой общей цепочки
|
|
163
|
-
*/
|
|
164
|
-
hasParentSpanId = !!Object.getOwnPropertyDescriptor(req.headers, propagator_b3_1.X_B3_PARENT_SPAN_ID);
|
|
165
|
-
/**
|
|
166
|
-
* Идентификатор родительского спана - больше нужен для определения рутового состояния в различных кодах по опен телеметрии
|
|
167
|
-
*/
|
|
168
|
-
parentSpanId = req.headers[propagator_b3_1.X_B3_PARENT_SPAN_ID];
|
|
169
|
-
}
|
|
170
|
-
if (isTracingInterceptor) {
|
|
171
|
-
/**
|
|
172
|
-
* Когда мы находимся в интерцепторе, то названием спана является название класса + метод интерцептора
|
|
173
|
-
* мы перебиваем на название класса + метод который трекаем
|
|
174
|
-
*/
|
|
175
|
-
spanName = TraceInjector.createSpanName(executionContext.getClass().name, executionContext.getHandler().name);
|
|
176
|
-
}
|
|
177
65
|
/**
|
|
178
66
|
* Создаем новый спан
|
|
179
67
|
*/
|
|
180
68
|
const span = tracer.startSpan(spanName, {});
|
|
181
|
-
// path parentSpanId for correct link to parent span
|
|
182
|
-
if (isTracingInterceptor && hasParentSpanId && parentSpanId) {
|
|
183
|
-
/**
|
|
184
|
-
* Так как опентелеметрия ставит свой некий парент спан ид, то наш слетает
|
|
185
|
-
* если мы работаем в рамках монолита то ничего не слетает
|
|
186
|
-
* как только мы перемещаемся между приложениями - он слетает
|
|
187
|
-
* чтобы иметь корректный парент спан ид - мы патчим его жестко (из коробки нельзя это сделать)
|
|
188
|
-
*/
|
|
189
|
-
span.parentSpanId = parentSpanId;
|
|
190
|
-
}
|
|
191
69
|
/**
|
|
192
70
|
* После создания контекста ранее при входе в приложение, у нас новый спан ид
|
|
193
71
|
* мы перетираем значением которе получили через заголовок
|
|
@@ -203,15 +81,6 @@ class TraceInjector {
|
|
|
203
81
|
if (traceId) {
|
|
204
82
|
span.spanContext().traceId = traceId;
|
|
205
83
|
}
|
|
206
|
-
if (req?.headers) {
|
|
207
|
-
/**
|
|
208
|
-
* Обычно самая первая точка входа это фронтовый запрос, который содержит некие заголовки хттп
|
|
209
|
-
* мы их кладем в рутовый спан
|
|
210
|
-
*/
|
|
211
|
-
span.setAttribute(semantic_conventions_1.SemanticAttributes.HTTP_METHOD, req.method);
|
|
212
|
-
span.setAttribute(semantic_conventions_1.SemanticAttributes.HTTP_URL, req.originalUrl || req.url);
|
|
213
|
-
span.setAttribute(semantic_conventions_1.SemanticAttributes.HTTP_ROUTE, req.route?.path || req.routeOptions?.url || req.routerPath);
|
|
214
|
-
}
|
|
215
84
|
/**
|
|
216
85
|
* Чтобы пробросить пропатченный спан нужно запустить две строчки ниже:
|
|
217
86
|
* 1) создаем контекст в котором активный спан перебиваем новым
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trace.injector.js","sourceRoot":"","sources":["../../../src/tracing/services/trace.injector.ts"],"names":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"trace.injector.js","sourceRoot":"","sources":["../../../src/tracing/services/trace.injector.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { CallHandler, ExecutionContext, NestInterceptor } from '@nestjs/common';
|
|
2
2
|
import type { Observable } from 'rxjs';
|
|
3
|
-
/**
|
|
4
|
-
* Интернал глобальный интерцептор для работы опентелеметрии
|
|
5
|
-
* его поведение будет модифицировано в зависимости от включенного или выключенного состояния глобального трэйсинга
|
|
6
|
-
*/
|
|
7
3
|
export declare class TracingInterceptor implements NestInterceptor {
|
|
8
|
-
intercept(
|
|
4
|
+
intercept(context: ExecutionContext, next: CallHandler): Observable<any>;
|
|
5
|
+
private static extractTracingHeaders;
|
|
6
|
+
private static extractFromGraphql;
|
|
7
|
+
private static extractFromHttp;
|
|
8
|
+
private static extractFromRpc;
|
|
9
|
+
private static createRequestId;
|
|
9
10
|
}
|
|
@@ -5,20 +5,105 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
5
5
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
6
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
7
|
};
|
|
8
|
+
var TracingInterceptor_1;
|
|
8
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
10
|
exports.TracingInterceptor = void 0;
|
|
10
11
|
const common_1 = require("@nestjs/common");
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
const propagator_b3_1 = require("@opentelemetry/propagator-b3");
|
|
13
|
+
const common_node_1 = require("@rsdk/common.node");
|
|
14
|
+
const node_crypto_1 = require("node:crypto");
|
|
15
|
+
const request_id_provider_1 = require("./services/request-id.provider");
|
|
16
|
+
const constants_1 = require("./constants");
|
|
17
|
+
const grpc_headers_1 = require("./grpc.headers");
|
|
18
|
+
const http_headers_1 = require("./http.headers");
|
|
19
|
+
const tracingHeaders = [
|
|
20
|
+
constants_1.X_REQUEST_ID,
|
|
21
|
+
propagator_b3_1.X_B3_TRACE_ID,
|
|
22
|
+
propagator_b3_1.X_B3_SPAN_ID,
|
|
23
|
+
propagator_b3_1.X_B3_PARENT_SPAN_ID,
|
|
24
|
+
];
|
|
25
|
+
let TracingInterceptor = TracingInterceptor_1 = class TracingInterceptor {
|
|
26
|
+
intercept(context, next) {
|
|
27
|
+
const requestId = TracingInterceptor_1.extractTracingHeaders(context);
|
|
28
|
+
request_id_provider_1.RequestIdProvider.set(requestId[constants_1.X_REQUEST_ID]);
|
|
29
|
+
request_id_provider_1.OpenTelemetryProvider.set((0, common_node_1.omitUndefined)(requestId));
|
|
17
30
|
return next.handle();
|
|
18
31
|
}
|
|
32
|
+
static extractTracingHeaders(executionContext) {
|
|
33
|
+
/**
|
|
34
|
+
* В зависимости от типа контекста запускаем парсинг переданной Metadata
|
|
35
|
+
*/
|
|
36
|
+
switch (executionContext.getType()) {
|
|
37
|
+
case 'rpc':
|
|
38
|
+
return this.extractFromRpc(executionContext);
|
|
39
|
+
case 'http':
|
|
40
|
+
return this.extractFromHttp(executionContext);
|
|
41
|
+
case 'graphql':
|
|
42
|
+
return this.extractFromGraphql(executionContext);
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
[constants_1.X_REQUEST_ID]: this.createRequestId(),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
static extractFromGraphql(executionContext) {
|
|
49
|
+
const req = executionContext.getArgs()[2]?.req; // аналог GqlExecutionContext.create(executionContext).getContext().req
|
|
50
|
+
/**
|
|
51
|
+
* При работе с сабскрипшен через веб сокет, заголовки передаются в опции подключения к сабскрипшен в переменную connectionParams
|
|
52
|
+
* и мы перегоняем эти данные в request заголовки
|
|
53
|
+
*/
|
|
54
|
+
const headers = {
|
|
55
|
+
...req?.headers,
|
|
56
|
+
...req?.connectionParams?.headers,
|
|
57
|
+
};
|
|
58
|
+
const extractedHeaders = new http_headers_1.HttpHeaders(headers).get([
|
|
59
|
+
constants_1.X_REQUEST_ID,
|
|
60
|
+
propagator_b3_1.X_B3_TRACE_ID,
|
|
61
|
+
propagator_b3_1.X_B3_SPAN_ID,
|
|
62
|
+
]);
|
|
63
|
+
const h = extractedHeaders;
|
|
64
|
+
h.http = {
|
|
65
|
+
httpMethod: req.method,
|
|
66
|
+
httpRoute: req.route?.path || req.routeOptions?.url || req.routerPath,
|
|
67
|
+
httpUrl: req.originalUrl || req.url,
|
|
68
|
+
};
|
|
69
|
+
h[constants_1.X_REQUEST_ID] ??= (0, node_crypto_1.randomUUID)();
|
|
70
|
+
return h;
|
|
71
|
+
}
|
|
72
|
+
static extractFromHttp(executionContext) {
|
|
73
|
+
// TODO:
|
|
74
|
+
const req = executionContext.switchToHttp().getRequest();
|
|
75
|
+
const headers = new http_headers_1.HttpHeaders(req.headers).get(tracingHeaders);
|
|
76
|
+
const h = headers;
|
|
77
|
+
h[constants_1.X_REQUEST_ID] ??= (0, node_crypto_1.randomUUID)();
|
|
78
|
+
h.http = {
|
|
79
|
+
httpMethod: req.method,
|
|
80
|
+
httpRoute: req.route?.path || req.routeOptions?.url || req.routerPath,
|
|
81
|
+
httpUrl: req.originalUrl || req.url,
|
|
82
|
+
};
|
|
83
|
+
return headers;
|
|
84
|
+
}
|
|
85
|
+
static extractFromRpc(executionContext) {
|
|
86
|
+
const metadata = executionContext.switchToRpc().getContext();
|
|
87
|
+
/**
|
|
88
|
+
* Если мы пришли в GRPC и у нас есть методы для работы с Metadata
|
|
89
|
+
* то мы конвертируем Metadata в некий виртуальный request с заголовками (заголовки выбраны как общий стандарт проброса мета информации)
|
|
90
|
+
*/
|
|
91
|
+
if (metadata?.get) {
|
|
92
|
+
const grpcHeaders = new grpc_headers_1.GrpcHeaders(metadata);
|
|
93
|
+
const h = grpcHeaders.get(tracingHeaders);
|
|
94
|
+
h[constants_1.X_REQUEST_ID] ??= this.createRequestId();
|
|
95
|
+
return h;
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
[constants_1.X_REQUEST_ID]: (0, node_crypto_1.randomUUID)(),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
static createRequestId() {
|
|
102
|
+
return (0, node_crypto_1.randomUUID)();
|
|
103
|
+
}
|
|
19
104
|
};
|
|
20
105
|
exports.TracingInterceptor = TracingInterceptor;
|
|
21
|
-
exports.TracingInterceptor = TracingInterceptor = __decorate([
|
|
106
|
+
exports.TracingInterceptor = TracingInterceptor = TracingInterceptor_1 = __decorate([
|
|
22
107
|
(0, common_1.Injectable)()
|
|
23
108
|
], TracingInterceptor);
|
|
24
109
|
//# sourceMappingURL=tracing.interceptor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracing.interceptor.js","sourceRoot":"","sources":["../../src/tracing/tracing.interceptor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tracing.interceptor.js","sourceRoot":"","sources":["../../src/tracing/tracing.interceptor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DynamicModule } from '@nestjs/common';
|
|
1
|
+
import type { DynamicModule, OnModuleInit } from '@nestjs/common';
|
|
2
2
|
import { NodeSDK } from '@opentelemetry/sdk-node';
|
|
3
3
|
import type { SpanExporter } from '@opentelemetry/sdk-trace-base';
|
|
4
4
|
import { ILogger } from '@rsdk/logging';
|
|
@@ -9,7 +9,7 @@ export interface TracingModuleOptions {
|
|
|
9
9
|
processing: 'simple' | 'batch';
|
|
10
10
|
exporter?: SpanExporter;
|
|
11
11
|
}
|
|
12
|
-
export declare class TracingModule {
|
|
12
|
+
export declare class TracingModule implements OnModuleInit {
|
|
13
13
|
private readonly logger;
|
|
14
14
|
private readonly instrumentations;
|
|
15
15
|
private readonly sdk;
|
|
@@ -27,9 +27,10 @@ const sdk_trace_base_1 = require("@opentelemetry/sdk-trace-base");
|
|
|
27
27
|
const semantic_conventions_1 = require("@opentelemetry/semantic-conventions");
|
|
28
28
|
const logging_1 = require("@rsdk/logging");
|
|
29
29
|
const logging_2 = require("../logging");
|
|
30
|
-
const
|
|
30
|
+
const request_id_provider_1 = require("./services/request-id.provider");
|
|
31
31
|
const active_span_module_1 = require("./active-span.module");
|
|
32
32
|
const auto_instrumentations_config_1 = require("./auto-instrumentations.config");
|
|
33
|
+
const open_telemetry_interceptor_1 = require("./open-telemetry.interceptor");
|
|
33
34
|
const request_metadata_module_1 = require("./request-metadata.module");
|
|
34
35
|
const services_1 = require("./services");
|
|
35
36
|
const tracing_config_1 = require("./tracing.config");
|
|
@@ -50,24 +51,22 @@ let TracingModule = TracingModule_1 = class TracingModule {
|
|
|
50
51
|
module: TracingModule_1,
|
|
51
52
|
imports: [request_metadata_module_1.RequestMetadataModule, active_span_module_1.ActiveSpanModule],
|
|
52
53
|
providers: [
|
|
54
|
+
{ provide: core_1.APP_INTERCEPTOR, useValue: new tracing_interceptor_1.TracingInterceptor() },
|
|
55
|
+
{
|
|
56
|
+
provide: core_1.APP_INTERCEPTOR,
|
|
57
|
+
useValue: new open_telemetry_interceptor_1.OpenTelemetryInterceptor(),
|
|
58
|
+
},
|
|
53
59
|
services_1.InstrumentationService,
|
|
54
60
|
this.createSDKProvider(options),
|
|
55
|
-
/**
|
|
56
|
-
* Глобальный интерцептор для проброса входящих traceId, spanId и requestId из заголовков и метадаты в активный AsyncLocalStorage запроса
|
|
57
|
-
*/
|
|
58
|
-
{ provide: core_1.APP_INTERCEPTOR, useClass: tracing_interceptor_1.TracingInterceptor },
|
|
59
61
|
],
|
|
60
62
|
};
|
|
61
63
|
}
|
|
62
64
|
// Можно добавить включение и выключение при изменении конфига.
|
|
63
65
|
async onModuleInit() {
|
|
64
|
-
this.logger.debug('Injecting request-metadata storage...');
|
|
65
|
-
this.instrumentations.injectWrapRequestMetadataInjector();
|
|
66
66
|
if (!this.config.enabled) {
|
|
67
67
|
this.logger.info('Tracing is disabled');
|
|
68
68
|
logging_1.LoggerFactory.applyInstrumentations((record) => {
|
|
69
|
-
record['request_id'] =
|
|
70
|
-
request_metadata_storage_1.RequestMetadataStorage.getInstance()?.getRequestMetadata().requestId;
|
|
69
|
+
record['request_id'] = request_id_provider_1.RequestIdProvider.get();
|
|
71
70
|
});
|
|
72
71
|
return;
|
|
73
72
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracing.module.js","sourceRoot":"","sources":["../../src/tracing/tracing.module.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AACA,2CAAwC;AACxC,uCAA+C;AAC/C,4CAAoD;AACpD,4EAAqF;AACrF,8CAA0D;AAC1D,sFAA4E;AAC5E,gEAA8E;AAC9E,wDAAoD;AACpD,sDAAkD;AAElD,kEAGuC;AACvC,8EAAiF;AACjF,2CAAuD;AAEvD,wCAA0C;AAE1C,
|
|
1
|
+
{"version":3,"file":"tracing.module.js","sourceRoot":"","sources":["../../src/tracing/tracing.module.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AACA,2CAAwC;AACxC,uCAA+C;AAC/C,4CAAoD;AACpD,4EAAqF;AACrF,8CAA0D;AAC1D,sFAA4E;AAC5E,gEAA8E;AAC9E,wDAAoD;AACpD,sDAAkD;AAElD,kEAGuC;AACvC,8EAAiF;AACjF,2CAAuD;AAEvD,wCAA0C;AAE1C,wEAAmE;AACnE,6DAAwD;AACxD,iFAA2E;AAC3E,6EAAwE;AACxE,uEAAkE;AAClE,yCAAoD;AACpD,qDAAuD;AACvD,+DAA2D;AASpD,IAAM,aAAa,qBAAnB,MAAM,aAAa;IAEwB;IAC7B;IACA;IACA;IAJnB,YACgD,MAAe,EAC5C,gBAAwC,EACxC,GAAY,EACZ,MAA2B;QAHE,WAAM,GAAN,MAAM,CAAS;QAC5C,qBAAgB,GAAhB,gBAAgB,CAAwB;QACxC,QAAG,GAAH,GAAG,CAAS;QACZ,WAAM,GAAN,MAAM,CAAqB;IAC3C,CAAC;IAEJ,MAAM,CAAC,OAAO,CAAC,OAA6B;QAC1C,OAAO;YACL,MAAM,EAAE,eAAa;YACrB,OAAO,EAAE,CAAC,+CAAqB,EAAE,qCAAgB,CAAC;YAClD,SAAS,EAAE;gBACT,EAAE,OAAO,EAAE,sBAAe,EAAE,QAAQ,EAAE,IAAI,wCAAkB,EAAE,EAAE;gBAChE;oBACE,OAAO,EAAE,sBAAe;oBACxB,QAAQ,EAAE,IAAI,qDAAwB,EAAE;iBACzC;gBACD,iCAAsB;gBACtB,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC;aAChC;SACF,CAAC;IACJ,CAAC;IAED,+DAA+D;IAC/D,KAAK,CAAC,YAAY;QAChB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;YAExC,uBAAa,CAAC,qBAAqB,CAAC,CAAC,MAAM,EAAE,EAAE;gBAC7C,MAAM,CAAC,YAAY,CAAC,GAAG,uCAAiB,CAAC,GAAG,EAAE,CAAC;YACjD,CAAC,CAAC,CAAC;YAEH,OAAO;QACT,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAEvC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACpD,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;QAEjB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACvD,IAAI,CAAC,gBAAgB,CAAC,uBAAuB,EAAE,CAAC;QAEhD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACxD,uBAAa,CAAC,qBAAqB,EAAE,CAAC;QACtC,uBAAa,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YACrC,MAAM,IAAI,GAAG,WAAK,CAAC,OAAO,CAAC,aAAO,CAAC,MAAM,EAAE,CAAC,CAAC;YAE7C,IAAI,EAAE,QAAQ,CAAC,KAAK,EAAE,EAAE,GAAG,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,MAAM,CAAC,iBAAiB,CAAC,OAA6B;QAC5D,OAAO;YACL,OAAO,EAAE,kBAAO;YAEhB,MAAM,EAAE,CAAC,oCAAmB,CAAC;YAC7B,UAAU,EAAE,CAAC,MAA2B,EAAW,EAAE;gBACnD,MAAM,QAAQ,GACZ,OAAO,CAAC,QAAQ;oBAChB,IAAI,4CAAiB,CAAC;wBACpB,GAAG,EAAE,MAAM,CAAC,YAAY,EAAE,QAAQ,EAAE;qBACrC,CAAC,CAAC;gBAEL,MAAM,SAAS,GACb,OAAO,CAAC,UAAU,KAAK,QAAQ;oBAC7B,CAAC,CAAC,IAAI,oCAAmB,CAAC,QAAQ,CAAC;oBACnC,CAAC,CAAC,IAAI,mCAAkB,CAAC,QAAQ,CAAC,CAAC;gBAEvC,OAAO,IAAI,kBAAO,CAAC;oBACjB,mBAAmB,EAAE,IAAI;oBACzB,cAAc,EAAE,IAAI,qDAA+B,EAAE;oBACrD,gBAAgB,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,wDAAyB,CAAC,CAAC,CAAC,CAAC,EAAE;oBACnE,QAAQ,EAAE,IAAI,oBAAQ,CAAC;wBACrB,CAAC,iDAA0B,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC,OAAO;qBAC3D,CAAC;oBACF,aAAa,EAAE,SAAS;oBACxB,iBAAiB,EAAE,IAAI,0BAAmB,CAAC;wBACzC,WAAW,EAAE;4BACX,IAAI,4BAAY,EAAE;4BAClB,IAAI,4BAAY,CAAC;gCACf,cAAc,EAAE,gCAAgB,CAAC,YAAY;6BAC9C,CAAC;yBACH;qBACF,CAAC;iBACH,CAAC,CAAC;YACL,CAAC;SACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,yBAAyB;QAC7B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;QACxD,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;IAC5B,CAAC;CACF,CAAA;AA/FY,sCAAa;wBAAb,aAAa;IADzB,IAAA,eAAM,EAAC,EAAE,CAAC;IAGN,WAAA,IAAA,sBAAY,EAAC,aAAa,CAAC,CAAA;6CACO,iCAAsB;QACnC,kBAAO;QACJ,oCAAmB;GALnC,aAAa,CA+FzB"}
|
package/dist/types/options.d.ts
CHANGED
|
@@ -68,4 +68,6 @@ export interface PlatformOptions extends PlatformManifestPathOptions {
|
|
|
68
68
|
plugins?: PlatformAppPlugin[];
|
|
69
69
|
}
|
|
70
70
|
export type PlatformAppOptions = RequiredFields<PlatformOptions, 'transports' | 'modules'>;
|
|
71
|
-
export type PlatformExtendedOptions = PlatformOptions & ManifestData
|
|
71
|
+
export type PlatformExtendedOptions = PlatformOptions & ManifestData & {
|
|
72
|
+
appScope: string;
|
|
73
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rsdk/core",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.0-next.1",
|
|
4
4
|
"description": "Nestjs based microservice chassis",
|
|
5
5
|
"license": "Apache License 2.0",
|
|
6
6
|
"publishConfig": {
|
|
@@ -32,18 +32,19 @@
|
|
|
32
32
|
"@nestjs/common": "^10.0.0",
|
|
33
33
|
"@nestjs/core": "^10.0.0",
|
|
34
34
|
"@nestjs/microservices": "^10.0.0",
|
|
35
|
-
"@rsdk/
|
|
36
|
-
"@rsdk/
|
|
37
|
-
"@rsdk/common
|
|
38
|
-
"@rsdk/common.
|
|
39
|
-
"@rsdk/
|
|
40
|
-
"@rsdk/
|
|
41
|
-
"@rsdk/
|
|
42
|
-
"@rsdk/
|
|
35
|
+
"@rsdk/actx": "^4.2.0-next.1",
|
|
36
|
+
"@rsdk/autodoc.protocol": "^4.2.0-next.1",
|
|
37
|
+
"@rsdk/common": "^4.2.0-next.1",
|
|
38
|
+
"@rsdk/common.nestjs": "^4.2.0-next.1",
|
|
39
|
+
"@rsdk/common.node": "^4.2.0-next.1",
|
|
40
|
+
"@rsdk/decorators": "^4.2.0-next.1",
|
|
41
|
+
"@rsdk/logging": "^4.2.0-next.1",
|
|
42
|
+
"@rsdk/metadata": "^4.2.0-next.1",
|
|
43
|
+
"@rsdk/nest-tools": "^4.2.0-next.1",
|
|
43
44
|
"axios": "^1.1.3",
|
|
44
45
|
"pino": "^8.16.1",
|
|
45
46
|
"reflect-metadata": "^0.1.13",
|
|
46
47
|
"rxjs": "^7.0.0"
|
|
47
48
|
},
|
|
48
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "e42244b7badde74fec2badc60a85d53878fe75ae"
|
|
49
50
|
}
|
|
@@ -3,7 +3,12 @@ import { Module } from '@nestjs/common';
|
|
|
3
3
|
|
|
4
4
|
import type { PlatformExtendedOptions } from '../types';
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
APP_DESCRIPTION,
|
|
8
|
+
APP_NAME,
|
|
9
|
+
APP_SCOPE,
|
|
10
|
+
APP_VERSION,
|
|
11
|
+
} from './app-metadata.const';
|
|
7
12
|
|
|
8
13
|
@Module({})
|
|
9
14
|
export class AppMetadataModule {
|
|
@@ -13,6 +18,10 @@ export class AppMetadataModule {
|
|
|
13
18
|
provide: APP_NAME,
|
|
14
19
|
useValue: options.name,
|
|
15
20
|
},
|
|
21
|
+
{
|
|
22
|
+
provide: APP_SCOPE,
|
|
23
|
+
useValue: options.appScope,
|
|
24
|
+
},
|
|
16
25
|
{
|
|
17
26
|
provide: APP_DESCRIPTION,
|
|
18
27
|
useValue: options.description,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const APP_NAME_PATTERN =
|
|
1
|
+
export const APP_NAME_PATTERN = /(^[a-z][a-z-]*)\.[.a-z-]*[a-z]$/;
|
package/src/index.ts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import './unhandled-rejection.handler';
|
|
2
2
|
|
|
3
|
+
export { APP_SCOPE } from './app-metadata/app-metadata.const';
|
|
4
|
+
|
|
3
5
|
export { Manifest } from './manifest/manifest';
|
|
4
6
|
|
|
5
7
|
export { ProtocolDetector } from './transport/protocol.detector';
|
|
6
8
|
|
|
7
9
|
export { X_REQUEST_ID } from './tracing/constants';
|
|
8
|
-
|
|
9
10
|
export {
|
|
10
|
-
RequestMetadata,
|
|
11
|
-
RequestMetadataStorage,
|
|
12
11
|
TracingModule,
|
|
13
12
|
saveAsyncHooksContext,
|
|
14
13
|
createSpan,
|
|
@@ -73,3 +72,4 @@ export {
|
|
|
73
72
|
X_B3_SPAN_ID,
|
|
74
73
|
X_B3_TRACE_ID,
|
|
75
74
|
} from '@opentelemetry/propagator-b3';
|
|
75
|
+
export { RequestIdProvider } from './tracing/services/request-id.provider';
|
package/src/platform.context.ts
CHANGED
|
@@ -7,6 +7,8 @@ import { LoggerFactory } from '@rsdk/logging';
|
|
|
7
7
|
import type { RsdkMetadataProvider } from '@rsdk/metadata';
|
|
8
8
|
import { groupBy, intersection } from 'lodash';
|
|
9
9
|
|
|
10
|
+
import { APP_NAME_PATTERN } from './app-metadata/app-name.const';
|
|
11
|
+
import { InvalidAppNameException } from './app-metadata/exceptions';
|
|
10
12
|
import { ConfigMetadataProvider } from './config/metadata/config-metadata.provider';
|
|
11
13
|
import { Manifest } from './manifest/manifest';
|
|
12
14
|
import { assertAppName } from './app-metadata';
|
|
@@ -78,12 +80,18 @@ export class PlatformContext {
|
|
|
78
80
|
const { name, description, version } = manifestData;
|
|
79
81
|
const appName = this.strictnessOptions?.forceAppName ?? name;
|
|
80
82
|
if (this.strictnessOptions?.skipAssertAppName) {
|
|
81
|
-
this.logger.warn('
|
|
83
|
+
this.logger.warn('app name asserting was skipped');
|
|
82
84
|
} else {
|
|
83
85
|
assertAppName(appName);
|
|
84
86
|
}
|
|
85
87
|
|
|
88
|
+
const regexrResult = APP_NAME_PATTERN.exec(name);
|
|
89
|
+
const appScope = regexrResult?.[1];
|
|
90
|
+
if (!regexrResult || !appScope) {
|
|
91
|
+
throw new InvalidAppNameException(name);
|
|
92
|
+
}
|
|
86
93
|
const extendedOptions: PlatformExtendedOptions = {
|
|
94
|
+
appScope,
|
|
87
95
|
description,
|
|
88
96
|
name: appName,
|
|
89
97
|
version,
|
package/src/platform.module.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { DynamicModule, NestModule } from '@nestjs/common';
|
|
2
2
|
import { Inject } from '@nestjs/common';
|
|
3
3
|
import type { MiddlewareConsumer } from '@nestjs/common/interfaces';
|
|
4
|
+
import { AsyncContextModule } from '@rsdk/actx';
|
|
4
5
|
import type { Constructor } from '@rsdk/common';
|
|
5
6
|
|
|
6
7
|
import { PlatformPluginModule } from './plugin/plugin.module';
|
|
@@ -19,13 +20,18 @@ export class PlatformModule implements NestModule {
|
|
|
19
20
|
|
|
20
21
|
static forRoot(options: PlatformExtendedOptions): DynamicModule {
|
|
21
22
|
const imports: (DynamicModule | Constructor)[] = [
|
|
23
|
+
/**
|
|
24
|
+
* Последовательность принципиально важна так как в этом модуле происходит инициализация глобального асинхронного контекста (AsyncLocalStorage)
|
|
25
|
+
*/
|
|
26
|
+
AsyncContextModule,
|
|
27
|
+
TracingModule.forRoot({ appName: options.name, processing: 'simple' }),
|
|
28
|
+
|
|
22
29
|
// Plugins
|
|
23
30
|
PlatformPluginModule.forOptions(options),
|
|
24
31
|
|
|
25
32
|
// Infrastructure
|
|
26
33
|
AppMetadataModule.forRoot(options),
|
|
27
34
|
PlatformConfigModule.forRoot(options),
|
|
28
|
-
TracingModule.forRoot({ appName: options.name, processing: 'simple' }),
|
|
29
35
|
LoggerInitializingModule,
|
|
30
36
|
...(options.modules ?? []),
|
|
31
37
|
];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
|
|
2
2
|
import { ClientRequest, IncomingMessage } from 'node:http';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { RequestIdProvider } from './services/request-id.provider';
|
|
5
5
|
|
|
6
6
|
export const autoInstumentationOptions: any[] = getNodeAutoInstrumentations({
|
|
7
7
|
'@opentelemetry/instrumentation-aws-sdk': {
|
|
@@ -38,8 +38,7 @@ export const autoInstumentationOptions: any[] = getNodeAutoInstrumentations({
|
|
|
38
38
|
'@opentelemetry/instrumentation-pino': {
|
|
39
39
|
enabled: true,
|
|
40
40
|
logHook: (_span, record) => {
|
|
41
|
-
record['request_id'] =
|
|
42
|
-
RequestMetadataStorage.getInstance()?.getRequestMetadata().requestId;
|
|
41
|
+
record['request_id'] = RequestIdProvider.get();
|
|
43
42
|
},
|
|
44
43
|
},
|
|
45
44
|
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Metadata } from '@grpc/grpc-js';
|
|
2
|
+
import type { MaybeReadonlyArray } from '@rsdk/common.node';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @description хелпер для нормализованного извлечения заголовков из grpc запроса
|
|
6
|
+
*/
|
|
7
|
+
export class GrpcHeaders {
|
|
8
|
+
constructor(private metadata: Metadata) {}
|
|
9
|
+
|
|
10
|
+
get<K extends string>(
|
|
11
|
+
key: MaybeReadonlyArray<K>,
|
|
12
|
+
): Record<K, string | undefined>;
|
|
13
|
+
get(key: string): string | undefined;
|
|
14
|
+
get(
|
|
15
|
+
key: string | MaybeReadonlyArray<string>,
|
|
16
|
+
): Record<string, string | undefined> | string | undefined {
|
|
17
|
+
if (Array.isArray(key)) {
|
|
18
|
+
return Object.fromEntries(key.map((k) => [k, this.get(k)])) as Record<
|
|
19
|
+
string,
|
|
20
|
+
any
|
|
21
|
+
>;
|
|
22
|
+
}
|
|
23
|
+
const requestIdMetadata = this.metadata.get(key as string);
|
|
24
|
+
if (requestIdMetadata.length > 0) {
|
|
25
|
+
return requestIdMetadata[0].toString();
|
|
26
|
+
}
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
}
|