问题
I am trying to implement a Go-based microservice system. I have two service and I try to Inject
and Extract
span data.
In my first service, I have:
func (apitracer apiTracer) validatemail(res http.ResponseWriter, req *http.Request) {
validateEmailSpan := apitracer.tracer.StartSpan("Validate Email")
apitracer.tracer.Inject(
validateEmailSpan.Context(),
opentracing.HTTPHeaders,
opentracing.HTTPHeadersCarrier(req.Header))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
resp, err := httpClient.Do(req)
In service two :
wireContext, err := opentracing.GlobalTracer().Extract(
opentracing.HTTPHeaders,
opentracing.HTTPHeadersCarrier(req.Header))
I get following error :
SpanContext not found in Extract carrier
If I dump log.Println("Form values : ", req.Header.Get("Uber-Trace-Id"))
, I get proper Uber-Trace-Id
value which is same as Service-One.
Request headers are set to application/x-www-form-urlencoded
as suggested here
Edit : After @eminlala
Tracer init step.
type apiTracer struct {
tracer opentracing.Tracer
}
// Tracing function
func startTracing(service string) opentracing.Tracer {
cfg := config.Configuration{
Sampler: &config.SamplerConfig{
Type: "const",
Param: 1,
},
Reporter: &config.ReporterConfig{
LogSpans: true,
BufferFlushInterval: 1 * time.Second,
},
}
tracer, _, _ := cfg.New(
service,
config.Logger(jaeger.StdLogger),
)
opentracing.SetGlobalTracer(tracer)
return tracer
}
回答1:
Looking at your code I see that you missed to add Injector
and Extractor
options when creating the tracer. It should look something like this:
zipkinPropagator := zipkin.NewZipkinB3HTTPHeaderPropagator()
tracer, _, err := cfg.New(
e.ServiceName, config.Logger(jaeger.StdLogger), config.ZipkinSharedRPCSpan(true),
config.Injector(opentracing.HTTPHeaders, zipkinPropagator),
config.Extractor(opentracing.HTTPHeaders, zipkinPropagator))
opentracing.SetGlobalTracer(tracer)
ZipkinPropagator
is from github.com/uber/jaeger-client-go/zipkin
package.
You should try ZipkinPropagator
because it has less configuration than the plain HTTPHeaderPropagator
. ZipkinPropagator
receives less parameters, but it's also less flexible. Also, the error you received is from the Extract
method is of type opentracing.ErrSpanContextNotFound
. Extract
method for ZipkinPropagator
is less complex as it only check for the TraceID
before sending the opentracing.ErrSpanContextNotFound
error (when carrier.TraceID()==0
).
You can use the HTTPHeaderPropagator
as well, but it has a bit more complex setup, and Extract
method checks for more things other than TraceID
before sending the opentracing.ErrSpanContextNotFound
error (checks for debugID
and baggage
that is extracted from HeadersConfig
).
EDIT:
Looking back at your previous question regarding opentracing
, if you haven't included Injector
and Extractor
setup, that might have been the problem why uber-trace-id
was not found when extracting the span context in the target service.
来源:https://stackoverflow.com/questions/58861152/spancontext-not-found-in-extract-carrier-in-microservice