Skip to content

ExpressJS instrumentation doesn't play nice with Sampler  #651

Closed
@hermanbanken

Description

I want to exclude certain routes from the ExpressJS instrumentation. However, this is made extra hard by the updateName usage in the instrumentation. If I look at the spans in our visualizer (Cloud Trace) the name of the span I want to exclude is "GET /health" (the Kubernetes health check), however, in the sampler the name of the span is still the name that the HTTP library instrumentation gives the span.

I'd like to see some possibility to exclude certain routes from being traced completely, however this does not seem possible now.

updateName culprit:

rpcMetadata.span.updateName(
`${req.method} ${route.length > 0 ? route : '/'}`
);

What version of OpenTelemetry are you using?

0.24 of core and contrib packages.

What version of Node are you using?

Node 14

What did you do?

export class FilterSampler implements Sampler {
  constructor(private parent: Sampler, private filter: (spanName: string) => boolean) {}
  public shouldSample(ctx: Context, tid: string, name: string, kind: SpanKind, attr: SpanAttributes, links: Link[]) {
    if (!this.filter(name)) {
      process.stderr.write(`Excluding span with name "${name}"\n`); // debug
      return { decision: SamplingDecision.NOT_RECORD };
    }
    process.stderr.write(`Sampling span with name "${name}"\n`); // debug
    return this.parent.shouldSample(ctx, tid, name, kind, attr, links);
  }
  public toString(): string {
    return `FilterSampler(${this.parent.toString()})`;
  }
}

const filterFn = (spanName: string) => spanName.indexOf("GET /health") < 0 && spanName.indexOf("GET /") < 0;
const sampler = new FilterSampler(new AlwaysOnSampler(), filterFn);
const provider = new NodeTracerProvider({ sampler });
provider.register();
trace.setGlobalTracerProvider(provider);
registerInstrumentations({
  instrumentations: [
    new HttpInstrumentation(),
    new ExpressInstrumentation(),
  ],
});

What did you expect to see?

Excluding span with name "GET /health"
Sampling span with name "middleware - query"
Sampling span with name "middleware - expressInit"
Sampling span with name "request handler - /health"

What did you see instead?

Sampling span with name "HTTP GET"
Sampling span with name "middleware - query"
Sampling span with name "middleware - expressInit"
Sampling span with name "request handler - /health"

Additional context

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions