How to pass opentracing data using json

时光毁灭记忆、已成空白 提交于 2020-01-22 02:35:53

问题


My API-gateway starts a tracer and a span for validate email. Then its passed to user-service for validation.

I want to pass this span details to user-service as a json object and start another span as a

tracer.start_span('Validate Email', child_of=API_gateway_span)

To do it, I have used following struct:

type checkEmail struct {
    GatewayTracerSpan opentracing.SpanContext `json: gatewayTracerSpan`
    Email             string                  `json: email`
    Uuid              string                  `json: uuid`
}

In function()

validateEmailSpan := apitracer.tracer.StartSpan("Validate Email")

emailJson := checkEmail{
            GatewayTracerSpan: validateEmailSpan.Context(),
            Email:             email,
            Uuid:              uuid,
        }

But always GatewayTracerSpan is empty value. I have just started distributed-tracing. Here I selected to use json over native http-headers as its easy for upgrade any protocol change.

Is this possible? If so, am I doing it right? Or what mistakes did I make?


回答1:


One way to link spans from different services is to use uber-trace-id from the parent span. If you have LogSpans set to true in your ReporterConfig, uber-trace-id is what gets printed out ("Reporting span xxx-xxx-xxx").

Here is how it might look like in the code:

//API Gateway
carrier := opentracing.TextMapCarrier{} //you can use any type of carrier or even create your own
ctx, _ := opentracing.GlobalTracer().Extract(opentracing.TextMap, carrier)
span := apitracer.tracer.StartSpan(name, ext.RPCServerOption(ctx))
_ := span.Tracer().Inject(span.Context(), opentracing.TextMap, carrier)
uberTraceID := carrier["uber-trace-id"]

You can now pass uberTraceID instead of validateEmailSpan.Context() to your other services.

You can use this function in your other services:

//Email service
func NewChildSpanThatFollows(name, uberTraceID string) opentracing.Span {
    carrier := opentracing.TextMapCarrier{}
    carrier.Set("uber-trace-id", uberTraceID)
    ctx, _ := opentracing.GlobalTracer().Extract(opentracing.TextMap, carrier)
    span := opentracing.StartSpan(name, opentracing.FollowsFrom(ctx))
    _ := span.Tracer().Inject(span.Context(), opentracing.TextMap, carrier)

    return span
}

This works for me if I need to see spans between services linked together in a parent-child manner. If other information needs to be passed as well, I would suggest passing it as regular data in the JSON object, then either create my own Carrier or use tags if needed to do a search with that passed data.

span.SetTag("request_id", requestID)

EDIT:

Here you can find a great tutorial on using opentracing. It uses HTTPHeadersCarrier, it has a step by step walkthrough, but it's basically the same process as above.



来源:https://stackoverflow.com/questions/58740621/how-to-pass-opentracing-data-using-json

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!