@temporalio/interceptors-opentelemetry
Version:
Temporal.io SDK interceptors bundle for tracing with opentelemetry
187 lines • 7.75 kB
JavaScript
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.OpenTelemetryInternalsInterceptor = exports.OpenTelemetryOutboundInterceptor = exports.OpenTelemetryInboundInterceptor = void 0;
/* eslint-disable import/order */
// eslint-disable-next-line import/no-unassigned-import
require("./runtime"); // Patch the Workflow isolate runtime for opentelemetry
const otel = __importStar(require("@opentelemetry/api"));
const tracing = __importStar(require("@opentelemetry/sdk-trace-base"));
const workflow_1 = require("@temporalio/workflow");
const instrumentation_1 = require("../instrumentation");
const context_manager_1 = require("./context-manager");
const definitions_1 = require("./definitions");
const span_exporter_1 = require("./span-exporter");
__exportStar(require("./definitions"), exports);
let tracer = undefined;
let contextManager = undefined;
function getTracer() {
if (contextManager === undefined) {
contextManager = new context_manager_1.ContextManager();
}
if (tracer === undefined) {
const provider = new tracing.BasicTracerProvider();
provider.addSpanProcessor(new tracing.SimpleSpanProcessor(new span_exporter_1.SpanExporter()));
provider.register({ contextManager });
tracer = provider.getTracer('@temporalio/interceptor-workflow');
}
return tracer;
}
/**
* Intercepts calls to run a Workflow
*
* Wraps the operation in an opentelemetry Span and links it to a parent Span context if one is
* provided in the Workflow input headers.
*/
class OpenTelemetryInboundInterceptor {
constructor() {
this.tracer = getTracer();
}
async execute(input, next) {
const context = await (0, instrumentation_1.extractContextFromHeaders)(input.headers);
return await (0, instrumentation_1.instrument)({
tracer: this.tracer,
spanName: `${definitions_1.SpanName.WORKFLOW_EXECUTE}${definitions_1.SPAN_DELIMITER}${(0, workflow_1.workflowInfo)().workflowType}`,
fn: () => next(input),
context,
acceptableErrors: (err) => err instanceof workflow_1.ContinueAsNew,
});
}
async handleSignal(input, next) {
const context = await (0, instrumentation_1.extractContextFromHeaders)(input.headers);
return await (0, instrumentation_1.instrument)({
tracer: this.tracer,
spanName: `${definitions_1.SpanName.WORKFLOW_SIGNAL}${definitions_1.SPAN_DELIMITER}${input.signalName}`,
fn: () => next(input),
context,
});
}
}
exports.OpenTelemetryInboundInterceptor = OpenTelemetryInboundInterceptor;
/**
* Intercepts outbound calls to schedule an Activity
*
* Wraps the operation in an opentelemetry Span and passes it to the Activity via headers.
*/
class OpenTelemetryOutboundInterceptor {
constructor() {
this.tracer = getTracer();
}
async scheduleActivity(input, next) {
return await (0, instrumentation_1.instrument)({
tracer: this.tracer,
spanName: `${definitions_1.SpanName.ACTIVITY_START}${definitions_1.SPAN_DELIMITER}${input.activityType}`,
fn: async () => {
const headers = await (0, instrumentation_1.headersWithContext)(input.headers);
return next({
...input,
headers,
});
},
});
}
async scheduleLocalActivity(input, next) {
return await (0, instrumentation_1.instrument)({
tracer: this.tracer,
spanName: `${definitions_1.SpanName.ACTIVITY_START}${definitions_1.SPAN_DELIMITER}${input.activityType}`,
fn: async () => {
const headers = await (0, instrumentation_1.headersWithContext)(input.headers);
return next({
...input,
headers,
});
},
});
}
async startChildWorkflowExecution(input, next) {
return await (0, instrumentation_1.instrument)({
tracer: this.tracer,
spanName: `${definitions_1.SpanName.CHILD_WORKFLOW_START}${definitions_1.SPAN_DELIMITER}${input.workflowType}`,
fn: async () => {
const headers = await (0, instrumentation_1.headersWithContext)(input.headers);
return next({
...input,
headers,
});
},
});
}
async continueAsNew(input, next) {
return await (0, instrumentation_1.instrument)({
tracer: this.tracer,
spanName: `${definitions_1.SpanName.CONTINUE_AS_NEW}${definitions_1.SPAN_DELIMITER}${input.options.workflowType}`,
fn: async () => {
const headers = await (0, instrumentation_1.headersWithContext)(input.headers);
return next({
...input,
headers,
});
},
acceptableErrors: (err) => err instanceof workflow_1.ContinueAsNew,
});
}
async signalWorkflow(input, next) {
return await (0, instrumentation_1.instrument)({
tracer: this.tracer,
spanName: `${definitions_1.SpanName.WORKFLOW_SIGNAL}${definitions_1.SPAN_DELIMITER}${input.signalName}`,
fn: async () => {
const headers = await (0, instrumentation_1.headersWithContext)(input.headers);
return next({
...input,
headers,
});
},
});
}
getLogAttributes(input, next) {
const span = otel.trace.getSpan(otel.context.active());
const spanContext = span?.spanContext();
if (spanContext && otel.isSpanContextValid(spanContext)) {
return next({
trace_id: spanContext.traceId,
span_id: spanContext.spanId,
trace_flags: `0${spanContext.traceFlags.toString(16)}`,
...input,
});
}
else {
return next(input);
}
}
}
exports.OpenTelemetryOutboundInterceptor = OpenTelemetryOutboundInterceptor;
class OpenTelemetryInternalsInterceptor {
async dispose(input, next) {
if (contextManager !== undefined) {
contextManager.disable();
}
next(input);
}
}
exports.OpenTelemetryInternalsInterceptor = OpenTelemetryInternalsInterceptor;
//# sourceMappingURL=index.js.map
;