diff --git a/plugins/node/opentelemetry-instrumentation-net/package.json b/plugins/node/opentelemetry-instrumentation-net/package.json index 73206bbf26..5437cb5b63 100644 --- a/plugins/node/opentelemetry-instrumentation-net/package.json +++ b/plugins/node/opentelemetry-instrumentation-net/package.json @@ -47,6 +47,7 @@ }, "devDependencies": { "@opentelemetry/api": "^1.3.0", + "@opentelemetry/context-async-hooks": "^1.8.0", "@opentelemetry/sdk-trace-base": "^1.8.0", "@opentelemetry/sdk-trace-node": "^1.8.0", "@types/mocha": "7.0.2", diff --git a/plugins/node/opentelemetry-instrumentation-net/src/instrumentation.ts b/plugins/node/opentelemetry-instrumentation-net/src/instrumentation.ts index 1247ffd990..848744bf42 100644 --- a/plugins/node/opentelemetry-instrumentation-net/src/instrumentation.ts +++ b/plugins/node/opentelemetry-instrumentation-net/src/instrumentation.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { diag, Span, SpanStatusCode } from '@opentelemetry/api'; +import { diag, Span, SpanStatusCode, context, trace } from '@opentelemetry/api'; import { InstrumentationBase, InstrumentationConfig, @@ -112,7 +112,12 @@ export class NetInstrumentation extends InstrumentationBase { ) { const tlsSpan = this.tracer.startSpan('tls.connect'); - const netSpan = this._startSpan(options, socket); + const netSpan = context.with( + trace.setSpan(context.active(), tlsSpan), + () => { + return this._startSpan(options, socket); + } + ); const otelTlsSpanListener = () => { const peerCertificate = socket.getPeerCertificate(true); diff --git a/plugins/node/opentelemetry-instrumentation-net/test/tls.test.ts b/plugins/node/opentelemetry-instrumentation-net/test/tls.test.ts index 5e27a99195..0052a4787c 100644 --- a/plugins/node/opentelemetry-instrumentation-net/test/tls.test.ts +++ b/plugins/node/opentelemetry-instrumentation-net/test/tls.test.ts @@ -14,12 +14,13 @@ * limitations under the License. */ -import { SpanStatusCode } from '@opentelemetry/api'; +import { SpanStatusCode, context } from '@opentelemetry/api'; import { InMemorySpanExporter, SimpleSpanProcessor, } from '@opentelemetry/sdk-trace-base'; import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node'; +import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks'; import * as assert from 'assert'; import * as tls from 'tls'; import { NetInstrumentation } from '../src'; @@ -48,12 +49,16 @@ function getTLSSpans() { describe('NetInstrumentation', () => { let instrumentation: NetInstrumentation; + let contextManager: AsyncHooksContextManager; + let tlsServer: tls.Server; let tlsSocket: tls.TLSSocket; before(() => { instrumentation = new NetInstrumentation(); instrumentation.setTracerProvider(provider); + contextManager = new AsyncHooksContextManager().enable(); + context.setGlobalContextManager(contextManager.enable()); require('net'); }); diff --git a/plugins/node/opentelemetry-instrumentation-net/test/utils.ts b/plugins/node/opentelemetry-instrumentation-net/test/utils.ts index 88d431e3c5..23bc6db72b 100644 --- a/plugins/node/opentelemetry-instrumentation-net/test/utils.ts +++ b/plugins/node/opentelemetry-instrumentation-net/test/utils.ts @@ -58,6 +58,7 @@ export function assertTLSSpan( { netSpan, tlsSpan }: { netSpan: ReadableSpan; tlsSpan: ReadableSpan }, socket: Socket ) { + assertParentChild(tlsSpan, netSpan); assertSpanKind(netSpan); assertAttrib( netSpan, @@ -108,6 +109,17 @@ export function assertAttrib(span: ReadableSpan, attrib: string, value: any) { assert.strictEqual(span.attributes[attrib], value); } +export function assertParentChild( + parentSpan: ReadableSpan, + childSpan: ReadableSpan +) { + assert.strictEqual( + childSpan.spanContext().traceId, + parentSpan.spanContext().traceId + ); + assert.strictEqual(childSpan.parentSpanId, parentSpan.spanContext().spanId); +} + export const TLS_SERVER_CERT = fs .readFileSync(path.resolve(__dirname, './fixtures/tls.crt')) .toString();