Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Context propagation using AWS S3 metadata #1715

Answered by srikanthccv
CeeBeeCee asked this question in Q&A
Discussion options

Hello everyone,

I have a Python app running on an AWS ECS container that goes out to a FTP server, fetches a file and places it in AWS' object store S3. Once a file gets placed, that creates an event which kicks off a AWS Python Lambda (serverless function) for further processing. Both the Python processes are instrumented with OTel and are production separate traces. Now I'm trying to combine them together as a single trace with the ECS span being the parent and the Lambda being the child.

So far, I've been able to pass the trace headers via S3's metadata from the ECS app.

`span = trace.get_current_span()

traceparent = "{}-{}-{}-{}".format(
"00",
trace.format_trace_id(span.context.trace_id)[2:],
trace.format_span_id(span.context.span_id)[2:],
"01"
)

s3_client.put_object(Bucket=bucket,
Metadata={'traceparent': traceparent}
)`

In the Lambda, I can read traceparent :

traceparent = response['Metadata']['traceparent']

What I need help with is creating a span in the Lambda such that it becomes a child span? Does anyone have experience doing something like this or can point me to sample code that I can reference?

Appreciate your help!
Thanks

You must be logged in to vote

Are you looking for a way to extract the trace context from carrier and use is it in your code? Probably something like this helps.

...
from opentelemetry.trace.propagation.textmap import DictGetter
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
...
carrier = {'traceparent': '00-a9c3b99a95cc045e573e163c3ac80a77-d99d251a8caecd06-01'} # response['Metadata'] in your case?
ctx = TraceContextTextMapPropagator().extract(DictGetter(), carrier)
# with 1.0 getter/setter are optional and `extract` signature changed. It would be just 
# `.extract(carrier)` as default getter is `DictGetter()`
with tracer.start_as_current_span('child', ctx):
 ...

Replies: 1 comment 4 replies

Comment options

Are you looking for a way to extract the trace context from carrier and use is it in your code? Probably something like this helps.

...
from opentelemetry.trace.propagation.textmap import DictGetter
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
...
carrier = {'traceparent': '00-a9c3b99a95cc045e573e163c3ac80a77-d99d251a8caecd06-01'} # response['Metadata'] in your case?
ctx = TraceContextTextMapPropagator().extract(DictGetter(), carrier)
# with 1.0 getter/setter are optional and `extract` signature changed. It would be just 
# `.extract(carrier)` as default getter is `DictGetter()`
with tracer.start_as_current_span('child', ctx):
 ...
You must be logged in to vote
4 replies
Comment options

@lonewolf3739 : Thanks for the quick response. This looks to be what we need. Will test this out and let you know how it goes. Thanks again.

Comment options

Hi @lonewolf3739 : That worked great! The only issue I'm seeing is that the duration of the child span does not seem to get added to the overall duration of the trace. Do you know why?

image

Comment options

I am not sure what's happening at your end but my first guess would be that parent span ends before ctx_propagation_test_child.

Comment options

I am in a pretty similar situation: I have a service (in Elixir) which serializes the context, and sends over as a HTTP header. On the other side, in python, I have a callback (which is the one called from Elixir, in a synchronous call, so I don't expect problems with overall durations) which creates other spans. I have not yet understood how to inflate/use the context I have received over the line. Of course no error shown, etc. I have tried the above Propagator solution, but also SpanCtx reinflation with the payload received and using it in:

with tracer.start_as_current_span(span_name, context=ctx):
 ....

where ctx is the SpanContext I have inflated.

The result is that the new spans are at the root level, and not correcly grouped under the proper trace.
What am I missing ?

Thanks in advance.

Answer selected by CeeBeeCee
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet

AltStyle によって変換されたページ (->オリジナル) /