UNPKG

@dynatrace/opentelemetry-core

Version:

Dynatrace OpenTelemetry core package

144 lines (141 loc) 6.83 kB
"use strict"; /* Copyright 2022 Dynatrace LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.addStacktrace = exports.prepareSpanForExport = exports.markSpanPropagatedNow = void 0; const api_1 = require("@opentelemetry/api"); const core_1 = require("@opentelemetry/core"); const SemConvTrace = require("../../gen/dynatrace/odin/semconv/v1/SemConvTrace"); const Fw4Tag_1 = require("../propagator/Fw4Tag"); const RumLite_1 = require("../utils/context/RumLite"); const SpanEmbedder_1 = require("./SpanEmbedder"); const SpanMetaData_1 = require("./SpanMetaData"); // ============================================================================= function markSpanPropagatedNow(span) { const metaData = (0, SpanEmbedder_1.getMetaData)(span); if (metaData != null) { metaData.lastPropagationTime = (0, core_1.hrTime)(); } } exports.markSpanPropagatedNow = markSpanPropagatedNow; // ============================================================================= /** * Prepares the span for export by initializing its SpanMetaData (calculating tenantParentSpanId, * setting mobileTag, ...) and creating an FW4Tag if required. * * @param span the span to prepare for export. * @param parentContext the context providing the parent span. * @param ids the ids required when creating the FW4 tag for the span. * @param transmitOptions the options for initializing the span's meta data. */ function prepareSpanForExport(span, parentContext, ids, transmitOptions, logger) { const metaData = new SpanMetaData_1.SpanMetaData(transmitOptions); (0, SpanEmbedder_1.setMetaData)(span, metaData); const parentSpan = getParent(span, parentContext); const { tenantParentSpanId, createFw4Tag, encodedLinkId } = checkParentSpan(parentSpan, logger); // set tenant parent spanId and encodedLinkId received via parent metaData.tenantParentSpanId = tenantParentSpanId; metaData.encodedLinkId = encodedLinkId; // propagate resource span attributes from parent to child span (0, SpanEmbedder_1.setPropagatedResourceAttributes)(span, (0, SpanEmbedder_1.getPropagatedResourceAttributes)(parentSpan)); // Create a tag for local propagation as there was none on parent if (createFw4Tag) { createTagOnTraceState(span.spanContext(), ids); } // set the serverId if provided and not yet set const fw4Tag = (0, SpanEmbedder_1.getFw4Tag)(span.spanContext().traceState); if ((fw4Tag === null || fw4Tag === void 0 ? void 0 : fw4Tag.serverId) === 0) { const serverId = (0, RumLite_1.getServerId)(parentContext); if (serverId != null) { fw4Tag.serverId = serverId; metaData.mobileTag = (0, RumLite_1.getMobileTag)(parentContext); const xDtc = (0, RumLite_1.getXDtc)(parentContext); if (xDtc != null) { span.setAttribute(SemConvTrace.DT_RUM_DTC, xDtc); } } } } exports.prepareSpanForExport = prepareSpanForExport; // ---------------------------------------------------------------------------- function addStacktrace(key, span, logger) { // remove error message and first frame ("at addStacktrace") from the stack const stackObj = {}; Error.captureStackTrace(stackObj, addStacktrace); const stack = stackObj.stack.substring(stackObj.stack.indexOf("\n") + 1); if (typeof (stack) === "string") { span.setAttribute(key, stack); if (logger.debugEnabled) { logger.debug(`${key}=${stack}`); } } } exports.addStacktrace = addStacktrace; // ---------------------------------------------------------------------------- function createTagOnTraceState(spanContext, ids) { if (spanContext.traceState == null) { spanContext.traceState = new core_1.TraceState(); } // attach an FW4 tag on TraceState which is automatically propagated to local child spans const tag = new Fw4Tag_1.Fw4Tag(ids, spanContext).setRootPathRandom(); (0, SpanEmbedder_1.setFw4Tag)(spanContext.traceState, tag); } // ---------------------------------------------------------------------------- function checkParentSpan(parentSpan, logger) { let tenantParentSpanId; let encodedLinkId; let createFw4Tag = true; if (parentSpan == null) { return { tenantParentSpanId, createFw4Tag, encodedLinkId }; } const spanContext = parentSpan.spanContext(); if (spanContext.isRemote) { if (spanContext.traceState != null) { const fw4Tag = (0, SpanEmbedder_1.getFw4Tag)(spanContext.traceState); if (fw4Tag != null) { createFw4Tag = false; // spanId received via TraceState to allow exporting it if (fw4Tag.extensions.spanId.length > 0) { tenantParentSpanId = fw4Tag.extensions.spanId; } // encoded linkId received from FW4 tag encodedLinkId = fw4Tag.encodedLinkId; } } } else { // for local parents use the parent spanId also as tenantParentSpanId tenantParentSpanId = spanContext.spanId; // Set/update last-propagation-time on parent markSpanPropagatedNow(parentSpan); // local parent, should have a TraceState with tag attached already... if ((0, SpanEmbedder_1.getFw4Tag)(spanContext.traceState) != null) { createFw4Tag = false; } else { logger.warn(`Expected FW4 tag to exist for span (traceId: ${spanContext.traceId}, spanId: ${spanContext.spanId}) but none found.`); } } return { tenantParentSpanId, createFw4Tag, encodedLinkId }; } // ---------------------------------------------------------------------------- function getParent(span, parentContext) { const parentSpan = api_1.trace.getSpan(parentContext); // the parentContext passed to the span processor in the tracer might not hold the actual // parent span, e.g. when SpanOptions.root = true was used. So check for this here. if (parentSpan == null || parentSpan.spanContext().spanId !== span.parentSpanId || !(0, api_1.isSpanContextValid)(parentSpan.spanContext())) { return undefined; } return parentSpan; } //# sourceMappingURL=SpanUpdater.js.map