@azure/monitor-opentelemetry
Version:
Azure Monitor OpenTelemetry (Node.js)
98 lines • 3.83 kB
JavaScript
;
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", { value: true });
exports.AzureMonitorSpanProcessor = void 0;
const api_1 = require("@opentelemetry/api");
const index_js_1 = require("../shared/logging/index.js");
const genaiAttributes_js_1 = require("../utils/genaiAttributes.js");
/**
* Azure Monitor Span Processor.
* @internal
*/
class AzureMonitorSpanProcessor {
_metricHandler;
constructor(metricHandler) {
this._metricHandler = metricHandler;
}
forceFlush() {
return Promise.resolve();
}
onStart(span, parentContext) {
try {
this._propagateMainAgentAttributesFromParent(span, parentContext);
}
catch (error) {
index_js_1.Logger.getInstance().warn("Error while propagating main agent attributes onStart", error);
}
this._metricHandler.markSpanAsProcessed(span);
}
onEnd(span) {
try {
this._applyInvokeAgentMainAgentFallback(span);
}
catch (error) {
index_js_1.Logger.getInstance().warn("Error while applying main agent fallback onEnd", error);
}
try {
this._metricHandler.recordSpan(span);
}
catch (error) {
index_js_1.Logger.getInstance().warn("Error while recording span", error);
}
}
_propagateMainAgentAttributesFromParent(span, parentContext) {
const parentSpan = api_1.trace.getSpan(parentContext);
if (!parentSpan) {
return;
}
// The Span returned by trace.getSpan may be a non-recording span or a
// foreign implementation that does not expose `attributes`. Only proceed
// when the parent looks like a ReadableSpan with readable attributes.
const parentAttributes = parentSpan.attributes;
if (!parentAttributes) {
return;
}
for (const { target, primary, fallback } of genaiAttributes_js_1.MAIN_AGENT_ONSTART_MAPPING) {
const primaryValue = parentAttributes[primary];
if (primaryValue !== undefined) {
span.setAttribute(target, primaryValue);
continue;
}
const fallbackValue = parentAttributes[fallback];
if (fallbackValue !== undefined) {
span.setAttribute(target, fallbackValue);
}
}
}
_applyInvokeAgentMainAgentFallback(span) {
const attributes = span.attributes;
if (!attributes || attributes[genaiAttributes_js_1.GEN_AI_OPERATION_NAME] !== genaiAttributes_js_1.GEN_AI_OPERATION_INVOKE_AGENT) {
return;
}
// Only check the four target attributes defined by the spec rather than
// scanning every key on the span.
for (const { target } of genaiAttributes_js_1.MAIN_AGENT_ONEND_MAPPING) {
if (attributes[target] !== undefined) {
return;
}
}
// The processor runs before BatchSpanProcessor, so mutating the span's
// attributes map here is observed by the exporter. Assigning into
// `attributes` directly avoids depending on the ReadableSpan also being a
// writable Span (and on `setAttribute` being a no-op once the span has
// ended).
const writableAttributes = attributes;
for (const { target, source } of genaiAttributes_js_1.MAIN_AGENT_ONEND_MAPPING) {
const value = attributes[source];
if (value !== undefined) {
writableAttributes[target] = value;
}
}
}
shutdown() {
return Promise.resolve();
}
}
exports.AzureMonitorSpanProcessor = AzureMonitorSpanProcessor;
//# sourceMappingURL=spanProcessor.js.map