Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't get active span in Express instrumentation. #2617

Open
ScottChapman opened this issue Dec 26, 2024 · 10 comments · May be fixed by #2638
Open

Can't get active span in Express instrumentation. #2617

ScottChapman opened this issue Dec 26, 2024 · 10 comments · May be fixed by #2638
Assignees
Labels
bug Something isn't working pkg:instrumentation-express priority:p2 Bugs and spec inconsistencies which cause telemetry to be incomplete or incorrect

Comments

@ScottChapman
Copy link

I followed the very simple instrumentation instructions:

const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');
const { registerInstrumentations } = require('@opentelemetry/instrumentation');
const { HttpInstrumentation } = require('@opentelemetry/instrumentation-http');
const { ExpressInstrumentation } = require('@opentelemetry/instrumentation-express');

const provider = new NodeTracerProvider();
provider.register();

registerInstrumentations({
  instrumentations: [
    // Express instrumentation expects HTTP layer to be instrumented
    new HttpInstrumentation(),
    new ExpressInstrumentation(),
  ],
});

And in my express code I am trying to get the active span:

app.get("/api/results/:id", async (req, res) => {
  const localSpan = opentelemetry.trace.getActiveSpan();

But it ends up being null??

@ScottChapman ScottChapman added the bug Something isn't working label Dec 26, 2024
@faranak-cs
Copy link

I am facing the same issue: TypeError: Cannot read properties of undefined (reading 'spanContext'). The value is undefined:

app.get("/data", async (req, res) => {
  try {
    if (req.query["fail"]) {
      throw new Error("A really bad error :/");
    }
    const apiResponse = await axios.get("http://localhost:8090/user");
    res.json(apiResponse.data);
  } catch (error) {
    const activeSpan = api.trace.getSpan(api.context.active());
    const traceId = activeSpan.spanContext().traceId;

    // Combine log  with trace
    console.error(`Critical Error, traceId: ${traceId}`);
    res.sendStatus(500);
  }
});
const { PrometheusExporter } = require("@opentelemetry/exporter-prometheus");
const { OTLPTraceExporter } = require("@opentelemetry/exporter-trace-otlp-http");
const { registerInstrumentations } = require("@opentelemetry/instrumentation");
const { ExpressInstrumentation } = require("@opentelemetry/instrumentation-express");
const { HttpInstrumentation } = require("@opentelemetry/instrumentation-http");
const { Resource } = require("@opentelemetry/resources");
const { MeterProvider } = require("@opentelemetry/sdk-metrics");
const {
  NodeTracerProvider,
  SimpleSpanProcessor,
  ConsoleSpanExporter,
} = require("@opentelemetry/sdk-trace-node");
const { ATTR_SERVICE_NAME } = require("@opentelemetry/semantic-conventions");

const init = function (serviceName, metricPort) {
  // Define metrics
  const metricExporter = new PrometheusExporter({ port: metricPort }, () => {
    console.log(
      `scrape: http://localhost/:${metricPort}${PrometheusExporter.DEFAULT_OPTIONS.endpoint}`
    );
  });

  // Create meter provider
  const meterProvider = new MeterProvider({
    readers: [metricExporter],
  });

  // Get meter
  const meter = meterProvider.getMeter(serviceName);

  // Define traces
  const traceExporter = new ConsoleSpanExporter();
  const processor = new SimpleSpanProcessor(traceExporter);

  // Create trace provider
  const provider = new NodeTracerProvider({
    resource: new Resource({
      [ATTR_SERVICE_NAME]: serviceName,
    }),
    spanProcessors: [processor],
  });

  provider.register();

  // Register instrumentations
  registerInstrumentations({
    instrumentations: [new HttpInstrumentation(), new ExpressInstrumentation()],
  });

  // Get tracer
  const tracer = provider.getTracer(serviceName);

  // Return meter & tracer
  return { meter, tracer };
};

module.exports = init;

@faranak-cs
Copy link

Hi @pichlermarc, please guide. Thanks

@ScottChapman
Copy link
Author

Oooph. One thing I considered doing was implement a requestHook for the express instrumentation and attach the span to the request. Felt pretty hacky though

@faranak-cs
Copy link

Any solutions for the time being? @raphael-theriault-swi
Thanks

@raphael-theriault-swi
Copy link
Contributor

Oooph. One thing I considered doing was implement a requestHook for the express instrumentation and attach the span to the request. Felt pretty hacky though

Yeah it's not great, but at the moment I don't see a better way to work around this until it's fixed in the instrumentation.

@faranak-cs
Copy link

Thanks a lot, @raphael-theriault-swi

@faranak-cs
Copy link

Oooph. One thing I considered doing was implement a requestHook for the express instrumentation and attach the span to the request. Felt pretty hacky though

Hi @ScottChapman, can you explain more about your solution?

@ScottChapman
Copy link
Author

Oooph. One thing I considered doing was implement a requestHook for the express instrumentation and attach the span to the request. Felt pretty hacky though

Hi @ScottChapman, can you explain more about your solution?

Yea so look here Basically you would just add a property to the request object and set it to the span.

That seems to be fine it you are doing manual instrumentation.

But I am not sure if you can add a request hook to the instance that is created during auto-instrumentation??

@ScottChapman
Copy link
Author

In the short term are folks having better success with an express alternative (like fastify or others)?
In my sample app I created a new running span, and I can see logs show the trace and span IDs, but the span doesn't appear under any trace. which is weird.

@pichlermarc pichlermarc added priority:p2 Bugs and spec inconsistencies which cause telemetry to be incomplete or incorrect and removed triage labels Jan 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working pkg:instrumentation-express priority:p2 Bugs and spec inconsistencies which cause telemetry to be incomplete or incorrect
Projects
None yet
4 participants