UNPKG

@instana/core

Version:
107 lines (85 loc) 3.21 kB
/* * (c) Copyright IBM Corp. 2025 */ 'use strict'; const constants = require('../constants'); const W3cTraceContext = require('../w3c_trace_context/W3cTraceContext'); let ConfluentKafkaInstrumentation; function initInstrumentation() { ConfluentKafkaInstrumentation = ConfluentKafkaInstrumentation || require('@instana/instrumentation-confluent-kafka-javascript').ConfluentKafkaInstrumentation; } module.exports.preInit = () => { initInstrumentation(); }; module.exports.init = () => { initInstrumentation(); const instrumentation = new ConfluentKafkaInstrumentation({}); if (!instrumentation.getConfig().enabled) { instrumentation.enable(); } }; module.exports.getKind = otelSpan => { if (otelSpan.attributes?.['messaging.operation.type'] === 'receive') { return constants.ENTRY; } return constants.EXIT; }; /** * The Otel instrumentations are part of our tracing pipeline. * As soon as there is an Exit -> Entry pair (such as Kafka), we have to manipulate * the Otel context to inject our Instana ids into the W3C trace context, because Otel internally creates their * own W3C trace context ids (via tracer.startSpan()). We do not monkey patch `startSpan` currently. * * The flow is: * - trace.setSpan(context.active(), span); * - wrap.js setSpan override * - create Instana span * - manipulate the returned context of `setSpan` with our ids * - the Otel span will be cleaned up automatically from Otel SDK */ module.exports.setW3CTraceContext = (api, preparedData, otelSpan, instanaSpan, originalCtx) => { if (preparedData.kind !== constants.EXIT) { return originalCtx; } const otelSpanContext = otelSpan.spanContext(); let w3cTraceContext; // CASE 1: Instana Tracing is suppressed, we do not create the Instana span - see transformToInstanaSpan in wrap.js. // We take the original Otel ids and forward the suppression state. The entry span will follow the decision. // CASE 2: Instana Tracing is active, we push the Instana ids into the Otel context. if (!instanaSpan) { w3cTraceContext = W3cTraceContext.fromOtelIds( otelSpanContext.traceId, otelSpanContext.spanId, preparedData.isSuppressed === false ); } else { w3cTraceContext = W3cTraceContext.fromInstanaIds(instanaSpan.t, instanaSpan.s, preparedData.isSuppressed === false); } const carrier = {}; carrier[constants.w3cTraceParent] = w3cTraceContext.renderTraceParent(); return api.propagation.extract(originalCtx, carrier); }; /** * We have to extract the w3c information from the otel span, because * the entry otel span will contain our Instana trace and parent information, which we have to * extract and connect to our Instana spans to keep the correlation. */ module.exports.extractW3CTraceContext = (preparedData, otelSpan) => { const result = { traceId: null, parentSpanId: null }; if (preparedData.kind !== constants.ENTRY) { return result; } const spanContext = otelSpan.parentSpanContext; if (spanContext?.traceId) { result.traceId = spanContext.traceId.substring(16); } if (spanContext?.spanId) { result.parentSpanId = spanContext.spanId; } return result; };