opentelemetry-js icon indicating copy to clipboard operation
opentelemetry-js copied to clipboard

exporter-zipkin does not send Content-Type in default config

Open flanfly opened this issue 4 years ago • 5 comments
trafficstars

What version of OpenTelemetry are you using?

0.13.0

What did you do?

import { ConsoleSpanExporter, SimpleSpanProcessor, BatchSpanProcessor } from '@opentelemetry/tracing';
import { WebTracerProvider } from '@opentelemetry/web';
import { XMLHttpRequestInstrumentation } from '@opentelemetry/instrumentation-xml-http-request';
import { ZoneContextManager } from '@opentelemetry/context-zone';
import { ZipkinExporter } from '@opentelemetry/exporter-zipkin';

export const provider = new WebTracerProvider({
  plugins: [
    new XMLHttpRequestInstrumentation({
      ignoreUrls: [/localhost:9000\/sockjs-node/],
      propagateTraceHeaderCorsUrls: [
        'http://localhost:9000/console'
      ]
    })
  ]
});

provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
provider.addSpanProcessor(new BatchSpanProcessor(new ZipkinExporter({
  serviceName: 'web',
  url: 'http://localhost:9411/api/v2/spans',
})));
provider.register({
  contextManager: new ZoneContextManager(),
})

export const Tracer = provider.getTracer('web')

export function newSpan(name: string) {
  return Tracer.startSpan(name, { parent: Tracer.getCurrentSpan() })
}
const span = newSpan("blah")
Tracer.withSpan(span, () => {
  console.log("test")
  span.end()
})

What did you expect to see?

The above trace should show up in my local Jaeger instance.

What did you see instead?

Nothing. The POST to http://localhost:9411/v2/spans 400'd with Unsupported Content-Type.

Additional context

Adding an empty header field to the ZipkinExporter config fixes the problem.

 provider.addSpanProcessor(new BatchSpanProcessor(new ZipkinExporter({
  serviceName: 'web',
  url: 'http://localhost:9411/api/v2/spans',
  headers: {}, // <-- HERE
})));

The bug (feature?) occurs in @opentelemetry/exporter-zipkin/build/src/platform/browser/util.js:26. Maybe it should say something like this.

xhrHeaders = Object.assign({ Accept: 'application/json', 'Content-Type': 'application/json' }, headers || {});

The project is awsome btw.

flanfly avatar Dec 06 '20 01:12 flanfly

By default we use sendBeacon where you cannot set any headers. If you set any headers in config then it will switch to use XMLHTTPRequest instead where you can set whatever headers you want, plus a default one. So having "header: {}" will switch to XMLHTTPRequest.

obecny avatar Dec 07 '20 14:12 obecny

If jaeger expects a content-type header to be set then maybe we should default to xhr and have a useBeacon setting where we document that you must be able to receive without any headers?

dyladan avatar Dec 07 '20 14:12 dyladan

If jaeger expects a content-type header to be set then maybe we should default to xhr and have a useBeacon setting where we document that you must be able to receive without any headers?

We have sendBeacon as default already for some time, so I would rather not change it now. If people want to have xhr by default we can add useXhr to config if that helps, otherwise I can think of situation when someone's setup is starting to break because of adding a header after this change. We can also document that it is enough to have "headers:{}" to switch to xhr. Both ways are fine for me (useXhr or "headers: {}") .

obecny avatar Dec 07 '20 14:12 obecny

If the default setup can't export to a default jaeger installation, it is broken

edit: just noticed this is about the zipkin exporter exporting to a jaeger all-in-one. Does the beacon method work when exporting to an official zipkin?

dyladan avatar Dec 07 '20 14:12 dyladan

Does this failure only occur when exporting to jaeger or does it also fail when sending to zipkin?

dyladan avatar Jul 20 '22 16:07 dyladan

Not enough information. Please reopen if you can answer the above questions

dyladan avatar Sep 14 '22 15:09 dyladan