Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,087 changes: 662 additions & 425 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@
"temporalio": "file:packages/meta"
},
"devDependencies": {
"@opentelemetry/api": "^1.7.0",
"@opentelemetry/core": "^1.19.0",
"@opentelemetry/sdk-node": "^0.46.0",
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/core": "^2.0.1",
"@opentelemetry/sdk-node": "^0.203.0",
"@tsconfig/node18": "^18.2.4",
"@types/fs-extra": "^11.0.4",
"@types/ms": "^0.7.34",
Expand Down
9 changes: 5 additions & 4 deletions packages/interceptors-opentelemetry/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@
"author": "Temporal Technologies Inc. <sdk@temporal.io>",
"license": "MIT",
"dependencies": {
"@opentelemetry/api": "^1.7.0",
"@opentelemetry/core": "^1.19.0",
"@opentelemetry/resources": "^1.19.0",
"@opentelemetry/sdk-trace-base": "^1.19.0"
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/core": "^2.0.1",
"@opentelemetry/resources": "^2.0.1",
"@opentelemetry/sdk-trace-base": "^2.0.1",
"@opentelemetry/sdk-trace-node": "^2.0.1"
},
"devDependencies": {
"@temporalio/activity": "file:../activity",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as otel from '@opentelemetry/api';
import * as tracing from '@opentelemetry/sdk-trace-base';
import { InstrumentationLibrary } from '@opentelemetry/core'; // eslint-disable deprecation/deprecation
import { InstrumentationScope } from '@opentelemetry/core'; // eslint-disable deprecation/deprecation
import { Sink, Sinks } from '@temporalio/workflow';

/**
Expand All @@ -10,7 +10,7 @@ export interface SerializableSpan {
readonly name: string;
readonly kind: otel.SpanKind;
readonly spanContext: otel.SpanContext;
readonly parentSpanId?: string;
readonly parentSpanContext?: otel.SpanContext;
readonly startTime: otel.HrTime;
readonly endTime: otel.HrTime;
readonly status: otel.SpanStatus;
Expand All @@ -24,7 +24,7 @@ export interface SerializableSpan {
readonly droppedEventsCount: number;
// readonly resource: Resource;
// eslint-disable-next-line deprecation/deprecation
readonly instrumentationLibrary: InstrumentationLibrary;
readonly instrumentationScope: InstrumentationScope;
}

export interface OpenTelemetryWorkflowExporter extends Sink {
Expand Down
7 changes: 4 additions & 3 deletions packages/interceptors-opentelemetry/src/workflow/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// eslint-disable-next-line import/no-unassigned-import
import './runtime'; // Patch the Workflow isolate runtime for opentelemetry
import * as otel from '@opentelemetry/api';
import * as tracing from '@opentelemetry/sdk-trace-base';
import * as tracing from '@opentelemetry/sdk-trace-node';
import {
ActivityInput,
ContinueAsNew,
Expand Down Expand Up @@ -35,8 +35,9 @@ function getTracer(): otel.Tracer {
contextManager = new ContextManager();
}
if (tracer === undefined) {
const provider = new tracing.BasicTracerProvider();
provider.addSpanProcessor(new tracing.SimpleSpanProcessor(new SpanExporter()));
const provider = new tracing.NodeTracerProvider({
spanProcessors: [new tracing.SimpleSpanProcessor(new SpanExporter())],
});
provider.register({ contextManager });
tracer = provider.getTracer('@temporalio/interceptor-workflow');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export class SpanExporter implements tracing.SpanExporter {
name: span.name,
kind: span.kind,
spanContext: span.spanContext(),
parentSpanId: span.parentSpanId,
parentSpanContext: span.parentSpanContext,
startTime: span.startTime,
endTime: span.endTime,
status: span.status,
Expand All @@ -32,7 +32,7 @@ export class SpanExporter implements tracing.SpanExporter {
droppedAttributesCount: span.droppedAttributesCount,
droppedEventsCount: span.droppedEventsCount,
droppedLinksCount: span.droppedLinksCount,
instrumentationLibrary: span.instrumentationLibrary,
instrumentationScope: span.instrumentationScope,
};
}
}
13 changes: 7 additions & 6 deletions packages/test/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@
"dependencies": {
"@grpc/grpc-js": "^1.12.4",
"@grpc/proto-loader": "^0.7.10",
"@opentelemetry/api": "^1.7.0",
"@opentelemetry/core": "^1.19.0",
"@opentelemetry/exporter-trace-otlp-grpc": "^0.46.0",
"@opentelemetry/sdk-node": "^0.46.0",
"@opentelemetry/sdk-trace-base": "^1.19.0",
"@opentelemetry/semantic-conventions": "^1.19.0",
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/core": "^2.0.1",
"@opentelemetry/exporter-trace-otlp-grpc": "^0.203.0",
"@opentelemetry/sdk-node": "^0.203.0",
"@opentelemetry/sdk-trace-base": "^2.0.1",
"@opentelemetry/sdk-trace-node": "^2.0.1",
"@opentelemetry/semantic-conventions": "^1.36.0",
"@temporalio/activity": "file:../activity",
"@temporalio/client": "file:../client",
"@temporalio/cloud": "file:../cloud",
Expand Down
6 changes: 3 additions & 3 deletions packages/test/src/load/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import http from 'node:http';
import { inspect } from 'node:util';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc';
import * as opentelemetry from '@opentelemetry/sdk-node';
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';
import { ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions';
import arg from 'arg';
import { Connection } from '@temporalio/client';
import {
Expand Down Expand Up @@ -34,8 +34,8 @@ async function withOptionalOtel(args: arg.Result<WorkerArgSpec>, fn: () => Promi

const traceExporter = new OTLPTraceExporter({ url });
const otel = new opentelemetry.NodeSDK({
resource: new opentelemetry.resources.Resource({
[SemanticResourceAttributes.SERVICE_NAME]: 'load-worker',
resource: opentelemetry.resources.resourceFromAttributes({
[ATTR_SERVICE_NAME]: 'load-worker',
taskQueue,
}),
traceExporter,
Expand Down
74 changes: 39 additions & 35 deletions packages/test/src/test-otel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import { SpanStatusCode } from '@opentelemetry/api';
import { ExportResultCode } from '@opentelemetry/core';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc';
import * as opentelemetry from '@opentelemetry/sdk-node';
import { BasicTracerProvider, InMemorySpanExporter, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base';
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';
import { InMemorySpanExporter, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base';
import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
import { ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions';
import test from 'ava';
import { v4 as uuid4 } from 'uuid';
import { Connection, WorkflowClient } from '@temporalio/client';
Expand Down Expand Up @@ -234,8 +235,8 @@ if (RUN_INTEGRATION_TESTS) {
try {
const spans = Array<opentelemetry.tracing.ReadableSpan>();

const staticResource = new opentelemetry.resources.Resource({
[SemanticResourceAttributes.SERVICE_NAME]: 'ts-test-otel-worker',
const staticResource = opentelemetry.resources.resourceFromAttributes({
[ATTR_SERVICE_NAME]: 'ts-test-otel-worker',
});
const traceExporter: opentelemetry.tracing.SpanExporter = {
export(spans_, resultCallback) {
Expand Down Expand Up @@ -283,98 +284,102 @@ if (RUN_INTEGRATION_TESTS) {
const originalSpan = spans.find(({ name }) => name === `${SpanName.WORKFLOW_START}${SPAN_DELIMITER}smorgasbord`);
t.true(originalSpan !== undefined);
t.log(
spans.map((span) => ({ name: span.name, parentSpanId: span.parentSpanId, spanId: span.spanContext().spanId }))
spans.map((span) => ({
name: span.name,
parentSpanContext: span.parentSpanContext,
spanId: span.spanContext().spanId,
}))
);

const firstExecuteSpan = spans.find(
({ name, parentSpanId }) =>
({ name, parentSpanContext }) =>
name === `${SpanName.WORKFLOW_EXECUTE}${SPAN_DELIMITER}smorgasbord` &&
parentSpanId === originalSpan?.spanContext().spanId
parentSpanContext === originalSpan?.spanContext()
);
t.true(firstExecuteSpan !== undefined);
t.true(firstExecuteSpan!.status.code === SpanStatusCode.OK);

const continueAsNewSpan = spans.find(
({ name, parentSpanId }) =>
({ name, parentSpanContext }) =>
name === `${SpanName.CONTINUE_AS_NEW}${SPAN_DELIMITER}smorgasbord` &&
parentSpanId === firstExecuteSpan?.spanContext().spanId
parentSpanContext === firstExecuteSpan?.spanContext()
);
t.true(continueAsNewSpan !== undefined);
t.true(continueAsNewSpan!.status.code === SpanStatusCode.OK);

const parentExecuteSpan = spans.find(
({ name, parentSpanId }) =>
({ name, parentSpanContext }) =>
name === `${SpanName.WORKFLOW_EXECUTE}${SPAN_DELIMITER}smorgasbord` &&
parentSpanId === continueAsNewSpan?.spanContext().spanId
parentSpanContext === continueAsNewSpan?.spanContext()
);
t.true(parentExecuteSpan !== undefined);
const firstActivityStartSpan = spans.find(
({ name, parentSpanId }) =>
({ name, parentSpanContext }) =>
name === `${SpanName.ACTIVITY_START}${SPAN_DELIMITER}fakeProgress` &&
parentSpanId === parentExecuteSpan?.spanContext().spanId
parentSpanContext === parentExecuteSpan?.spanContext()
);
t.true(firstActivityStartSpan !== undefined);

const firstActivityExecuteSpan = spans.find(
({ name, parentSpanId }) =>
({ name, parentSpanContext }) =>
name === `${SpanName.ACTIVITY_EXECUTE}${SPAN_DELIMITER}fakeProgress` &&
parentSpanId === firstActivityStartSpan?.spanContext().spanId
parentSpanContext === firstActivityStartSpan?.spanContext()
);
t.true(firstActivityExecuteSpan !== undefined);

const secondActivityStartSpan = spans.find(
({ name, parentSpanId }) =>
({ name, parentSpanContext }) =>
name === `${SpanName.ACTIVITY_START}${SPAN_DELIMITER}queryOwnWf` &&
parentSpanId === parentExecuteSpan?.spanContext().spanId
parentSpanContext === parentExecuteSpan?.spanContext()
);
t.true(secondActivityStartSpan !== undefined);

const secondActivityExecuteSpan = spans.find(
({ name, parentSpanId }) =>
({ name, parentSpanContext }) =>
name === `${SpanName.ACTIVITY_EXECUTE}${SPAN_DELIMITER}queryOwnWf` &&
parentSpanId === secondActivityStartSpan?.spanContext().spanId
parentSpanContext === secondActivityStartSpan?.spanContext()
);
t.true(secondActivityExecuteSpan !== undefined);

const childWorkflowStartSpan = spans.find(
({ name, parentSpanId }) =>
({ name, parentSpanContext }) =>
name === `${SpanName.CHILD_WORKFLOW_START}${SPAN_DELIMITER}signalTarget` &&
parentSpanId === parentExecuteSpan?.spanContext().spanId
parentSpanContext === parentExecuteSpan?.spanContext()
);
t.true(childWorkflowStartSpan !== undefined);

const childWorkflowExecuteSpan = spans.find(
({ name, parentSpanId }) =>
({ name, parentSpanContext }) =>
name === `${SpanName.WORKFLOW_EXECUTE}${SPAN_DELIMITER}signalTarget` &&
parentSpanId === childWorkflowStartSpan?.spanContext().spanId
parentSpanContext === childWorkflowStartSpan?.spanContext()
);
t.true(childWorkflowExecuteSpan !== undefined);

const signalChildWithUnblockSpan = spans.find(
({ name, parentSpanId }) =>
({ name, parentSpanContext }) =>
name === `${SpanName.WORKFLOW_SIGNAL}${SPAN_DELIMITER}unblock` &&
parentSpanId === parentExecuteSpan?.spanContext().spanId
parentSpanContext === parentExecuteSpan?.spanContext()
);
t.true(signalChildWithUnblockSpan !== undefined);

const localActivityStartSpan = spans.find(
({ name, parentSpanId }) =>
({ name, parentSpanContext }) =>
name === `${SpanName.ACTIVITY_START}${SPAN_DELIMITER}echo` &&
parentSpanId === parentExecuteSpan?.spanContext().spanId
parentSpanContext === parentExecuteSpan?.spanContext()
);
t.true(localActivityStartSpan !== undefined);

const localActivityExecuteSpan = spans.find(
({ name, parentSpanId }) =>
({ name, parentSpanContext }) =>
name === `${SpanName.ACTIVITY_EXECUTE}${SPAN_DELIMITER}echo` &&
parentSpanId === localActivityStartSpan?.spanContext().spanId
parentSpanContext === localActivityStartSpan?.spanContext()
);
t.true(localActivityExecuteSpan !== undefined);

const activityStartedSignalSpan = spans.find(
({ name, parentSpanId }) =>
({ name, parentSpanContext }) =>
name === `${SpanName.WORKFLOW_SIGNAL}${SPAN_DELIMITER}activityStarted` &&
parentSpanId === firstActivityExecuteSpan?.spanContext().spanId
parentSpanContext === firstActivityExecuteSpan?.spanContext()
);
t.true(activityStartedSignalSpan !== undefined);

Expand All @@ -396,8 +401,8 @@ if (RUN_INTEGRATION_TESTS) {
try {
const oTelUrl = 'http://127.0.0.1:4317';
const exporter = new OTLPTraceExporter({ url: oTelUrl });
const staticResource = new opentelemetry.resources.Resource({
[SemanticResourceAttributes.SERVICE_NAME]: 'ts-test-otel-worker',
const staticResource = opentelemetry.resources.resourceFromAttributes({
[ATTR_SERVICE_NAME]: 'ts-test-otel-worker',
});
const otel = new opentelemetry.NodeSDK({
resource: staticResource,
Expand Down Expand Up @@ -440,8 +445,7 @@ if (RUN_INTEGRATION_TESTS) {

test('instrumentation: Error status includes message and records exception', async (t) => {
const memoryExporter = new InMemorySpanExporter();
const provider = new BasicTracerProvider();
provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
const provider = new NodeTracerProvider({ spanProcessors: [new SimpleSpanProcessor(memoryExporter)] });
provider.register();
const tracer = provider.getTracer('test-error-tracer');

Expand Down