autotel-plugins 0.19.25 → 0.19.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bigquery.cjs +393 -309
- package/dist/bigquery.d.cts +56 -44
- package/dist/bigquery.d.ts +56 -44
- package/dist/bigquery.js +389 -308
- package/dist/constants-DKKe2D25.d.cts +94 -47
- package/dist/constants-DKKe2D25.d.ts +94 -47
- package/dist/index.cjs +853 -627
- package/dist/index.d.cts +124 -4
- package/dist/index.d.ts +124 -4
- package/dist/index.js +856 -598
- package/dist/kafka.cjs +330 -226
- package/dist/kafka.d.cts +458 -345
- package/dist/kafka.d.ts +458 -345
- package/dist/kafka.js +326 -210
- package/dist/rabbitmq.cjs +117 -84
- package/dist/rabbitmq.d.cts +218 -151
- package/dist/rabbitmq.d.ts +218 -151
- package/dist/rabbitmq.js +129 -79
- package/package.json +2 -2
package/dist/kafka.js
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
propagation,
|
|
3
|
+
ROOT_CONTEXT,
|
|
4
|
+
otelTrace,
|
|
5
|
+
context,
|
|
6
|
+
SpanKind,
|
|
7
|
+
SpanStatusCode,
|
|
8
|
+
} from 'autotel';
|
|
2
9
|
import { metrics } from '@opentelemetry/api';
|
|
3
10
|
|
|
4
11
|
// src/kafka/headers.ts
|
|
@@ -12,7 +19,7 @@ function normalizeHeaders(headers) {
|
|
|
12
19
|
if (value === void 0) {
|
|
13
20
|
continue;
|
|
14
21
|
}
|
|
15
|
-
normalized[key] = Buffer.isBuffer(value) ? value.toString(
|
|
22
|
+
normalized[key] = Buffer.isBuffer(value) ? value.toString('utf8') : value;
|
|
16
23
|
}
|
|
17
24
|
return normalized;
|
|
18
25
|
}
|
|
@@ -28,39 +35,44 @@ var caseInsensitiveGetter = {
|
|
|
28
35
|
},
|
|
29
36
|
keys(carrier) {
|
|
30
37
|
return Object.keys(carrier);
|
|
31
|
-
}
|
|
38
|
+
},
|
|
32
39
|
};
|
|
33
40
|
function extractTraceContext(headers) {
|
|
34
41
|
return propagation.extract(ROOT_CONTEXT, headers, caseInsensitiveGetter);
|
|
35
42
|
}
|
|
36
43
|
|
|
37
44
|
// src/common/constants.ts
|
|
38
|
-
var SEMATTRS_MESSAGING_SYSTEM =
|
|
39
|
-
var SEMATTRS_MESSAGING_DESTINATION_NAME =
|
|
40
|
-
var SEMATTRS_MESSAGING_OPERATION =
|
|
41
|
-
var SEMATTRS_MESSAGING_KAFKA_CONSUMER_GROUP =
|
|
42
|
-
var SEMATTRS_MESSAGING_KAFKA_PARTITION =
|
|
43
|
-
var SEMATTRS_MESSAGING_KAFKA_OFFSET =
|
|
44
|
-
var SEMATTRS_MESSAGING_KAFKA_MESSAGE_KEY =
|
|
45
|
-
var SEMATTRS_LINKED_TRACE_ID_COUNT =
|
|
46
|
-
var SEMATTRS_LINKED_TRACE_ID_HASH =
|
|
47
|
-
var CORRELATION_ID_HEADER =
|
|
48
|
-
var SEMATTRS_MESSAGING_BATCH_MESSAGE_COUNT =
|
|
49
|
-
var SEMATTRS_MESSAGING_KAFKA_BATCH_FIRST_OFFSET =
|
|
50
|
-
|
|
51
|
-
var
|
|
52
|
-
|
|
53
|
-
var
|
|
45
|
+
var SEMATTRS_MESSAGING_SYSTEM = 'messaging.system';
|
|
46
|
+
var SEMATTRS_MESSAGING_DESTINATION_NAME = 'messaging.destination.name';
|
|
47
|
+
var SEMATTRS_MESSAGING_OPERATION = 'messaging.operation';
|
|
48
|
+
var SEMATTRS_MESSAGING_KAFKA_CONSUMER_GROUP = 'messaging.kafka.consumer.group';
|
|
49
|
+
var SEMATTRS_MESSAGING_KAFKA_PARTITION = 'messaging.kafka.partition';
|
|
50
|
+
var SEMATTRS_MESSAGING_KAFKA_OFFSET = 'messaging.kafka.offset';
|
|
51
|
+
var SEMATTRS_MESSAGING_KAFKA_MESSAGE_KEY = 'messaging.kafka.message.key';
|
|
52
|
+
var SEMATTRS_LINKED_TRACE_ID_COUNT = 'linked_trace_id_count';
|
|
53
|
+
var SEMATTRS_LINKED_TRACE_ID_HASH = 'linked_trace_id_hash';
|
|
54
|
+
var CORRELATION_ID_HEADER = 'x-correlation-id';
|
|
55
|
+
var SEMATTRS_MESSAGING_BATCH_MESSAGE_COUNT = 'messaging.batch.message_count';
|
|
56
|
+
var SEMATTRS_MESSAGING_KAFKA_BATCH_FIRST_OFFSET =
|
|
57
|
+
'messaging.kafka.batch.first_offset';
|
|
58
|
+
var SEMATTRS_MESSAGING_KAFKA_BATCH_LAST_OFFSET =
|
|
59
|
+
'messaging.kafka.batch.last_offset';
|
|
60
|
+
var SEMATTRS_MESSAGING_KAFKA_BATCH_MESSAGES_PROCESSED =
|
|
61
|
+
'messaging.kafka.batch.messages_processed';
|
|
62
|
+
var SEMATTRS_MESSAGING_KAFKA_BATCH_MESSAGES_FAILED =
|
|
63
|
+
'messaging.kafka.batch.messages_failed';
|
|
64
|
+
var SEMATTRS_MESSAGING_KAFKA_BATCH_PROCESSING_TIME_MS =
|
|
65
|
+
'messaging.kafka.batch.processing_time_ms';
|
|
54
66
|
|
|
55
67
|
// src/kafka/correlation.ts
|
|
56
68
|
var headerSetter = {
|
|
57
69
|
set(carrier, key, value) {
|
|
58
70
|
carrier[key] = value;
|
|
59
|
-
}
|
|
71
|
+
},
|
|
60
72
|
};
|
|
61
73
|
function deriveCorrelationId() {
|
|
62
74
|
const activeBaggage = propagation.getActiveBaggage();
|
|
63
|
-
const baggageCorrelationId = activeBaggage?.getEntry(
|
|
75
|
+
const baggageCorrelationId = activeBaggage?.getEntry('correlation-id');
|
|
64
76
|
if (baggageCorrelationId?.value) {
|
|
65
77
|
return baggageCorrelationId.value;
|
|
66
78
|
}
|
|
@@ -69,7 +81,7 @@ function deriveCorrelationId() {
|
|
|
69
81
|
const spanContext = activeSpan.spanContext();
|
|
70
82
|
return spanContext.traceId.slice(0, 16);
|
|
71
83
|
}
|
|
72
|
-
return
|
|
84
|
+
return '';
|
|
73
85
|
}
|
|
74
86
|
function extractCorrelationId(headers) {
|
|
75
87
|
const lowerKey = CORRELATION_ID_HEADER.toLowerCase();
|
|
@@ -92,21 +104,26 @@ function injectTraceHeaders(base = {}, options = {}) {
|
|
|
92
104
|
}
|
|
93
105
|
return carrier;
|
|
94
106
|
}
|
|
95
|
-
var DEFAULT_TRACER_NAME =
|
|
107
|
+
var DEFAULT_TRACER_NAME = 'autotel-plugins/kafka';
|
|
96
108
|
function isValidSpanContext(spanContext) {
|
|
97
|
-
return !!(
|
|
109
|
+
return !!(
|
|
110
|
+
spanContext &&
|
|
111
|
+
spanContext.traceId &&
|
|
112
|
+
spanContext.spanId &&
|
|
113
|
+
otelTrace.isSpanContextValid(spanContext)
|
|
114
|
+
);
|
|
98
115
|
}
|
|
99
116
|
async function withProcessingSpan(descriptor, fn) {
|
|
100
117
|
const {
|
|
101
118
|
name,
|
|
102
119
|
headers,
|
|
103
|
-
contextMode =
|
|
120
|
+
contextMode = 'inherit',
|
|
104
121
|
links = [],
|
|
105
122
|
topic,
|
|
106
123
|
consumerGroup,
|
|
107
124
|
partition,
|
|
108
125
|
offset,
|
|
109
|
-
key
|
|
126
|
+
key,
|
|
110
127
|
} = descriptor;
|
|
111
128
|
const tracer = otelTrace.getTracer(DEFAULT_TRACER_NAME);
|
|
112
129
|
const normalizedHeaders = normalizeHeaders(headers);
|
|
@@ -115,22 +132,22 @@ async function withProcessingSpan(descriptor, fn) {
|
|
|
115
132
|
const { parentContext, spanLinks } = resolveContextAndLinks(
|
|
116
133
|
contextMode,
|
|
117
134
|
extractedSpanContext,
|
|
118
|
-
links
|
|
135
|
+
links,
|
|
119
136
|
);
|
|
120
137
|
const span = tracer.startSpan(
|
|
121
138
|
name,
|
|
122
139
|
{
|
|
123
140
|
kind: SpanKind.CONSUMER,
|
|
124
|
-
links: spanLinks
|
|
141
|
+
links: spanLinks,
|
|
125
142
|
},
|
|
126
|
-
parentContext
|
|
143
|
+
parentContext,
|
|
127
144
|
);
|
|
128
145
|
setMessagingAttributes(span, {
|
|
129
146
|
topic,
|
|
130
147
|
consumerGroup,
|
|
131
148
|
partition,
|
|
132
149
|
offset,
|
|
133
|
-
key
|
|
150
|
+
key,
|
|
134
151
|
});
|
|
135
152
|
const spanContext = otelTrace.setSpan(context.active(), span);
|
|
136
153
|
try {
|
|
@@ -151,14 +168,18 @@ async function withProcessingSpan(descriptor, fn) {
|
|
|
151
168
|
throw error;
|
|
152
169
|
}
|
|
153
170
|
}
|
|
154
|
-
function resolveContextAndLinks(
|
|
171
|
+
function resolveContextAndLinks(
|
|
172
|
+
contextMode,
|
|
173
|
+
extractedSpanContext,
|
|
174
|
+
additionalLinks,
|
|
175
|
+
) {
|
|
155
176
|
const activeSpan = otelTrace.getActiveSpan();
|
|
156
177
|
const activeContext = context.active();
|
|
157
178
|
const hasActiveSpan = activeSpan !== void 0;
|
|
158
179
|
const hasValidExtracted = isValidSpanContext(extractedSpanContext);
|
|
159
180
|
const spanLinks = [...additionalLinks];
|
|
160
181
|
switch (contextMode) {
|
|
161
|
-
case
|
|
182
|
+
case 'inherit': {
|
|
162
183
|
if (hasActiveSpan) {
|
|
163
184
|
if (hasValidExtracted) {
|
|
164
185
|
const activeSpanContext = activeSpan.spanContext();
|
|
@@ -171,20 +192,20 @@ function resolveContextAndLinks(contextMode, extractedSpanContext, additionalLin
|
|
|
171
192
|
if (hasValidExtracted) {
|
|
172
193
|
const extractedParentCtx = otelTrace.setSpanContext(
|
|
173
194
|
activeContext,
|
|
174
|
-
extractedSpanContext
|
|
195
|
+
extractedSpanContext,
|
|
175
196
|
);
|
|
176
197
|
return { parentContext: extractedParentCtx, spanLinks };
|
|
177
198
|
}
|
|
178
199
|
return { parentContext: activeContext, spanLinks };
|
|
179
200
|
}
|
|
180
201
|
}
|
|
181
|
-
case
|
|
202
|
+
case 'link': {
|
|
182
203
|
if (hasValidExtracted) {
|
|
183
204
|
spanLinks.push({ context: extractedSpanContext });
|
|
184
205
|
}
|
|
185
206
|
return { parentContext: activeContext, spanLinks };
|
|
186
207
|
}
|
|
187
|
-
case
|
|
208
|
+
case 'none': {
|
|
188
209
|
return { parentContext: activeContext, spanLinks };
|
|
189
210
|
}
|
|
190
211
|
default: {
|
|
@@ -196,7 +217,7 @@ function resolveContextAndLinks(contextMode, extractedSpanContext, additionalLin
|
|
|
196
217
|
function setMessagingAttributes(span, attrs) {
|
|
197
218
|
const { topic, consumerGroup, partition, offset, key } = attrs;
|
|
198
219
|
if (topic) {
|
|
199
|
-
span.setAttribute(SEMATTRS_MESSAGING_SYSTEM,
|
|
220
|
+
span.setAttribute(SEMATTRS_MESSAGING_SYSTEM, 'kafka');
|
|
200
221
|
span.setAttribute(SEMATTRS_MESSAGING_DESTINATION_NAME, topic);
|
|
201
222
|
}
|
|
202
223
|
if (consumerGroup) {
|
|
@@ -212,16 +233,16 @@ function setMessagingAttributes(span, attrs) {
|
|
|
212
233
|
span.setAttribute(SEMATTRS_MESSAGING_KAFKA_MESSAGE_KEY, key);
|
|
213
234
|
}
|
|
214
235
|
}
|
|
215
|
-
var DEFAULT_TRACER_NAME2 =
|
|
236
|
+
var DEFAULT_TRACER_NAME2 = 'autotel-plugins/kafka';
|
|
216
237
|
async function withProducerSpan(descriptor, fn) {
|
|
217
|
-
const { name, topic, messageKey, system =
|
|
238
|
+
const { name, topic, messageKey, system = 'kafka' } = descriptor;
|
|
218
239
|
const tracer = otelTrace.getTracer(DEFAULT_TRACER_NAME2);
|
|
219
240
|
const span = tracer.startSpan(name, {
|
|
220
|
-
kind: SpanKind.PRODUCER
|
|
241
|
+
kind: SpanKind.PRODUCER,
|
|
221
242
|
});
|
|
222
243
|
span.setAttribute(SEMATTRS_MESSAGING_SYSTEM, system);
|
|
223
244
|
span.setAttribute(SEMATTRS_MESSAGING_DESTINATION_NAME, topic);
|
|
224
|
-
span.setAttribute(SEMATTRS_MESSAGING_OPERATION,
|
|
245
|
+
span.setAttribute(SEMATTRS_MESSAGING_OPERATION, 'publish');
|
|
225
246
|
if (messageKey !== void 0) {
|
|
226
247
|
span.setAttribute(SEMATTRS_MESSAGING_KAFKA_MESSAGE_KEY, messageKey);
|
|
227
248
|
}
|
|
@@ -246,31 +267,39 @@ async function withProducerSpan(descriptor, fn) {
|
|
|
246
267
|
}
|
|
247
268
|
var DEFAULT_MAX_LINKS = 128;
|
|
248
269
|
function isValidSpanContext2(spanContext) {
|
|
249
|
-
return !!(
|
|
270
|
+
return !!(
|
|
271
|
+
spanContext &&
|
|
272
|
+
spanContext.traceId &&
|
|
273
|
+
spanContext.spanId &&
|
|
274
|
+
otelTrace.isSpanContextValid(spanContext)
|
|
275
|
+
);
|
|
250
276
|
}
|
|
251
277
|
async function hashTraceIds(traceIds) {
|
|
252
|
-
const input = traceIds.join(
|
|
278
|
+
const input = traceIds.join('|');
|
|
253
279
|
try {
|
|
254
280
|
const encoder = new TextEncoder();
|
|
255
281
|
const data = encoder.encode(input);
|
|
256
|
-
const hashBuffer = await crypto.subtle.digest(
|
|
282
|
+
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
|
|
257
283
|
const hashArray = new Uint8Array(hashBuffer);
|
|
258
|
-
return [...hashArray]
|
|
284
|
+
return [...hashArray]
|
|
285
|
+
.map((byte) => byte.toString(16).padStart(2, '0'))
|
|
286
|
+
.join('')
|
|
287
|
+
.slice(0, 16);
|
|
259
288
|
} catch {
|
|
260
289
|
let hash = 5381;
|
|
261
290
|
for (let i = 0; i < input.length; i++) {
|
|
262
|
-
hash = hash * 33 ^ input.charCodeAt(i);
|
|
291
|
+
hash = (hash * 33) ^ input.charCodeAt(i);
|
|
263
292
|
}
|
|
264
|
-
return (hash >>> 0).toString(16).padStart(16,
|
|
293
|
+
return (hash >>> 0).toString(16).padStart(16, '0');
|
|
265
294
|
}
|
|
266
295
|
}
|
|
267
296
|
function hashTraceIdsSync(traceIds) {
|
|
268
|
-
const input = traceIds.join(
|
|
297
|
+
const input = traceIds.join('|');
|
|
269
298
|
let hash = 5381;
|
|
270
299
|
for (let i = 0; i < input.length; i++) {
|
|
271
|
-
hash = hash * 33 ^ input.charCodeAt(i);
|
|
300
|
+
hash = (hash * 33) ^ input.charCodeAt(i);
|
|
272
301
|
}
|
|
273
|
-
return (hash >>> 0).toString(16).padStart(16,
|
|
302
|
+
return (hash >>> 0).toString(16).padStart(16, '0');
|
|
274
303
|
}
|
|
275
304
|
function extractBatchLineage(items, options = {}) {
|
|
276
305
|
const { includeTraceIds = false, maxLinks = DEFAULT_MAX_LINKS } = options;
|
|
@@ -280,23 +309,29 @@ function extractBatchLineage(items, options = {}) {
|
|
|
280
309
|
const normalizedHeaders = normalizeHeaders(item.headers);
|
|
281
310
|
const extractedCtx = extractTraceContext(normalizedHeaders);
|
|
282
311
|
const spanContext = otelTrace.getSpanContext(extractedCtx);
|
|
283
|
-
if (
|
|
312
|
+
if (
|
|
313
|
+
isValidSpanContext2(spanContext) &&
|
|
314
|
+
!seenTraceIds.has(spanContext.traceId)
|
|
315
|
+
) {
|
|
284
316
|
seenTraceIds.add(spanContext.traceId);
|
|
285
317
|
extractedContexts.push({
|
|
286
318
|
traceId: spanContext.traceId,
|
|
287
|
-
spanContext
|
|
319
|
+
spanContext,
|
|
288
320
|
});
|
|
289
321
|
}
|
|
290
322
|
}
|
|
291
323
|
extractedContexts.sort((a, b) => a.traceId.localeCompare(b.traceId));
|
|
292
324
|
const traceIds = extractedContexts.map((ec) => ec.traceId);
|
|
293
|
-
const links = extractedContexts
|
|
294
|
-
|
|
325
|
+
const links = extractedContexts
|
|
326
|
+
.slice(0, maxLinks)
|
|
327
|
+
.map((ec) => ({ context: ec.spanContext }));
|
|
328
|
+
const hash =
|
|
329
|
+
traceIds.length > 0 ? hashTraceIdsSync(traceIds) : '0000000000000000';
|
|
295
330
|
return {
|
|
296
331
|
linked_trace_id_count: traceIds.length,
|
|
297
332
|
linked_trace_id_hash: hash,
|
|
298
333
|
links,
|
|
299
|
-
...includeTraceIds && { trace_ids: traceIds }
|
|
334
|
+
...(includeTraceIds && { trace_ids: traceIds }),
|
|
300
335
|
};
|
|
301
336
|
}
|
|
302
337
|
async function extractBatchLineageAsync(items, options = {}) {
|
|
@@ -307,28 +342,34 @@ async function extractBatchLineageAsync(items, options = {}) {
|
|
|
307
342
|
const normalizedHeaders = normalizeHeaders(item.headers);
|
|
308
343
|
const extractedCtx = extractTraceContext(normalizedHeaders);
|
|
309
344
|
const spanContext = otelTrace.getSpanContext(extractedCtx);
|
|
310
|
-
if (
|
|
345
|
+
if (
|
|
346
|
+
isValidSpanContext2(spanContext) &&
|
|
347
|
+
!seenTraceIds.has(spanContext.traceId)
|
|
348
|
+
) {
|
|
311
349
|
seenTraceIds.add(spanContext.traceId);
|
|
312
350
|
extractedContexts.push({
|
|
313
351
|
traceId: spanContext.traceId,
|
|
314
|
-
spanContext
|
|
352
|
+
spanContext,
|
|
315
353
|
});
|
|
316
354
|
}
|
|
317
355
|
}
|
|
318
356
|
extractedContexts.sort((a, b) => a.traceId.localeCompare(b.traceId));
|
|
319
357
|
const traceIds = extractedContexts.map((ec) => ec.traceId);
|
|
320
|
-
const links = extractedContexts
|
|
321
|
-
|
|
358
|
+
const links = extractedContexts
|
|
359
|
+
.slice(0, maxLinks)
|
|
360
|
+
.map((ec) => ({ context: ec.spanContext }));
|
|
361
|
+
const hash =
|
|
362
|
+
traceIds.length > 0 ? await hashTraceIds(traceIds) : '0000000000000000';
|
|
322
363
|
return {
|
|
323
364
|
linked_trace_id_count: traceIds.length,
|
|
324
365
|
linked_trace_id_hash: hash,
|
|
325
366
|
links,
|
|
326
|
-
...includeTraceIds && { trace_ids: traceIds }
|
|
367
|
+
...(includeTraceIds && { trace_ids: traceIds }),
|
|
327
368
|
};
|
|
328
369
|
}
|
|
329
|
-
var DEFAULT_TRACER_NAME3 =
|
|
370
|
+
var DEFAULT_TRACER_NAME3 = 'autotel-plugins/kafka';
|
|
330
371
|
function withBatchConsumer(config, handler) {
|
|
331
|
-
const { name, consumerGroup, perMessageSpans =
|
|
372
|
+
const { name, consumerGroup, perMessageSpans = 'none', onProgress } = config;
|
|
332
373
|
const tracer = otelTrace.getTracer(DEFAULT_TRACER_NAME3);
|
|
333
374
|
return async (payload) => {
|
|
334
375
|
const { batch } = payload;
|
|
@@ -337,7 +378,7 @@ function withBatchConsumer(config, handler) {
|
|
|
337
378
|
let failed = 0;
|
|
338
379
|
let skipped = 0;
|
|
339
380
|
const batchSpan = tracer.startSpan(name, {
|
|
340
|
-
kind: SpanKind.CONSUMER
|
|
381
|
+
kind: SpanKind.CONSUMER,
|
|
341
382
|
});
|
|
342
383
|
setBatchAttributes(batchSpan, {
|
|
343
384
|
topic: batch.topic,
|
|
@@ -345,31 +386,31 @@ function withBatchConsumer(config, handler) {
|
|
|
345
386
|
consumerGroup,
|
|
346
387
|
messageCount: batch.messages.length,
|
|
347
388
|
firstOffset: batch.firstOffset() ?? void 0,
|
|
348
|
-
lastOffset: batch.lastOffset()
|
|
389
|
+
lastOffset: batch.lastOffset(),
|
|
349
390
|
});
|
|
350
391
|
const spanContext = otelTrace.setSpan(context.active(), batchSpan);
|
|
351
392
|
const {
|
|
352
393
|
wrappedPayload,
|
|
353
394
|
endOpenMessageSpans,
|
|
354
|
-
endRemainingMessageSpansOnSuccess
|
|
395
|
+
endRemainingMessageSpansOnSuccess,
|
|
355
396
|
} = createWrappedPayload(
|
|
356
397
|
payload,
|
|
357
398
|
perMessageSpans,
|
|
358
399
|
tracer,
|
|
359
400
|
spanContext,
|
|
360
401
|
(type) => {
|
|
361
|
-
if (type ===
|
|
362
|
-
else if (type ===
|
|
402
|
+
if (type === 'processed') processed++;
|
|
403
|
+
else if (type === 'failed') failed++;
|
|
363
404
|
else skipped++;
|
|
364
405
|
if (onProgress) {
|
|
365
406
|
onProgress({
|
|
366
407
|
processed,
|
|
367
408
|
failed,
|
|
368
409
|
skipped,
|
|
369
|
-
batchProcessingTimeMs: Date.now() - startTime
|
|
410
|
+
batchProcessingTimeMs: Date.now() - startTime,
|
|
370
411
|
});
|
|
371
412
|
}
|
|
372
|
-
}
|
|
413
|
+
},
|
|
373
414
|
);
|
|
374
415
|
try {
|
|
375
416
|
await context.with(spanContext, async () => {
|
|
@@ -379,47 +420,47 @@ function withBatchConsumer(config, handler) {
|
|
|
379
420
|
const processingTime = Date.now() - startTime;
|
|
380
421
|
batchSpan.setAttribute(
|
|
381
422
|
SEMATTRS_MESSAGING_KAFKA_BATCH_MESSAGES_PROCESSED,
|
|
382
|
-
processed
|
|
423
|
+
processed,
|
|
383
424
|
);
|
|
384
425
|
batchSpan.setAttribute(
|
|
385
426
|
SEMATTRS_MESSAGING_KAFKA_BATCH_MESSAGES_FAILED,
|
|
386
|
-
failed
|
|
427
|
+
failed,
|
|
387
428
|
);
|
|
388
429
|
batchSpan.setAttribute(
|
|
389
430
|
SEMATTRS_MESSAGING_KAFKA_BATCH_PROCESSING_TIME_MS,
|
|
390
|
-
processingTime
|
|
431
|
+
processingTime,
|
|
391
432
|
);
|
|
392
433
|
batchSpan.setStatus({ code: SpanStatusCode.OK });
|
|
393
434
|
batchSpan.end();
|
|
394
435
|
} catch (error) {
|
|
395
436
|
endOpenMessageSpans?.(error);
|
|
396
437
|
const firstMessage = batch.messages[0];
|
|
397
|
-
if (perMessageSpans ===
|
|
438
|
+
if (perMessageSpans === 'errors' && firstMessage !== void 0) {
|
|
398
439
|
createMessageErrorSpan(
|
|
399
440
|
name,
|
|
400
441
|
{
|
|
401
442
|
offset: firstMessage.offset,
|
|
402
443
|
key: firstMessage.key ?? void 0,
|
|
403
|
-
headers: firstMessage.headers
|
|
444
|
+
headers: firstMessage.headers,
|
|
404
445
|
},
|
|
405
446
|
error instanceof Error ? error : new Error(String(error)),
|
|
406
447
|
batch.topic,
|
|
407
|
-
batch.partition
|
|
448
|
+
batch.partition,
|
|
408
449
|
);
|
|
409
450
|
}
|
|
410
451
|
const processingTime = Date.now() - startTime;
|
|
411
452
|
batchSpan.setAttribute(
|
|
412
453
|
SEMATTRS_MESSAGING_KAFKA_BATCH_MESSAGES_PROCESSED,
|
|
413
|
-
processed
|
|
454
|
+
processed,
|
|
414
455
|
);
|
|
415
456
|
batchSpan.setAttribute(
|
|
416
457
|
SEMATTRS_MESSAGING_KAFKA_BATCH_MESSAGES_FAILED,
|
|
417
|
-
failed + 1
|
|
458
|
+
failed + 1,
|
|
418
459
|
// Count the batch error
|
|
419
460
|
);
|
|
420
461
|
batchSpan.setAttribute(
|
|
421
462
|
SEMATTRS_MESSAGING_KAFKA_BATCH_PROCESSING_TIME_MS,
|
|
422
|
-
processingTime
|
|
463
|
+
processingTime,
|
|
423
464
|
);
|
|
424
465
|
batchSpan.setStatus({ code: SpanStatusCode.ERROR });
|
|
425
466
|
if (error instanceof Error) {
|
|
@@ -433,77 +474,86 @@ function withBatchConsumer(config, handler) {
|
|
|
433
474
|
};
|
|
434
475
|
}
|
|
435
476
|
function setBatchAttributes(span, attrs) {
|
|
436
|
-
span.setAttribute(SEMATTRS_MESSAGING_SYSTEM,
|
|
477
|
+
span.setAttribute(SEMATTRS_MESSAGING_SYSTEM, 'kafka');
|
|
437
478
|
span.setAttribute(SEMATTRS_MESSAGING_DESTINATION_NAME, attrs.topic);
|
|
438
479
|
span.setAttribute(SEMATTRS_MESSAGING_KAFKA_PARTITION, attrs.partition);
|
|
439
480
|
span.setAttribute(SEMATTRS_MESSAGING_BATCH_MESSAGE_COUNT, attrs.messageCount);
|
|
440
481
|
if (attrs.consumerGroup) {
|
|
441
482
|
span.setAttribute(
|
|
442
483
|
SEMATTRS_MESSAGING_KAFKA_CONSUMER_GROUP,
|
|
443
|
-
attrs.consumerGroup
|
|
484
|
+
attrs.consumerGroup,
|
|
444
485
|
);
|
|
445
486
|
}
|
|
446
487
|
if (attrs.firstOffset) {
|
|
447
488
|
span.setAttribute(
|
|
448
489
|
SEMATTRS_MESSAGING_KAFKA_BATCH_FIRST_OFFSET,
|
|
449
|
-
attrs.firstOffset
|
|
490
|
+
attrs.firstOffset,
|
|
450
491
|
);
|
|
451
492
|
}
|
|
452
493
|
span.setAttribute(
|
|
453
494
|
SEMATTRS_MESSAGING_KAFKA_BATCH_LAST_OFFSET,
|
|
454
|
-
attrs.lastOffset
|
|
495
|
+
attrs.lastOffset,
|
|
455
496
|
);
|
|
456
497
|
}
|
|
457
|
-
function createWrappedPayload(
|
|
458
|
-
|
|
498
|
+
function createWrappedPayload(
|
|
499
|
+
original,
|
|
500
|
+
perMessageSpans,
|
|
501
|
+
tracer,
|
|
502
|
+
parentContext,
|
|
503
|
+
onMetric,
|
|
504
|
+
) {
|
|
505
|
+
if (perMessageSpans === 'none') {
|
|
459
506
|
return {
|
|
460
507
|
wrappedPayload: {
|
|
461
508
|
...original,
|
|
462
509
|
resolveOffset: (offset) => {
|
|
463
|
-
onMetric(
|
|
510
|
+
onMetric('processed');
|
|
464
511
|
original.resolveOffset(offset);
|
|
465
|
-
}
|
|
466
|
-
}
|
|
512
|
+
},
|
|
513
|
+
},
|
|
467
514
|
};
|
|
468
515
|
}
|
|
469
516
|
const messageSpans = /* @__PURE__ */ new Map();
|
|
470
|
-
if (perMessageSpans ===
|
|
517
|
+
if (perMessageSpans === 'all') {
|
|
471
518
|
for (const message of original.batch.messages) {
|
|
472
519
|
const normalizedHeaders = normalizeHeaders(message.headers);
|
|
473
520
|
const extractedCtx = extractTraceContext(normalizedHeaders);
|
|
474
521
|
const spanContext = otelTrace.getSpanContext(extractedCtx);
|
|
475
|
-
const parentCtx =
|
|
522
|
+
const parentCtx =
|
|
523
|
+
spanContext && otelTrace.isSpanContextValid(spanContext)
|
|
524
|
+
? extractedCtx
|
|
525
|
+
: parentContext;
|
|
476
526
|
const span = tracer.startSpan(
|
|
477
527
|
`${original.batch.topic}.${original.batch.partition}.${message.offset}`,
|
|
478
528
|
{
|
|
479
|
-
kind: SpanKind.CONSUMER
|
|
529
|
+
kind: SpanKind.CONSUMER,
|
|
480
530
|
},
|
|
481
|
-
parentCtx
|
|
531
|
+
parentCtx,
|
|
482
532
|
);
|
|
483
533
|
span.setAttributes({
|
|
484
|
-
[SEMATTRS_MESSAGING_SYSTEM]:
|
|
534
|
+
[SEMATTRS_MESSAGING_SYSTEM]: 'kafka',
|
|
485
535
|
[SEMATTRS_MESSAGING_DESTINATION_NAME]: original.batch.topic,
|
|
486
536
|
[SEMATTRS_MESSAGING_KAFKA_PARTITION]: original.batch.partition,
|
|
487
537
|
[SEMATTRS_MESSAGING_KAFKA_OFFSET]: message.offset,
|
|
488
|
-
...message.key && {
|
|
489
|
-
[SEMATTRS_MESSAGING_KAFKA_MESSAGE_KEY]: message.key.toString()
|
|
490
|
-
}
|
|
538
|
+
...(message.key && {
|
|
539
|
+
[SEMATTRS_MESSAGING_KAFKA_MESSAGE_KEY]: message.key.toString(),
|
|
540
|
+
}),
|
|
491
541
|
});
|
|
492
542
|
messageSpans.set(message.offset, span);
|
|
493
543
|
}
|
|
494
544
|
}
|
|
495
545
|
const wrappedMessages = original.batch.messages.map((message) => ({
|
|
496
|
-
...message
|
|
546
|
+
...message,
|
|
497
547
|
}));
|
|
498
548
|
const wrappedBatch = {
|
|
499
549
|
...original.batch,
|
|
500
|
-
messages: wrappedMessages
|
|
550
|
+
messages: wrappedMessages,
|
|
501
551
|
};
|
|
502
552
|
const wrappedPayload = {
|
|
503
553
|
...original,
|
|
504
554
|
batch: wrappedBatch,
|
|
505
555
|
resolveOffset: (offset) => {
|
|
506
|
-
onMetric(
|
|
556
|
+
onMetric('processed');
|
|
507
557
|
const span = messageSpans.get(offset);
|
|
508
558
|
if (span) {
|
|
509
559
|
span.setStatus({ code: SpanStatusCode.OK });
|
|
@@ -511,31 +561,37 @@ function createWrappedPayload(original, perMessageSpans, tracer, parentContext,
|
|
|
511
561
|
messageSpans.delete(offset);
|
|
512
562
|
}
|
|
513
563
|
original.resolveOffset(offset);
|
|
514
|
-
}
|
|
564
|
+
},
|
|
515
565
|
};
|
|
516
|
-
const endOpenMessageSpans =
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
566
|
+
const endOpenMessageSpans =
|
|
567
|
+
perMessageSpans === 'all'
|
|
568
|
+
? (error) => {
|
|
569
|
+
for (const [, span] of messageSpans) {
|
|
570
|
+
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
571
|
+
if (error instanceof Error) {
|
|
572
|
+
span.recordException(error);
|
|
573
|
+
} else {
|
|
574
|
+
span.recordException(new Error(String(error)));
|
|
575
|
+
}
|
|
576
|
+
span.end();
|
|
577
|
+
}
|
|
578
|
+
messageSpans.clear();
|
|
579
|
+
}
|
|
580
|
+
: void 0;
|
|
581
|
+
const endRemainingMessageSpansOnSuccess =
|
|
582
|
+
perMessageSpans === 'all'
|
|
583
|
+
? () => {
|
|
584
|
+
for (const [, span] of messageSpans) {
|
|
585
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
586
|
+
span.end();
|
|
587
|
+
}
|
|
588
|
+
messageSpans.clear();
|
|
589
|
+
}
|
|
590
|
+
: void 0;
|
|
535
591
|
return {
|
|
536
592
|
wrappedPayload,
|
|
537
593
|
endOpenMessageSpans,
|
|
538
|
-
endRemainingMessageSpansOnSuccess
|
|
594
|
+
endRemainingMessageSpansOnSuccess,
|
|
539
595
|
};
|
|
540
596
|
}
|
|
541
597
|
function createMessageErrorSpan(name, message, error, topic, partition) {
|
|
@@ -545,24 +601,24 @@ function createMessageErrorSpan(name, message, error, topic, partition) {
|
|
|
545
601
|
const span = tracer.startSpan(
|
|
546
602
|
`${name}.error`,
|
|
547
603
|
{
|
|
548
|
-
kind: SpanKind.CONSUMER
|
|
604
|
+
kind: SpanKind.CONSUMER,
|
|
549
605
|
},
|
|
550
|
-
extractedCtx
|
|
606
|
+
extractedCtx,
|
|
551
607
|
);
|
|
552
608
|
span.setAttributes({
|
|
553
|
-
[SEMATTRS_MESSAGING_SYSTEM]:
|
|
609
|
+
[SEMATTRS_MESSAGING_SYSTEM]: 'kafka',
|
|
554
610
|
[SEMATTRS_MESSAGING_DESTINATION_NAME]: topic,
|
|
555
611
|
[SEMATTRS_MESSAGING_KAFKA_PARTITION]: partition,
|
|
556
612
|
[SEMATTRS_MESSAGING_KAFKA_OFFSET]: message.offset,
|
|
557
|
-
...message.key && {
|
|
558
|
-
[SEMATTRS_MESSAGING_KAFKA_MESSAGE_KEY]: message.key.toString()
|
|
559
|
-
}
|
|
613
|
+
...(message.key && {
|
|
614
|
+
[SEMATTRS_MESSAGING_KAFKA_MESSAGE_KEY]: message.key.toString(),
|
|
615
|
+
}),
|
|
560
616
|
});
|
|
561
617
|
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
562
618
|
span.recordException(error);
|
|
563
619
|
span.end();
|
|
564
620
|
}
|
|
565
|
-
var DEFAULT_TRACER_NAME4 =
|
|
621
|
+
var DEFAULT_TRACER_NAME4 = 'autotel-plugins/kafka';
|
|
566
622
|
function createStreamProcessor(config) {
|
|
567
623
|
const { name } = config;
|
|
568
624
|
const tracer = otelTrace.getTracer(DEFAULT_TRACER_NAME4);
|
|
@@ -574,22 +630,27 @@ function createStreamProcessor(config) {
|
|
|
574
630
|
const processorSpan = tracer.startSpan(
|
|
575
631
|
name,
|
|
576
632
|
{
|
|
577
|
-
kind: SpanKind.CONSUMER
|
|
633
|
+
kind: SpanKind.CONSUMER,
|
|
578
634
|
},
|
|
579
|
-
inputSpanContext && otelTrace.isSpanContextValid(inputSpanContext)
|
|
635
|
+
inputSpanContext && otelTrace.isSpanContextValid(inputSpanContext)
|
|
636
|
+
? extractedCtx
|
|
637
|
+
: void 0,
|
|
638
|
+
);
|
|
639
|
+
processorSpan.setAttribute(SEMATTRS_MESSAGING_SYSTEM, 'kafka');
|
|
640
|
+
processorSpan.setAttribute(SEMATTRS_MESSAGING_OPERATION, 'process');
|
|
641
|
+
const processorContext = otelTrace.setSpan(
|
|
642
|
+
context.active(),
|
|
643
|
+
processorSpan,
|
|
580
644
|
);
|
|
581
|
-
processorSpan.setAttribute(SEMATTRS_MESSAGING_SYSTEM, "kafka");
|
|
582
|
-
processorSpan.setAttribute(SEMATTRS_MESSAGING_OPERATION, "process");
|
|
583
|
-
const processorContext = otelTrace.setSpan(context.active(), processorSpan);
|
|
584
645
|
const ctx = {
|
|
585
646
|
span: processorSpan,
|
|
586
647
|
inputContext: inputSpanContext,
|
|
587
648
|
async stage(stageName, fn) {
|
|
588
649
|
return context.with(processorContext, async () => {
|
|
589
650
|
const stageSpan = tracer.startSpan(`${name}.${stageName}`, {
|
|
590
|
-
kind: SpanKind.INTERNAL
|
|
651
|
+
kind: SpanKind.INTERNAL,
|
|
591
652
|
});
|
|
592
|
-
stageSpan.setAttribute(
|
|
653
|
+
stageSpan.setAttribute('stream.stage', stageName);
|
|
593
654
|
const stageContext = otelTrace.setSpan(context.active(), stageSpan);
|
|
594
655
|
try {
|
|
595
656
|
const result = await context.with(stageContext, async () => {
|
|
@@ -611,28 +672,36 @@ function createStreamProcessor(config) {
|
|
|
611
672
|
});
|
|
612
673
|
},
|
|
613
674
|
async produce(topic, _payload, options) {
|
|
614
|
-
const { linkToInput = false, headers: extraHeaders = {} } =
|
|
675
|
+
const { linkToInput = false, headers: extraHeaders = {} } =
|
|
676
|
+
options ?? {};
|
|
615
677
|
const links = [];
|
|
616
|
-
if (
|
|
678
|
+
if (
|
|
679
|
+
linkToInput &&
|
|
680
|
+
inputSpanContext &&
|
|
681
|
+
otelTrace.isSpanContextValid(inputSpanContext)
|
|
682
|
+
) {
|
|
617
683
|
links.push({ context: inputSpanContext });
|
|
618
684
|
}
|
|
619
685
|
const produceSpan = tracer.startSpan(`${name}.produce`, {
|
|
620
686
|
kind: SpanKind.PRODUCER,
|
|
621
|
-
links
|
|
687
|
+
links,
|
|
622
688
|
});
|
|
623
|
-
produceSpan.setAttribute(SEMATTRS_MESSAGING_SYSTEM,
|
|
689
|
+
produceSpan.setAttribute(SEMATTRS_MESSAGING_SYSTEM, 'kafka');
|
|
624
690
|
produceSpan.setAttribute(SEMATTRS_MESSAGING_DESTINATION_NAME, topic);
|
|
625
|
-
produceSpan.setAttribute(SEMATTRS_MESSAGING_OPERATION,
|
|
626
|
-
const produceContext = otelTrace.setSpan(
|
|
691
|
+
produceSpan.setAttribute(SEMATTRS_MESSAGING_OPERATION, 'publish');
|
|
692
|
+
const produceContext = otelTrace.setSpan(
|
|
693
|
+
context.active(),
|
|
694
|
+
produceSpan,
|
|
695
|
+
);
|
|
627
696
|
return context.with(produceContext, () => {
|
|
628
697
|
const headers = injectTraceHeaders(extraHeaders, {
|
|
629
|
-
includeCorrelationIdHeader: true
|
|
698
|
+
includeCorrelationIdHeader: true,
|
|
630
699
|
});
|
|
631
700
|
produceSpan.setStatus({ code: SpanStatusCode.OK });
|
|
632
701
|
produceSpan.end();
|
|
633
702
|
return headers;
|
|
634
703
|
});
|
|
635
|
-
}
|
|
704
|
+
},
|
|
636
705
|
};
|
|
637
706
|
try {
|
|
638
707
|
const result = await context.with(processorContext, async () => {
|
|
@@ -651,7 +720,7 @@ function createStreamProcessor(config) {
|
|
|
651
720
|
processorSpan.end();
|
|
652
721
|
throw error;
|
|
653
722
|
}
|
|
654
|
-
}
|
|
723
|
+
},
|
|
655
724
|
};
|
|
656
725
|
}
|
|
657
726
|
var ConsumerMetrics = class {
|
|
@@ -666,61 +735,69 @@ var ConsumerMetrics = class {
|
|
|
666
735
|
lagPollInterval;
|
|
667
736
|
isRunning = false;
|
|
668
737
|
constructor(config) {
|
|
669
|
-
if (
|
|
670
|
-
|
|
738
|
+
if (
|
|
739
|
+
config.enableLag &&
|
|
740
|
+
config.lagStrategy === 'polling' &&
|
|
741
|
+
!config.lagPollIntervalMs
|
|
742
|
+
) {
|
|
743
|
+
throw new Error('Lag polling requires lagPollIntervalMs');
|
|
671
744
|
}
|
|
672
|
-
if (
|
|
745
|
+
if (
|
|
746
|
+
config.enableLag &&
|
|
747
|
+
(config.lagStrategy === 'polling' || config.lagStrategy === 'hybrid')
|
|
748
|
+
) {
|
|
673
749
|
if (!config.admin) {
|
|
674
750
|
throw new Error(
|
|
675
|
-
`Lag strategy '${config.lagStrategy}' requires admin client
|
|
751
|
+
`Lag strategy '${config.lagStrategy}' requires admin client`,
|
|
676
752
|
);
|
|
677
753
|
}
|
|
678
754
|
if (!config.groupId) {
|
|
679
|
-
throw new Error(
|
|
755
|
+
throw new Error('Lag tracking requires groupId');
|
|
680
756
|
}
|
|
681
757
|
if (!config.topics || config.topics.length === 0) {
|
|
682
|
-
throw new Error(
|
|
758
|
+
throw new Error('Lag tracking requires topics');
|
|
683
759
|
}
|
|
684
760
|
}
|
|
685
761
|
this.config = {
|
|
686
762
|
...config,
|
|
687
|
-
metricsPrefix: config.metricsPrefix ??
|
|
763
|
+
metricsPrefix: config.metricsPrefix ?? 'kafka.consumer',
|
|
688
764
|
enableLag: config.enableLag ?? false,
|
|
689
|
-
lagStrategy: config.lagStrategy ??
|
|
690
|
-
lagPollIntervalMs: config.lagPollIntervalMs ?? 3e4
|
|
765
|
+
lagStrategy: config.lagStrategy ?? 'hybrid',
|
|
766
|
+
lagPollIntervalMs: config.lagPollIntervalMs ?? 3e4,
|
|
691
767
|
};
|
|
692
|
-
this.meter = metrics.getMeter(
|
|
768
|
+
this.meter = metrics.getMeter('autotel-plugins/kafka');
|
|
693
769
|
const prefix = this.config.metricsPrefix;
|
|
694
770
|
this.messagesProcessed = this.meter.createCounter(
|
|
695
771
|
`${prefix}.messages_processed`,
|
|
696
772
|
{
|
|
697
|
-
description:
|
|
698
|
-
}
|
|
773
|
+
description: 'Total number of messages processed',
|
|
774
|
+
},
|
|
699
775
|
);
|
|
700
776
|
this.processingDuration = this.meter.createHistogram(
|
|
701
777
|
`${prefix}.processing_duration`,
|
|
702
778
|
{
|
|
703
|
-
description:
|
|
704
|
-
unit:
|
|
705
|
-
}
|
|
779
|
+
description: 'Message processing duration in milliseconds',
|
|
780
|
+
unit: 'ms',
|
|
781
|
+
},
|
|
706
782
|
);
|
|
707
783
|
this.batchSize = this.meter.createHistogram(`${prefix}.batch_size`, {
|
|
708
|
-
description:
|
|
784
|
+
description: 'Number of messages in each batch',
|
|
709
785
|
});
|
|
710
786
|
this.rebalances = this.meter.createCounter(`${prefix}.rebalances`, {
|
|
711
|
-
description:
|
|
787
|
+
description: 'Number of consumer group rebalances',
|
|
712
788
|
});
|
|
713
789
|
this.lag = this.meter.createObservableGauge(`${prefix}.lag`, {
|
|
714
|
-
description:
|
|
790
|
+
description: 'Consumer lag per topic-partition',
|
|
715
791
|
});
|
|
716
792
|
if (this.config.enableLag) {
|
|
717
793
|
this.lag.addCallback((observableResult) => {
|
|
718
794
|
for (const [, state] of this.partitionStates.entries()) {
|
|
719
795
|
if (state.highWatermark) {
|
|
720
|
-
const lagValue =
|
|
796
|
+
const lagValue =
|
|
797
|
+
BigInt(state.highWatermark) - BigInt(state.currentOffset);
|
|
721
798
|
observableResult.observe(Number(lagValue), {
|
|
722
799
|
topic: state.topic,
|
|
723
|
-
partition: state.partition
|
|
800
|
+
partition: state.partition,
|
|
724
801
|
});
|
|
725
802
|
}
|
|
726
803
|
}
|
|
@@ -734,18 +811,21 @@ var ConsumerMetrics = class {
|
|
|
734
811
|
if (this.isRunning) return;
|
|
735
812
|
this.isRunning = true;
|
|
736
813
|
const { consumer } = this.config;
|
|
737
|
-
consumer.on(
|
|
738
|
-
this.rebalances.add(1, { event:
|
|
814
|
+
consumer.on('consumer.rebalancing', () => {
|
|
815
|
+
this.rebalances.add(1, { event: 'rebalancing' });
|
|
739
816
|
});
|
|
740
|
-
consumer.on(
|
|
741
|
-
this.rebalances.add(1, { event:
|
|
817
|
+
consumer.on('consumer.group_join', () => {
|
|
818
|
+
this.rebalances.add(1, { event: 'group_join' });
|
|
742
819
|
});
|
|
743
|
-
if (
|
|
820
|
+
if (
|
|
821
|
+
this.config.enableLag &&
|
|
822
|
+
(this.config.lagStrategy === 'polling' ||
|
|
823
|
+
this.config.lagStrategy === 'hybrid')
|
|
824
|
+
) {
|
|
744
825
|
await this.pollLag();
|
|
745
826
|
this.lagPollInterval = setInterval(
|
|
746
|
-
() => this.pollLag().catch(() => {
|
|
747
|
-
|
|
748
|
-
this.config.lagPollIntervalMs
|
|
827
|
+
() => this.pollLag().catch(() => {}),
|
|
828
|
+
this.config.lagPollIntervalMs,
|
|
749
829
|
);
|
|
750
830
|
}
|
|
751
831
|
}
|
|
@@ -798,7 +878,7 @@ var ConsumerMetrics = class {
|
|
|
798
878
|
topic,
|
|
799
879
|
partition,
|
|
800
880
|
currentOffset: offset,
|
|
801
|
-
highWatermark: highWatermark ?? existing?.highWatermark
|
|
881
|
+
highWatermark: highWatermark ?? existing?.highWatermark,
|
|
802
882
|
});
|
|
803
883
|
}
|
|
804
884
|
/**
|
|
@@ -810,15 +890,15 @@ var ConsumerMetrics = class {
|
|
|
810
890
|
try {
|
|
811
891
|
const committedOffsets = await admin.fetchOffsets({
|
|
812
892
|
groupId,
|
|
813
|
-
topics
|
|
893
|
+
topics,
|
|
814
894
|
});
|
|
815
895
|
for (const topicOffsets of committedOffsets) {
|
|
816
896
|
const topicHighWatermarks = await admin.fetchTopicOffsets(
|
|
817
|
-
topicOffsets.topic
|
|
897
|
+
topicOffsets.topic,
|
|
818
898
|
);
|
|
819
899
|
for (const partition of topicOffsets.partitions) {
|
|
820
900
|
const hwm = topicHighWatermarks.find(
|
|
821
|
-
(p) => p.partition === partition.partition
|
|
901
|
+
(p) => p.partition === partition.partition,
|
|
822
902
|
);
|
|
823
903
|
if (hwm) {
|
|
824
904
|
const key = `${topicOffsets.topic}-${partition.partition}`;
|
|
@@ -826,34 +906,33 @@ var ConsumerMetrics = class {
|
|
|
826
906
|
topic: topicOffsets.topic,
|
|
827
907
|
partition: partition.partition,
|
|
828
908
|
currentOffset: partition.offset,
|
|
829
|
-
highWatermark: hwm.high
|
|
909
|
+
highWatermark: hwm.high,
|
|
830
910
|
});
|
|
831
911
|
}
|
|
832
912
|
}
|
|
833
913
|
}
|
|
834
|
-
} catch {
|
|
835
|
-
}
|
|
914
|
+
} catch {}
|
|
836
915
|
}
|
|
837
916
|
};
|
|
838
|
-
var DEFAULT_TRACER_NAME5 =
|
|
917
|
+
var DEFAULT_TRACER_NAME5 = 'autotel-plugins/kafka';
|
|
839
918
|
var REBALANCE_EVENTS = [
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
919
|
+
'consumer.group_join',
|
|
920
|
+
'consumer.rebalancing',
|
|
921
|
+
'consumer.stop',
|
|
843
922
|
];
|
|
844
923
|
var ERROR_EVENTS = [
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
924
|
+
'consumer.crash',
|
|
925
|
+
'consumer.disconnect',
|
|
926
|
+
'consumer.network.request_timeout',
|
|
848
927
|
];
|
|
849
|
-
var HEARTBEAT_EVENTS = [
|
|
928
|
+
var HEARTBEAT_EVENTS = ['consumer.heartbeat'];
|
|
850
929
|
function instrumentConsumerEvents(consumer, config = {}) {
|
|
851
930
|
const {
|
|
852
|
-
mode =
|
|
931
|
+
mode = 'events',
|
|
853
932
|
traceRebalances = true,
|
|
854
933
|
traceErrors = true,
|
|
855
934
|
traceHeartbeats = false,
|
|
856
|
-
lifecycleSpan
|
|
935
|
+
lifecycleSpan,
|
|
857
936
|
} = config;
|
|
858
937
|
const tracer = otelTrace.getTracer(DEFAULT_TRACER_NAME5);
|
|
859
938
|
const listeners = [];
|
|
@@ -864,7 +943,7 @@ function instrumentConsumerEvents(consumer, config = {}) {
|
|
|
864
943
|
if (traceRebalances) {
|
|
865
944
|
for (const event of REBALANCE_EVENTS) {
|
|
866
945
|
addListener(event, (payload) => {
|
|
867
|
-
if (mode ===
|
|
946
|
+
if (mode === 'spans') {
|
|
868
947
|
createEventSpan(tracer, event, payload);
|
|
869
948
|
} else if (lifecycleSpan) {
|
|
870
949
|
lifecycleSpan.addEvent(event, extractEventAttributes(payload));
|
|
@@ -875,14 +954,14 @@ function instrumentConsumerEvents(consumer, config = {}) {
|
|
|
875
954
|
if (traceErrors) {
|
|
876
955
|
for (const event of ERROR_EVENTS) {
|
|
877
956
|
addListener(event, (payload) => {
|
|
878
|
-
if (mode ===
|
|
957
|
+
if (mode === 'spans') {
|
|
879
958
|
createErrorSpan(tracer, event, payload);
|
|
880
959
|
} else if (lifecycleSpan) {
|
|
881
960
|
lifecycleSpan.addEvent(event, {
|
|
882
961
|
...extractEventAttributes(payload),
|
|
883
|
-
|
|
962
|
+
'event.severity': 'error',
|
|
884
963
|
});
|
|
885
|
-
if (event ===
|
|
964
|
+
if (event === 'consumer.crash' && isErrorPayload(payload)) {
|
|
886
965
|
lifecycleSpan.recordException(payload.error);
|
|
887
966
|
}
|
|
888
967
|
}
|
|
@@ -892,7 +971,7 @@ function instrumentConsumerEvents(consumer, config = {}) {
|
|
|
892
971
|
if (traceHeartbeats) {
|
|
893
972
|
for (const event of HEARTBEAT_EVENTS) {
|
|
894
973
|
addListener(event, (payload) => {
|
|
895
|
-
if (mode ===
|
|
974
|
+
if (mode === 'spans') {
|
|
896
975
|
createEventSpan(tracer, event, payload);
|
|
897
976
|
} else if (lifecycleSpan) {
|
|
898
977
|
lifecycleSpan.addEvent(event, extractEventAttributes(payload));
|
|
@@ -911,7 +990,7 @@ function instrumentConsumerEvents(consumer, config = {}) {
|
|
|
911
990
|
}
|
|
912
991
|
function createEventSpan(tracer, eventName, payload) {
|
|
913
992
|
const span = tracer.startSpan(`kafka.consumer.${eventName}`, {
|
|
914
|
-
kind: SpanKind.INTERNAL
|
|
993
|
+
kind: SpanKind.INTERNAL,
|
|
915
994
|
});
|
|
916
995
|
const attributes = extractEventAttributes(payload);
|
|
917
996
|
for (const [key, value] of Object.entries(attributes)) {
|
|
@@ -922,7 +1001,7 @@ function createEventSpan(tracer, eventName, payload) {
|
|
|
922
1001
|
}
|
|
923
1002
|
function createErrorSpan(tracer, eventName, payload) {
|
|
924
1003
|
const span = tracer.startSpan(`kafka.consumer.${eventName}`, {
|
|
925
|
-
kind: SpanKind.INTERNAL
|
|
1004
|
+
kind: SpanKind.INTERNAL,
|
|
926
1005
|
});
|
|
927
1006
|
const attributes = extractEventAttributes(payload);
|
|
928
1007
|
for (const [key, value] of Object.entries(attributes)) {
|
|
@@ -936,37 +1015,74 @@ function createErrorSpan(tracer, eventName, payload) {
|
|
|
936
1015
|
}
|
|
937
1016
|
function extractEventAttributes(payload) {
|
|
938
1017
|
const attributes = {};
|
|
939
|
-
if (!payload || typeof payload !==
|
|
1018
|
+
if (!payload || typeof payload !== 'object') {
|
|
940
1019
|
return attributes;
|
|
941
1020
|
}
|
|
942
1021
|
const p = payload;
|
|
943
|
-
if (typeof p.groupId ===
|
|
944
|
-
attributes[
|
|
1022
|
+
if (typeof p.groupId === 'string') {
|
|
1023
|
+
attributes['messaging.kafka.consumer.group'] = p.groupId;
|
|
945
1024
|
}
|
|
946
|
-
if (typeof p.memberId ===
|
|
947
|
-
attributes[
|
|
1025
|
+
if (typeof p.memberId === 'string') {
|
|
1026
|
+
attributes['messaging.kafka.consumer.member_id'] = p.memberId;
|
|
948
1027
|
}
|
|
949
|
-
if (typeof p.leaderId ===
|
|
950
|
-
attributes[
|
|
1028
|
+
if (typeof p.leaderId === 'string') {
|
|
1029
|
+
attributes['messaging.kafka.consumer.leader_id'] = p.leaderId;
|
|
951
1030
|
}
|
|
952
|
-
if (typeof p.duration ===
|
|
953
|
-
attributes[
|
|
1031
|
+
if (typeof p.duration === 'number') {
|
|
1032
|
+
attributes['event.duration_ms'] = p.duration;
|
|
954
1033
|
}
|
|
955
|
-
if (typeof p.isLeader ===
|
|
956
|
-
attributes[
|
|
1034
|
+
if (typeof p.isLeader === 'boolean') {
|
|
1035
|
+
attributes['messaging.kafka.consumer.is_leader'] = p.isLeader;
|
|
957
1036
|
}
|
|
958
1037
|
if (Array.isArray(p.memberAssignment)) {
|
|
959
|
-
attributes[
|
|
1038
|
+
attributes['messaging.kafka.consumer.assignment_count'] =
|
|
1039
|
+
p.memberAssignment.length;
|
|
960
1040
|
}
|
|
961
|
-
if (typeof p.type ===
|
|
962
|
-
attributes[
|
|
1041
|
+
if (typeof p.type === 'string') {
|
|
1042
|
+
attributes['event.type'] = p.type;
|
|
963
1043
|
}
|
|
964
1044
|
return attributes;
|
|
965
1045
|
}
|
|
966
1046
|
function isErrorPayload(payload) {
|
|
967
|
-
return
|
|
1047
|
+
return (
|
|
1048
|
+
payload !== null &&
|
|
1049
|
+
typeof payload === 'object' &&
|
|
1050
|
+
'error' in payload &&
|
|
1051
|
+
payload.error instanceof Error
|
|
1052
|
+
);
|
|
968
1053
|
}
|
|
969
1054
|
|
|
970
|
-
export {
|
|
1055
|
+
export {
|
|
1056
|
+
CORRELATION_ID_HEADER,
|
|
1057
|
+
ConsumerMetrics,
|
|
1058
|
+
SEMATTRS_LINKED_TRACE_ID_COUNT,
|
|
1059
|
+
SEMATTRS_LINKED_TRACE_ID_HASH,
|
|
1060
|
+
SEMATTRS_MESSAGING_BATCH_MESSAGE_COUNT,
|
|
1061
|
+
SEMATTRS_MESSAGING_DESTINATION_NAME,
|
|
1062
|
+
SEMATTRS_MESSAGING_KAFKA_BATCH_FIRST_OFFSET,
|
|
1063
|
+
SEMATTRS_MESSAGING_KAFKA_BATCH_LAST_OFFSET,
|
|
1064
|
+
SEMATTRS_MESSAGING_KAFKA_BATCH_MESSAGES_FAILED,
|
|
1065
|
+
SEMATTRS_MESSAGING_KAFKA_BATCH_MESSAGES_PROCESSED,
|
|
1066
|
+
SEMATTRS_MESSAGING_KAFKA_BATCH_PROCESSING_TIME_MS,
|
|
1067
|
+
SEMATTRS_MESSAGING_KAFKA_CONSUMER_GROUP,
|
|
1068
|
+
SEMATTRS_MESSAGING_KAFKA_MESSAGE_KEY,
|
|
1069
|
+
SEMATTRS_MESSAGING_KAFKA_OFFSET,
|
|
1070
|
+
SEMATTRS_MESSAGING_KAFKA_PARTITION,
|
|
1071
|
+
SEMATTRS_MESSAGING_OPERATION,
|
|
1072
|
+
SEMATTRS_MESSAGING_SYSTEM,
|
|
1073
|
+
createMessageErrorSpan,
|
|
1074
|
+
createStreamProcessor,
|
|
1075
|
+
deriveCorrelationId,
|
|
1076
|
+
extractBatchLineage,
|
|
1077
|
+
extractBatchLineageAsync,
|
|
1078
|
+
extractCorrelationId,
|
|
1079
|
+
extractTraceContext,
|
|
1080
|
+
injectTraceHeaders,
|
|
1081
|
+
instrumentConsumerEvents,
|
|
1082
|
+
normalizeHeaders,
|
|
1083
|
+
withBatchConsumer,
|
|
1084
|
+
withProcessingSpan,
|
|
1085
|
+
withProducerSpan,
|
|
1086
|
+
};
|
|
1087
|
+
//# sourceMappingURL=kafka.js.map
|
|
971
1088
|
//# sourceMappingURL=kafka.js.map
|
|
972
|
-
//# sourceMappingURL=kafka.js.map
|