@lad-tech/nsc-toolkit 1.27.0 → 1.28.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/CHANGELOG.md +2 -2
- package/dist/Client.js +20 -22
- package/dist/Meter.js +58 -0
- package/dist/Root.js +41 -1
- package/dist/Service.js +66 -18
- package/dist/interfaces.js +7 -1
- package/dist/types/Client.d.ts +1 -1
- package/dist/types/Container.d.ts +3 -1
- package/dist/types/Meter.d.ts +11 -0
- package/dist/types/Root.d.ts +3 -1
- package/dist/types/Service.d.ts +5 -1
- package/dist/types/StreamOptions/BufferToJsonTransform.d.ts +1 -0
- package/dist/types/Union/Subscription.d.ts +1 -1
- package/dist/types/interfaces.d.ts +22 -0
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# [1.
|
|
1
|
+
# [1.28.0](https://github.com/lad-tech/nsc-toolkit/compare/v1.27.0...v1.28.0) (2025-05-12)
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
### Features
|
|
5
5
|
|
|
6
|
-
*
|
|
6
|
+
* Async event traces and tags ([#145](https://github.com/lad-tech/nsc-toolkit/issues/145)) ([02c3560](https://github.com/lad-tech/nsc-toolkit/commit/02c356051d295d528c4cc7758b2a310d37074424))
|
package/dist/Client.js
CHANGED
|
@@ -10,6 +10,7 @@ const node_stream_1 = require("node:stream");
|
|
|
10
10
|
const promises_1 = require("node:timers/promises");
|
|
11
11
|
const Root_1 = require("./Root");
|
|
12
12
|
const StreamManager_1 = require("./StreamManager");
|
|
13
|
+
const Meter_1 = require("./Meter");
|
|
13
14
|
class Client extends Root_1.Root {
|
|
14
15
|
constructor({ broker, events, loggerOutputFormatter, serviceName, baggage, cache, Ref }) {
|
|
15
16
|
super(broker, loggerOutputFormatter);
|
|
@@ -35,6 +36,11 @@ class Client extends Root_1.Root {
|
|
|
35
36
|
data = (0, nats_1.StringCodec)().decode(event.data);
|
|
36
37
|
}
|
|
37
38
|
const message = { data };
|
|
39
|
+
let baggage;
|
|
40
|
+
if (event.headers) {
|
|
41
|
+
baggage = this.getBaggageFromNATSHeader(event.headers);
|
|
42
|
+
}
|
|
43
|
+
message.meter = new Meter_1.Meter(eventName, baggage);
|
|
38
44
|
if (this.isJsMessage(event)) {
|
|
39
45
|
message.ack = event.ack.bind(event);
|
|
40
46
|
message.nak = event.nak.bind(event);
|
|
@@ -264,31 +270,23 @@ class Client extends Root_1.Root {
|
|
|
264
270
|
request.end();
|
|
265
271
|
});
|
|
266
272
|
}
|
|
267
|
-
convertBaggaggeToExternalHeader(baggage) {
|
|
268
|
-
if (!baggage) {
|
|
269
|
-
return {};
|
|
270
|
-
}
|
|
271
|
-
const headers = {};
|
|
272
|
-
if (baggage.expired) {
|
|
273
|
-
headers['nsc-expired'] = baggage.expired;
|
|
274
|
-
}
|
|
275
|
-
if (baggage.requestId) {
|
|
276
|
-
headers['x-request-id'] = baggage.requestId;
|
|
277
|
-
}
|
|
278
|
-
if (baggage.traceId) {
|
|
279
|
-
headers['nsc-trace-id'] = baggage.traceId;
|
|
280
|
-
}
|
|
281
|
-
if (baggage.spanId) {
|
|
282
|
-
headers['nsc-span-id'] = baggage.spanId;
|
|
283
|
-
}
|
|
284
|
-
if (baggage.traceFlags) {
|
|
285
|
-
headers['nsc-trace-flags'] = baggage.traceFlags;
|
|
286
|
-
}
|
|
287
|
-
return headers;
|
|
288
|
-
}
|
|
289
273
|
isJsMessage(message) {
|
|
290
274
|
return !!message.ack && !!message.nak;
|
|
291
275
|
}
|
|
276
|
+
getBaggageFromNATSHeader(headers) {
|
|
277
|
+
const traceId = headers.get('nsc-trace-id');
|
|
278
|
+
const spanId = headers.get('nsc-span-id');
|
|
279
|
+
const traceFlags = headers.has('nsc-trace-flags') ? +headers.get('nsc-trace-flags') : undefined;
|
|
280
|
+
const requestId = headers.has('x-request-id') ? String(headers.get('x-request-id')) : undefined;
|
|
281
|
+
if (traceId && spanId && traceFlags) {
|
|
282
|
+
return {
|
|
283
|
+
traceId,
|
|
284
|
+
spanId,
|
|
285
|
+
traceFlags,
|
|
286
|
+
requestId,
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
}
|
|
292
290
|
}
|
|
293
291
|
exports.Client = Client;
|
|
294
292
|
//# sourceMappingURL=Client.js.map
|
package/dist/Meter.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Meter = void 0;
|
|
4
|
+
const interfaces_1 = require("./interfaces");
|
|
5
|
+
const opentelemetry = require("@opentelemetry/api");
|
|
6
|
+
const Root_1 = require("./Root");
|
|
7
|
+
class Meter extends Root_1.Root {
|
|
8
|
+
constructor(name, baggage) {
|
|
9
|
+
super();
|
|
10
|
+
this.name = name;
|
|
11
|
+
this.baggage = baggage;
|
|
12
|
+
}
|
|
13
|
+
start() {
|
|
14
|
+
const tracer = opentelemetry.trace.getTracer('');
|
|
15
|
+
this.span = tracer.startSpan(this.name, { kind: opentelemetry.SpanKind.CONSUMER }, this.getContext(this.baggage));
|
|
16
|
+
}
|
|
17
|
+
end(error) {
|
|
18
|
+
if (!this.span) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (error) {
|
|
22
|
+
this.span.setAttribute('error', true);
|
|
23
|
+
this.span.setAttribute('error.kind', error.message);
|
|
24
|
+
}
|
|
25
|
+
this.span.end();
|
|
26
|
+
}
|
|
27
|
+
measure(func, arg, context, tag) {
|
|
28
|
+
const tracer = opentelemetry.trace.getTracer('');
|
|
29
|
+
let spanContext;
|
|
30
|
+
if (this.span) {
|
|
31
|
+
spanContext = opentelemetry.trace.setSpan(opentelemetry.context.active(), this.span);
|
|
32
|
+
}
|
|
33
|
+
const options = { kind: opentelemetry.SpanKind.INTERNAL };
|
|
34
|
+
if ((tag === null || tag === void 0 ? void 0 : tag[interfaces_1.TagKey.LOCATION]) === 'external') {
|
|
35
|
+
options.kind = opentelemetry.SpanKind.CLIENT;
|
|
36
|
+
}
|
|
37
|
+
const span = tracer.startSpan(func.name, options, spanContext);
|
|
38
|
+
this.applyTag(span, tag);
|
|
39
|
+
const result = func.apply(context, arg);
|
|
40
|
+
if (result.then) {
|
|
41
|
+
return result.then((result) => {
|
|
42
|
+
span.end();
|
|
43
|
+
return result;
|
|
44
|
+
}, (error) => {
|
|
45
|
+
span.setAttribute('error', true);
|
|
46
|
+
span.setAttribute('error.kind', error.message);
|
|
47
|
+
span.end();
|
|
48
|
+
throw error;
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
span.end();
|
|
53
|
+
}
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
exports.Meter = Meter;
|
|
58
|
+
//# sourceMappingURL=Meter.js.map
|
package/dist/Root.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Root = void 0;
|
|
4
4
|
const toolbelt_1 = require("@lad-tech/toolbelt");
|
|
5
5
|
const opentelemetry = require("@opentelemetry/api");
|
|
6
|
+
const interfaces_1 = require("./interfaces");
|
|
6
7
|
const Union_1 = require("./Union");
|
|
7
8
|
class Root {
|
|
8
9
|
constructor(broker, outputFormatter) {
|
|
@@ -52,7 +53,7 @@ class Root {
|
|
|
52
53
|
return expired;
|
|
53
54
|
}
|
|
54
55
|
catch (error) {
|
|
55
|
-
|
|
56
|
+
this.logger.error(error);
|
|
56
57
|
process.exit(1);
|
|
57
58
|
}
|
|
58
59
|
}
|
|
@@ -75,6 +76,45 @@ class Root {
|
|
|
75
76
|
},
|
|
76
77
|
};
|
|
77
78
|
}
|
|
79
|
+
convertBaggaggeToExternalHeader(baggage) {
|
|
80
|
+
if (!baggage) {
|
|
81
|
+
return {};
|
|
82
|
+
}
|
|
83
|
+
const headers = {};
|
|
84
|
+
if (baggage.expired) {
|
|
85
|
+
headers['nsc-expired'] = baggage.expired;
|
|
86
|
+
}
|
|
87
|
+
if (baggage.requestId) {
|
|
88
|
+
headers['x-request-id'] = baggage.requestId;
|
|
89
|
+
}
|
|
90
|
+
if (baggage.traceId) {
|
|
91
|
+
headers['nsc-trace-id'] = baggage.traceId;
|
|
92
|
+
}
|
|
93
|
+
if (baggage.spanId) {
|
|
94
|
+
headers['nsc-span-id'] = baggage.spanId;
|
|
95
|
+
}
|
|
96
|
+
if (baggage.traceFlags) {
|
|
97
|
+
headers['nsc-trace-flags'] = baggage.traceFlags;
|
|
98
|
+
}
|
|
99
|
+
return headers;
|
|
100
|
+
}
|
|
101
|
+
applyTag(span, tag) {
|
|
102
|
+
if (!tag) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if ((tag === null || tag === void 0 ? void 0 : tag[interfaces_1.TagKey.TYPE]) === 'dbms') {
|
|
106
|
+
span.setAttribute('db.system', tag === null || tag === void 0 ? void 0 : tag[interfaces_1.TagKey.NAME]);
|
|
107
|
+
if (tag === null || tag === void 0 ? void 0 : tag[interfaces_1.TagKey.TARGET]) {
|
|
108
|
+
span.setAttribute('db.name', tag[interfaces_1.TagKey.TARGET]);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if ((tag === null || tag === void 0 ? void 0 : tag[interfaces_1.TagKey.TYPE]) === 'api') {
|
|
112
|
+
span.setAttribute('net.peer.name', tag === null || tag === void 0 ? void 0 : tag[interfaces_1.TagKey.NAME]);
|
|
113
|
+
if (tag === null || tag === void 0 ? void 0 : tag[interfaces_1.TagKey.TARGET]) {
|
|
114
|
+
span.setAttribute('http.target', tag[interfaces_1.TagKey.TARGET]);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
78
118
|
}
|
|
79
119
|
exports.Root = Root;
|
|
80
120
|
//# sourceMappingURL=Root.js.map
|
package/dist/Service.js
CHANGED
|
@@ -44,11 +44,12 @@ class Service extends Root_1.Root {
|
|
|
44
44
|
if (options.events) {
|
|
45
45
|
const events = Object.keys(options.events.list);
|
|
46
46
|
this.emitter = events.reduce((result, eventName) => {
|
|
47
|
-
result[eventName] = ((params, uniqId, rollupId) => {
|
|
47
|
+
result[eventName] = ((params, uniqId, rollupId, external) => {
|
|
48
48
|
var _a, _b, _c;
|
|
49
49
|
const subject = [options.name];
|
|
50
50
|
const eventOptions = (_a = options.events) === null || _a === void 0 ? void 0 : _a.list[eventName];
|
|
51
|
-
|
|
51
|
+
const isStream = (_b = eventOptions === null || eventOptions === void 0 ? void 0 : eventOptions.options) === null || _b === void 0 ? void 0 : _b.stream;
|
|
52
|
+
if (isStream) {
|
|
52
53
|
const prefix = (_c = options.events) === null || _c === void 0 ? void 0 : _c.streamOptions.prefix;
|
|
53
54
|
if (!prefix) {
|
|
54
55
|
throw new Error(`Stream prefix not set for event ${String(eventName)} marked as stream`);
|
|
@@ -61,14 +62,32 @@ class Service extends Root_1.Root {
|
|
|
61
62
|
settings = { headers: (0, nats_1.headers)() };
|
|
62
63
|
settings.headers.append(this.UNIQ_ID_HEADER, uniqId);
|
|
63
64
|
}
|
|
64
|
-
if (rollupId) {
|
|
65
|
+
if (rollupId && isStream) {
|
|
65
66
|
settings = settings !== null && settings !== void 0 ? settings : { headers: (0, nats_1.headers)() };
|
|
66
67
|
settings.headers.append(this.ROLLUP_HEADER, this.ROLLUP_STRATEGY);
|
|
67
68
|
subject.push(rollupId);
|
|
68
69
|
}
|
|
69
|
-
else {
|
|
70
|
+
else if (rollupId && !isStream) {
|
|
71
|
+
this.logger.warn(`${String(eventName)}. Rollup is available only for streams`);
|
|
72
|
+
}
|
|
73
|
+
else if (isStream) {
|
|
70
74
|
subject.push(this.BASE_EVENT_SUFFIX);
|
|
71
75
|
}
|
|
76
|
+
if (external) {
|
|
77
|
+
const baggage = this.getBaggageFromExternalHeader(external);
|
|
78
|
+
const tracer = api_1.trace.getTracer('');
|
|
79
|
+
const context = this.getContext(this.isBaggageContainTrace(baggage) ? baggage : undefined);
|
|
80
|
+
const span = tracer.startSpan(String(eventName), { kind: api_1.SpanKind.PRODUCER }, context);
|
|
81
|
+
const eventSpanContext = span.spanContext();
|
|
82
|
+
const eventHeader = this.convertBaggaggeToExternalHeader(eventSpanContext);
|
|
83
|
+
if (!settings) {
|
|
84
|
+
settings = { headers: (0, nats_1.headers)() };
|
|
85
|
+
}
|
|
86
|
+
for (const [key, value] of Object.entries(eventHeader)) {
|
|
87
|
+
settings.headers.append(key, `${value}`);
|
|
88
|
+
}
|
|
89
|
+
span.end();
|
|
90
|
+
}
|
|
72
91
|
this.broker.publish(subject.join('.'), this.buildMessage(params), settings);
|
|
73
92
|
});
|
|
74
93
|
return result;
|
|
@@ -97,41 +116,42 @@ class Service extends Root_1.Root {
|
|
|
97
116
|
provider.addSpanProcessor(new sdk_trace_base_1.SimpleSpanProcessor(exporter));
|
|
98
117
|
provider.register();
|
|
99
118
|
}
|
|
100
|
-
finishSpan(span, error) {
|
|
119
|
+
finishSpan(span, error, tag) {
|
|
101
120
|
if (error) {
|
|
102
121
|
span.setAttribute('error', true);
|
|
103
122
|
span.setAttribute('error.kind', error.message);
|
|
104
123
|
}
|
|
124
|
+
this.applyTag(span, tag);
|
|
105
125
|
span.end();
|
|
106
126
|
}
|
|
107
127
|
/**
|
|
108
128
|
* Wrapper for async methods. Create span
|
|
109
129
|
*/
|
|
110
|
-
perform(func, funcContext, arg, tracer, context) {
|
|
130
|
+
perform(func, funcContext, arg, tracer, context, tag) {
|
|
111
131
|
const span = tracer.startSpan(func.name, undefined, context);
|
|
112
132
|
try {
|
|
113
133
|
const result = func.apply(funcContext, arg);
|
|
114
134
|
if (result.then) {
|
|
115
135
|
return result.then((result) => {
|
|
116
|
-
this.finishSpan(span);
|
|
136
|
+
this.finishSpan(span, undefined, tag);
|
|
117
137
|
return result;
|
|
118
138
|
}, (error) => {
|
|
119
|
-
this.finishSpan(span, error);
|
|
139
|
+
this.finishSpan(span, error, tag);
|
|
120
140
|
throw error;
|
|
121
141
|
});
|
|
122
142
|
}
|
|
123
|
-
this.finishSpan(span);
|
|
143
|
+
this.finishSpan(span, undefined, tag);
|
|
124
144
|
return result;
|
|
125
145
|
}
|
|
126
146
|
catch (error) {
|
|
127
|
-
this.finishSpan(span, error);
|
|
147
|
+
this.finishSpan(span, error, tag);
|
|
128
148
|
throw error;
|
|
129
149
|
}
|
|
130
150
|
}
|
|
131
151
|
/**
|
|
132
152
|
* Build trap for object with async methods
|
|
133
153
|
*/
|
|
134
|
-
getTrap(instance, tracer, baggage) {
|
|
154
|
+
getTrap(instance, tracer, baggage, tag) {
|
|
135
155
|
const perform = this.perform.bind(this);
|
|
136
156
|
const context = this.getContext(baggage);
|
|
137
157
|
return {
|
|
@@ -139,7 +159,7 @@ class Service extends Root_1.Root {
|
|
|
139
159
|
const method = Reflect.get(target, propKey, receiver);
|
|
140
160
|
if (typeof method === 'function') {
|
|
141
161
|
return function (...args) {
|
|
142
|
-
return perform(method, instance, args, tracer, context);
|
|
162
|
+
return perform(method, instance, args, tracer, context, tag);
|
|
143
163
|
};
|
|
144
164
|
}
|
|
145
165
|
else {
|
|
@@ -154,11 +174,13 @@ class Service extends Root_1.Root {
|
|
|
154
174
|
createObjectWithDependencies(method, tracer, baggage) {
|
|
155
175
|
const services = _1.ServiceContainer.get(method.settings.action) || new Map();
|
|
156
176
|
const instances = _1.InstanceContainer.get(method.settings.action) || new Map();
|
|
177
|
+
const tags = new Map();
|
|
157
178
|
const dependences = { [_1.ConstructorDependencyKey]: [] };
|
|
158
179
|
const dependencyStorage = Reflect.getMetadata(_1.dependencyStorageMetaKey, method);
|
|
159
180
|
if (dependencyStorage && dependencyStorage.size) {
|
|
160
181
|
// for constructor
|
|
161
182
|
dependencyStorage.forEach((dependencyKey, propertyName) => {
|
|
183
|
+
var _a;
|
|
162
184
|
if (Array.isArray(dependencyKey)) {
|
|
163
185
|
if (propertyName === _1.ConstructorDependencyKey) {
|
|
164
186
|
dependencyKey.forEach((item, index) => {
|
|
@@ -184,6 +206,9 @@ class Service extends Root_1.Root {
|
|
|
184
206
|
}
|
|
185
207
|
if (dependency.type === _1.DependencyType.ADAPTER) {
|
|
186
208
|
instances.set(propertyName, _1.container.getInstance(dependencyKey));
|
|
209
|
+
if ((_a = dependency.options) === null || _a === void 0 ? void 0 : _a.tag) {
|
|
210
|
+
tags.set(propertyName, dependency.options.tag);
|
|
211
|
+
}
|
|
187
212
|
}
|
|
188
213
|
if (dependency.type === _1.DependencyType.CONSTANT) {
|
|
189
214
|
dependences[propertyName] = dependency.value;
|
|
@@ -197,7 +222,7 @@ class Service extends Root_1.Root {
|
|
|
197
222
|
}
|
|
198
223
|
if (instances.size) {
|
|
199
224
|
instances.forEach((instance, key) => {
|
|
200
|
-
const trap = this.getTrap(instance, tracer, baggage);
|
|
225
|
+
const trap = this.getTrap(instance, tracer, baggage, tags.get(key));
|
|
201
226
|
dependences[key] = new Proxy(instance, trap);
|
|
202
227
|
});
|
|
203
228
|
}
|
|
@@ -231,7 +256,7 @@ class Service extends Root_1.Root {
|
|
|
231
256
|
* If there is no baggage. For example, in HTTP Gateway
|
|
232
257
|
*/
|
|
233
258
|
getRootBaggage(subject, headers, ownTimeout) {
|
|
234
|
-
const baggage = headers ? this.
|
|
259
|
+
const baggage = headers ? this.getBaggageFromExternalHeader(headers) : undefined;
|
|
235
260
|
const tracer = api_1.trace.getTracer('');
|
|
236
261
|
const context = this.getContext(this.isBaggageContainTrace(baggage) ? baggage : undefined);
|
|
237
262
|
const span = tracer.startSpan(subject, undefined, context);
|
|
@@ -328,7 +353,7 @@ class Service extends Root_1.Root {
|
|
|
328
353
|
if (other.length || wrongServiceName || !Method) {
|
|
329
354
|
throw new Error('Wrong url or service name or action');
|
|
330
355
|
}
|
|
331
|
-
const baggage = this.
|
|
356
|
+
const baggage = this.getBaggageFromExternalHeader(request.headers);
|
|
332
357
|
if ((_b = (_a = Method.settings.options) === null || _a === void 0 ? void 0 : _a.useStream) === null || _b === void 0 ? void 0 : _b.request) {
|
|
333
358
|
const result = await this.handled(request, Method, baggage);
|
|
334
359
|
if (Method.settings.options.useStream.response && result.payload instanceof node_stream_1.Readable) {
|
|
@@ -373,11 +398,12 @@ class Service extends Root_1.Root {
|
|
|
373
398
|
metadata: baggage,
|
|
374
399
|
outputFormatter: this.options.loggerOutputFormatter,
|
|
375
400
|
});
|
|
401
|
+
const nextBaggage = this.getNextBaggage(span, baggage);
|
|
376
402
|
try {
|
|
377
|
-
const requestedDependencies = this.createObjectWithDependencies(Method, tracer,
|
|
403
|
+
const requestedDependencies = this.createObjectWithDependencies(Method, tracer, nextBaggage);
|
|
378
404
|
const context = this.createMethodContext(Method, requestedDependencies);
|
|
379
405
|
context['logger'] = logger;
|
|
380
|
-
context['emitter'] = this.
|
|
406
|
+
context['emitter'] = this.getWrappedEmitter(nextBaggage);
|
|
381
407
|
const response = await context.handler.call(context, payload);
|
|
382
408
|
const result = {
|
|
383
409
|
payload: response,
|
|
@@ -393,6 +419,28 @@ class Service extends Root_1.Root {
|
|
|
393
419
|
return this.buildErrorMessage(error);
|
|
394
420
|
}
|
|
395
421
|
}
|
|
422
|
+
/**
|
|
423
|
+
* Wrap emitter for luggage baggagge
|
|
424
|
+
*/
|
|
425
|
+
getWrappedEmitter(baggage) {
|
|
426
|
+
if (!baggage) {
|
|
427
|
+
return this.emitter;
|
|
428
|
+
}
|
|
429
|
+
const externalBaggage = this.convertBaggaggeToExternalHeader(baggage);
|
|
430
|
+
return new Proxy(this.emitter, {
|
|
431
|
+
get(target, propKey, receiver) {
|
|
432
|
+
const event = Reflect.get(target, propKey, receiver);
|
|
433
|
+
if (typeof event === 'function') {
|
|
434
|
+
return (params, uniqId, rollupId, userExternalBaggage) => {
|
|
435
|
+
return event(params, uniqId, rollupId, userExternalBaggage !== null && userExternalBaggage !== void 0 ? userExternalBaggage : externalBaggage);
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
else {
|
|
439
|
+
return event;
|
|
440
|
+
}
|
|
441
|
+
},
|
|
442
|
+
});
|
|
443
|
+
}
|
|
396
444
|
/**
|
|
397
445
|
* Make error object if error instance of Error object for logger
|
|
398
446
|
*/
|
|
@@ -607,7 +655,7 @@ class Service extends Root_1.Root {
|
|
|
607
655
|
port: this.httpPort,
|
|
608
656
|
};
|
|
609
657
|
}
|
|
610
|
-
|
|
658
|
+
getBaggageFromExternalHeader(headers) {
|
|
611
659
|
const expired = headers['nsc-expired'] ? +headers['nsc-expired'] : undefined;
|
|
612
660
|
const traceId = headers['nsc-trace-id'];
|
|
613
661
|
const spanId = headers['nsc-span-id'];
|
package/dist/interfaces.js
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// COMMON
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.DependencyType = void 0;
|
|
4
|
+
exports.TagKey = exports.DependencyType = void 0;
|
|
5
5
|
exports.DependencyType = {
|
|
6
6
|
SERVICE: 'service',
|
|
7
7
|
ADAPTER: 'adapter',
|
|
8
8
|
CONSTANT: 'constant', // Just an object
|
|
9
9
|
};
|
|
10
|
+
exports.TagKey = {
|
|
11
|
+
LOCATION: 'location',
|
|
12
|
+
TYPE: 'type',
|
|
13
|
+
NAME: 'name',
|
|
14
|
+
TARGET: 'target',
|
|
15
|
+
};
|
|
10
16
|
//# sourceMappingURL=interfaces.js.map
|
package/dist/types/Client.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ export declare class Client<E extends Emitter = Emitter> extends Root {
|
|
|
26
26
|
private isStream;
|
|
27
27
|
private makeBrokerRequest;
|
|
28
28
|
private makeHttpRequest;
|
|
29
|
-
private convertBaggaggeToExternalHeader;
|
|
30
29
|
private isJsMessage;
|
|
30
|
+
private getBaggageFromNATSHeader;
|
|
31
31
|
}
|
|
32
32
|
export {};
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { ClientService, DependencyType, InitializableService } from '.';
|
|
1
|
+
import { ClientService, DependencyType, InitializableService, Tag } from '.';
|
|
2
2
|
type Constant = Record<string, any>;
|
|
3
3
|
type Service<R extends Constant = Constant> = ClientService<R>;
|
|
4
4
|
export type Adapter<R extends Constant = Constant> = new (...args: any[]) => R;
|
|
5
5
|
export type Singlton = {
|
|
6
6
|
singlton: true;
|
|
7
|
+
tag?: Tag;
|
|
7
8
|
};
|
|
8
9
|
export type NeedInit = {
|
|
9
10
|
init: true;
|
|
11
|
+
tag?: Tag;
|
|
10
12
|
};
|
|
11
13
|
export type AdapterOptions = Singlton | NeedInit;
|
|
12
14
|
type Dependency = Service | Adapter | Constant;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Baggage, EventMeter, Tag } from './interfaces';
|
|
2
|
+
import { Root } from './Root';
|
|
3
|
+
export declare class Meter extends Root implements EventMeter {
|
|
4
|
+
private name;
|
|
5
|
+
private baggage?;
|
|
6
|
+
private span?;
|
|
7
|
+
constructor(name: string, baggage?: Baggage | undefined);
|
|
8
|
+
start(): void;
|
|
9
|
+
end(error?: Error): void;
|
|
10
|
+
measure<T extends (...args: any[]) => any>(func: T, arg: Parameters<T>, context: unknown, tag?: Tag): ReturnType<T>;
|
|
11
|
+
}
|
package/dist/types/Root.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Logs } from '@lad-tech/toolbelt';
|
|
2
2
|
import * as opentelemetry from '@opentelemetry/api';
|
|
3
3
|
import type { NatsConnection } from 'nats';
|
|
4
|
-
import type
|
|
4
|
+
import { type Baggage, type ExternalBaggage, type Tag } from './interfaces';
|
|
5
5
|
import { Broker } from './Union';
|
|
6
6
|
export declare class Root {
|
|
7
7
|
protected readonly SERVICE_SUBJECT_FOR_GET_HTTP_SETTINGS = "get_http_settings";
|
|
@@ -24,4 +24,6 @@ export declare class Root {
|
|
|
24
24
|
code: number | undefined;
|
|
25
25
|
};
|
|
26
26
|
};
|
|
27
|
+
protected convertBaggaggeToExternalHeader(baggage?: Partial<Baggage>): ExternalBaggage;
|
|
28
|
+
protected applyTag(span: opentelemetry.Span, tag?: Tag): void;
|
|
27
29
|
}
|
package/dist/types/Service.d.ts
CHANGED
|
@@ -88,6 +88,10 @@ export declare class Service<E extends Emitter = Emitter> extends Root {
|
|
|
88
88
|
* Run business logic for request
|
|
89
89
|
*/
|
|
90
90
|
private handled;
|
|
91
|
+
/**
|
|
92
|
+
* Wrap emitter for luggage baggagge
|
|
93
|
+
*/
|
|
94
|
+
private getWrappedEmitter;
|
|
91
95
|
/**
|
|
92
96
|
* Make error object if error instance of Error object for logger
|
|
93
97
|
*/
|
|
@@ -132,5 +136,5 @@ export declare class Service<E extends Emitter = Emitter> extends Root {
|
|
|
132
136
|
private upHTTPServer;
|
|
133
137
|
private getMyIpV4;
|
|
134
138
|
private getHttpSettings;
|
|
135
|
-
private
|
|
139
|
+
private getBaggageFromExternalHeader;
|
|
136
140
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
/// <reference types="node" />
|
|
3
|
+
/// <reference types="node" />
|
|
3
4
|
import { Logs } from '@lad-tech/toolbelt';
|
|
4
5
|
import { Transform, TransformCallback, TransformOptions } from 'stream';
|
|
5
6
|
export declare class BufferToJsonTransform<T = any> extends Transform {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { Closed, ConsumerInfoable, Destroyable, Msg, NatsError, Subscription } from 'nats';
|
|
3
3
|
import { PassThrough } from 'node:stream';
|
|
4
4
|
export declare class UnionSubscription extends PassThrough implements Subscription, Destroyable, Closed, ConsumerInfoable {
|
|
5
|
-
closed:
|
|
5
|
+
closed: any;
|
|
6
6
|
unsubscribe(max?: number): void;
|
|
7
7
|
drain(): Promise<void>;
|
|
8
8
|
isDraining(): boolean;
|
|
@@ -85,10 +85,12 @@ export interface StreamManagerParam {
|
|
|
85
85
|
}
|
|
86
86
|
export interface EmitterEvent<D extends Record<string, any>> {
|
|
87
87
|
data: D;
|
|
88
|
+
meter: EventMeter;
|
|
88
89
|
}
|
|
89
90
|
export interface EmitterStreamEvent<D extends Record<string, any>> extends EmitterEvent<D> {
|
|
90
91
|
ack: () => void;
|
|
91
92
|
nak: (millis: number) => void;
|
|
93
|
+
meter: EventMeter;
|
|
92
94
|
}
|
|
93
95
|
export interface StreamAction {
|
|
94
96
|
action: string;
|
|
@@ -157,3 +159,23 @@ export declare const DependencyType: {
|
|
|
157
159
|
readonly ADAPTER: "adapter";
|
|
158
160
|
readonly CONSTANT: "constant";
|
|
159
161
|
};
|
|
162
|
+
export type TagKey = typeof TagKey[keyof typeof TagKey];
|
|
163
|
+
export declare const TagKey: {
|
|
164
|
+
readonly LOCATION: "location";
|
|
165
|
+
readonly TYPE: "type";
|
|
166
|
+
readonly NAME: "name";
|
|
167
|
+
readonly TARGET: "target";
|
|
168
|
+
};
|
|
169
|
+
export type LocationTagValue = 'internal' | 'external';
|
|
170
|
+
export type TypeTagValue = 'dbms' | 'api';
|
|
171
|
+
export type Tag = {
|
|
172
|
+
[TagKey.LOCATION]: LocationTagValue;
|
|
173
|
+
[TagKey.TYPE]: TypeTagValue;
|
|
174
|
+
[TagKey.NAME]: string;
|
|
175
|
+
[TagKey.TARGET]?: string;
|
|
176
|
+
};
|
|
177
|
+
export interface EventMeter {
|
|
178
|
+
start(): void;
|
|
179
|
+
end(): void;
|
|
180
|
+
measure<T extends (...args: any[]) => any>(func: T, arg: Parameters<T>, context: any, tag?: Tag): ReturnType<T>;
|
|
181
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lad-tech/nsc-toolkit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.28.0",
|
|
4
4
|
"description": "Toolkit for create microservices around NATS",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "./dist/types/index.d.ts",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"@semantic-release/changelog": "^6.0.2",
|
|
18
18
|
"@semantic-release/npm": "^9.0.1",
|
|
19
19
|
"@types/jest": "^27.5.2",
|
|
20
|
-
"@types/node": "^
|
|
20
|
+
"@types/node": "^22.13.13",
|
|
21
21
|
"eslint": "^7.32.0",
|
|
22
22
|
"eslint-config-airbnb-base": "^15.0.0",
|
|
23
23
|
"eslint-config-prettier": "^8.5.0",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"@opentelemetry/sdk-trace-base": "^1.3.1",
|
|
42
42
|
"@opentelemetry/semantic-conventions": "^1.3.1",
|
|
43
43
|
"ajv": "^8.11.0",
|
|
44
|
-
"nats": "^2.
|
|
44
|
+
"nats": "^2.29.3",
|
|
45
45
|
"reflect-metadata": "^0.1.13"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|