2

I am using Stackdriver Trace to monitor the delays of some microservices, but am having some issues in making all the round trip to be shown as one request.

Say I have two services (to keep it simple). In order to get the traces from both of them, I need to install client libraries in both services. Now say in the first service I do:

@app.route('/dump')
def dump():
    url = "http://db-dump/dump"
    tracer = app.config['TRACER']
    tracer.start_span(name='dump')
    result = requests.get(url)
    tracer.end_span()

    return result.content

In my second service, I do:

@app.route('/dump')
def dump():
    conn = connect()
    tracer = app.config['TRACER']
    tracer.start_span(name='dump')
    db_content = select(conn)
    tracer.end_span()
    db_content_to_print = format(db_content)

    return render_page(db_content_to_print)

This second service, makes a query to a database, gts the results, and sends them to the first service, which displays the content.

Now, of course I have to start counting the delay in both microservices, since I want to know how long it takes from the first service to the second service. And Also I have to start counting in the second service, since I want to know how long it takes to retrieve the content from the database.

But when I get the traces on GCP console, I see this:

enter image description here

Where the first trace is from the database, and the second trace is both (from the first service to the second one + database).

I want to know how can I embed the second trace inside the first one in python. I have been checking opencensus documentation for python, and I found this:

class opencensus.trace.span.Span(name, parent_span=None,...)

A span is an individual timed event which forms a node of the trace tree. Each span has its name, span id and parent id. The parent id indicates the causal relationships between the individual spans in a single distributed trace. Span that does not have a parent id is called root span. All spans associated with a specific trace also share a common trace id. Spans do not need to be continuous, there can be gaps between two spans.

So, I guess, I have to send the span_id of the first request along with the request to the second microservice? There is another problem here, that this seems to need to initialize the tracer with these parameters, but my tracer on the second microservice is already initialized. I can't initialize it when sending the request as it is already no going to calculate the delay correctly.

I need to ask this, as to make the tests, I have to create the image, upload it to docker hub, then to make the tests on k8s. It is too much work to do being pretty blind here.

Python client library for Stackdriver trace is in alpha, so also there is not much documentation regarding this on GCP site.

EDIT

Since there were no responses, I actually tried passing the span_context information, which is this:

>>> print(tracer.span_context)
SpanContext(trace_id=987b84e7efc5562ff6c21723e674cd41, span_id=910de32857b896da, trace_options=TraceOptions(enabled=True), tracestate=None)

...to the second microservice upon initialization, but it didn't work. When it starts counting the trace on the second microservice, it automatically generates new trace_id and span_id and ignores the span_context of the first one. I am out of ideas at this point.

EDIT2

What I want, is the entire trace (microservice 1 -> microservice 2 -> database) to appear under the same trace, with different spans. Something similar to this:

a new

suren
  • 7,817
  • 1
  • 30
  • 51
  • Hello Suren, let me know if I got this correctly _the first trace is from the database, and the second trace is both (from the first service to the second one + database)_ meaning that what you want is **from the first service to the second service to database to the first service** all in one trace so you can see the entire time it takes to get the answer. Am I right? If not, please elaborate so I can help. Thank you! – Luis Javier Alvarez Rodriguez Nov 28 '19 at 19:49
  • taht's correct. the first one is from the database, and the second one if from the first service to the second one, and from the second one to the database. And they appear in separate traces. What I want is them to appear in the same trace, but with different spans. I have added a new picture in my post (EDIT2) – suren Nov 29 '19 at 08:53

2 Answers2

1

Suren,

Can you please pass the trace_id instead of span_id ? That should show you everything in a single trace.

  • That's correct. I posted the answer, but wasn't sure I was doing it right, so deleted it to investigate more. But if you are confirming that's the way, I'll continue with it. Thanks. – suren Nov 29 '19 at 20:40
0

I got this done, in the end. Looks like, I had to pass the trace_id to the second microservice. Not span_id. But I have now a different problem, that I will put another question.

So, to sum up, I got solved the problem of having the traces in separate spans. Now they are in the same oneenter image description here:

The problem is that the first trace still includes the second one. And if I would have a third one, the first one would include them both, and the second one would include the third one, as I have no way to stop the first span from the second microservice. When I try, I get the following error.

WARNING:root:No active span, cannot do end_span.

What I tried is to end the first span from the second microservice right after getting there, but I get this error. I am just going to post another answer, as I can't go through this screen how.

suren
  • 7,817
  • 1
  • 30
  • 51