Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Opentracing bridge #388

Closed
wants to merge 12 commits into from
Closed

Conversation

beniwohli
Copy link
Contributor

@beniwohli beniwohli commented Jan 22, 2019

No description provided.

In other words,
it translates the calls to the OpenTracing API to Elastic APM and thus allows for reusing existing instrumentation.

The first span of a service will be converted to an Elastic APM
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

first span of a service trace / operation?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Saying "trace" here might be misleading, as a trace represents the request through multiple services.

But I agree that it is not super clear what is meant here. I'd love if opentracing would define something like an entry span, but they do not.

appears in the "User" tab in the transaction details in the Elastic APM UI
- `result` - sets the result of the transaction. Overrides the default value of `success`.

NOTE: these tags need to be set on the first span of an operation (e.g. an incoming request of your webapp).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

users still can set any arbitrary tags on spans, right? only that they will not be mapped to know fields. Ill rephrase L61 to something like: "Some tags are well defined in Elastic APM. If you defined these tags in the first span of an operation, the will be automatically mapped to defined fields..." and remove this Note

[[opentracing-instrumentation]]
==== Instrumentation

It is recommended to not use the built-in instrumentations of Elastic APM together with third-party OpenTracing instrumentations like https://pypi.org/project/opentracing_instrumentation/[opentracing_instrumentation].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll clarify that the advise is to not use 2 different instrumentation libraries for the same service, as the whole point of opentracing is to be able to mix different vendors for DT.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(side note: OpenTracing and distributed tracing aren't really related, and I don't think a goal of opentracing is to mix vendors. As far as I understand, the main goal of opentracing is to easily allow the user to switch vendor without (too many) code changes, but it doesn't define a common trace propagation protocol like the W3C traceparent (hopefully-soon-)standard does, and it says nothing about storage or data model.)

Do I understand you correctly that you'd like to add "in the same service" to the above sentence? That seems reasonable.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, thanks for clarifying!

thread_local = threading.local()
thread_local.transaction = None
from elasticapm.context.base import BaseContext

elasticapm_span_var = None
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why does this exist?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because I forgot to remove it when refactoring this whole bit :) good catch!

def __init__(self, client_instance=None, config=None, scope_manager=None):
self._agent = client_instance or self._elasticapm_client_class(config=config)
if scope_manager and not isinstance(scope_manager, ThreadLocalScopeManager):
warnings.warn(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if not supported, instead of issuing a use-at-your-own-peril warning isn't just better to ignore it and set self._scope_manager to ThreadLocalScopeManager()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, things will fail in hilarious ways anyway if you use asyncio or gevent with a ThreadLocalScopeManager. With this, people have at least the choice what kind of hilarity they want. Also, I hope to get at least asyncio covered Real Soon Now ™️ (maybe even this decade!)

else None
)
span = transaction.begin_span(operation_name, None, parent_span_id=parent_span_id)
trace_parent = parent_context.trace_parent if parent_context else transaction.trace_parent
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just to wrap my head around this, parent_context.trace_parent is not None when the span's parent is propagated from another service, right? if so, parent_context.trace_parent is not None means that transaction is None (because this is the first span of a service)?

another way of putting it: i actually don't understand this bit 🙈

ot_span.set_tag(k, v)
return ot_span

def extract(self, format, carrier):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why some errors return an exception (like carrier not supported) and others do not (like elastic-apm-traceparent header bad formatted)?

[[opentracing-baggage]]
==== Baggage
The `Span.set_baggage_item(key, value)` method is not supported.
Baggage items are silently dropped.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how this exactly happens? i was expecting to have set_baggage_item method implemented as a noop, but i don't find it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We inherit the noop-method from the super class

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could use a test, for some more explicitness 🙈

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in 4ca8859 (plus another few tests plus a fix for an issue I found thanks to those tests. "write more tests" is the lesson here I guess)

return self

def set_tag(self, key, value):
if self.is_transaction:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aren't a few known tags missing? context.request.cookies, context.request.headers, context.response...?

@@ -48,8 +48,8 @@ def __init__(self, tracer, transaction_type="custom", trace_parent=None, is_samp
def end_transaction(self):
self.duration = _time_func() - self.start_time

def begin_span(self, name, span_type, context=None, leaf=False, tags=None):
parent_span = get_span()
def begin_span(self, name, span_type, context=None, leaf=False, tags=None, parent_span_id=None):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this part of the agent API? if so, what do you think about making this private and keep a public begin_span without the parent_span_id argument?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you think of something like this? d33852d

Copy link
Contributor

@jalvz jalvz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awesome work!

@beniwohli beniwohli closed this in 8e820e8 Jan 29, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants