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