Opentelemetry-js: getCurrentSpan() returns undefined when a span is started

Created on 21 Jun 2020  路  5Comments  路  Source: open-telemetry/opentelemetry-js

Please answer these questions before submitting a bug report.

What version of OpenTelemetry are you using?

    "@opentelemetry/api": "^0.8.3",
    "@opentelemetry/context-base": "^0.9.0",
    "@opentelemetry/node": "^0.8.3",
    "@opentelemetry/plugin-express": "^0.8.0",
    "@opentelemetry/plugin-http": "^0.8.3",
    "@opentelemetry/plugin-https": "^0.8.3",
    "@opentelemetry/plugin-pg": "^0.8.0",
    "@opentelemetry/plugin-pg-pool": "^0.8.0",
    "@opentelemetry/tracing": "^0.8.3",

What version of Node are you using?

v10.18.1

What did you do?

If possible, provide a recipe for reproducing the error.

        const parentSpan = tracer.startSpan('main');
        console.log(tracer.getCurrentSpan())

getCurrentSpan() returns undefined, even though the main span started on the previous line.

What did you expect to see?

tracer.getCurrentSpan() not returning undefined.

What did you see instead?

undefined

Additional context

I've got quite a large codebase that I want to instrument with opentelemetry.
I'd like to avoid passing parent spans down the call stack explicitly because that would require me to change all function signatures.
I expected const span = tracer.startSpan('name') to inject the parent if not provided.
Instead it seems like the only way for a span to be linked to its parent is const span = tracer.startSpan('name', { parent }).
I tried getCurrentSpan(), but it's always undefined.
Would be great if you could advise on how to proceed.
Thank you

bug

Most helpful comment

startSpan does not add the span to the context, it only creates a new span.

const parentSpan = tracer.startSpan('main');

tracer.withSpan(parentSpan, () => {
    console.log(tracer.getCurrentSpan());
});

All 5 comments

I guess you didn't register a ContextManager, how did you configure the tracer exactly ? Could you show the full code used ? See this example

Hi @vmarchaud, thanks for the quick response, it's very appreciated!

I do call register. register adds and enables an instance of AsyncHooksContextManager.
Here's a simple script which I run with ts-node.


const opentelemetry = require('@opentelemetry/api');
const { NodeTracerProvider } = require('@opentelemetry/node');
const { SimpleSpanProcessor, ConsoleSpanExporter } = require('@opentelemetry/tracing');
const { TraceExporter } = require('@google-cloud/opentelemetry-cloud-trace-exporter');

let tracer
let exporter

export function initialise() {
    const projectId = 'HIDDEN' // I use Google Cloud Trace
    const provider = new NodeTracerProvider();

    exporter = new TraceExporter({ projectId: projectId });

    provider.addSpanProcessor(new SimpleSpanProcessor(exporter));
    provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));

    provider.register()

    opentelemetry.trace.setGlobalTracerProvider(provider);
    tracer = opentelemetry.trace.getTracer('basic')
}

function doWork() {
    const span = tracer.startSpan('doWork')

    for (let i = 0; i <= Math.floor(Math.random() * 40000000); i += 1) {
        // empty
    }

    span.setAttribute('key', 'value');
    span.addEvent('invoking doWork');

    span.end();
}

function run() {
    initialise()

    const parentSpan = tracer.startSpan('main');
    console.log('Current span')
    console.log(tracer.getCurrentSpan())

    for (let i = 0; i < 10; i += 1) {
        doWork();
    }
    parentSpan.end();
}

run()

console.log(tracer.getCurrentSpan()) prints undefined.
Also, all child spans do not link to the parent.

If I pass parentSpan to doWork, then child spans do link to their parent. Like so

// ...
function doWork(parent) {
    const span = tracer.startSpan('doWork', { parent })

    for (let i = 0; i <= Math.floor(Math.random() * 40000000); i += 1) {
        // empty
    }

    span.setAttribute('key', 'value');
    span.addEvent('invoking doWork');

    span.end();
}

function run() {
    initialise()

    const parentSpan = tracer.startSpan('main');
    console.log('Current span')
    console.log(tracer.getCurrentSpan())

    for (let i = 0; i < 10; i += 1) {
        doWork(parentSpan);
    }
    parentSpan.end();
}
// ...

But it does not happen via the context.

I suspect, but it's just a guess, that the child spans not linking to the parent (via the context) and getCurrenctSpan() returning undefined could be the same issue.

Unless I am doing something completely wrong in the script.
In any case, would you be able to advice on how best to proceed?
Thank you!

startSpan does not add the span to the context, it only creates a new span.

const parentSpan = tracer.startSpan('main');

tracer.withSpan(parentSpan, () => {
    console.log(tracer.getCurrentSpan());
});

Yes, that's right. You can read more in API Documentation: startSpan and withSpan.

Ok, thanks guys! I'm going to close this.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

naseemkullah picture naseemkullah  路  6Comments

carlosalberto picture carlosalberto  路  3Comments

giri-jeedigunta picture giri-jeedigunta  路  5Comments

amarflybot18 picture amarflybot18  路  3Comments

obecny picture obecny  路  6Comments