-
Notifications
You must be signed in to change notification settings - Fork 651
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
Add support for lazy events and links #474
Add support for lazy events and links #474
Conversation
The computation of attributes is expensive in some conditions, even in some cases those attributes are not used at all. This commit fixes the add_lazy_event method by providing a true solution that delays the attributes calculation until attributes are accessed. It also provides a new LazyLink class.
ab3515d
to
17aad29
Compare
@@ -149,7 +221,7 @@ def __init__( | |||
trace_config: None = None, # TODO | |||
resource: None = None, | |||
attributes: types.Attributes = None, # TODO | |||
events: Sequence[trace_api.Event] = None, # TODO | |||
events: Sequence[Event] = None, # TODO |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't Tracer.start_span
and Tracer.start_as_current_span
take in events
as well in the api, since you can pass in events into the constructor of a span? I think if this is the case, you have to move the
Event` definition back from the sdk to the api.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/api-tracing.md#span-creation the events cannot be passed at start creation time, infact we should remove them from the constructor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense. Curious, what does the # TODO
refer to in the code? Can that be removed with these changes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know what the TODO was about. I'll remove that in a followup PR in next days.
149dd66
to
21ba2a9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few comments, but it largely LGTM.
I was surprised to see the lazy classes don't eventually return Event
s and Link
s, but are instead copies of those classes that do lazy attribute creation. It's consistent with the spec, but I'm worried it complicates the API without much benefit.
And it's a topic for another issue, but I think we should be distinguish between abstract classes that are meant to be implemented as part of the SDK and those that are just there to prevent accidentally instantiating a base class. Having mixed base/abstract classes in the API muddies this.
@@ -26,3 +26,4 @@ | |||
Sequence[float], | |||
] | |||
Attributes = Optional[Dict[str, AttributeValue]] | |||
AttributesFormatter = Callable[[], Optional[Dict[str, AttributeValue]]] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AttributesFormatter = Callable[[], Optional[Dict[str, AttributeValue]]] | |
AttributesFormatter = Callable[[], Attributes] |
Or am I missing something about these types?
else: | ||
self._timestamp = timestamp | ||
|
||
@property |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using properties in the base class means implementations can't use regular attributes. Not a big deal if we don't expect users to extend EventBase
and LinkBase
though.
def timestamp(self) -> int: | ||
return self._timestamp | ||
def attributes(self) -> types.Attributes: | ||
return self._link_formatter() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you want to call this every time the user accesses attributes? It seem like it would be better to cache them after the first call.
def __init__( | ||
self, | ||
context: "SpanContext", | ||
link_formatter: types.AttributesFormatter, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know the spec says this "SHOULD be named LinkFormatter
", but I think that assumes it's returning a Link
. attribute_formatter
sounds like a better name in both classes because this is responsible for returning Attributes
, and not specific to either links or events.
Event( | ||
name=name, | ||
attributes=attributes, | ||
timestamp=time_ns() if timestamp is None else timestamp, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do this here if EventBase
constructor does the same thing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the code looks functionally correct. And I may change to an approve based on the fact that this is technically following the spec.
But I think Event (or the ABC) should still be in the API. I feel like it's an oversight that the spec calls out an Event adder interface and even the fields of such an object, but falls short of the API actually requiring it.
If the Event ABC can be moved back to the API for now, I'll switch to approved.
Also an aside and not a blocker, but "Formatter" feels weird to me. So two related issues in spec:
open-telemetry/opentelemetry-specification#532
open-telemetry/opentelemetry-specification#533
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whelp, I've been schooled :) open-telemetry/opentelemetry-specification#532. Sorry to hold you up, I think, at the moment, moving events to the SDK is an appropriate one.
This PR didn't aim to solve all the issues with lazy events & links, I wanted to fix the support for those events that was badly broken. I see that there are still discussions about whether lazy events and links are needed or not, and also how to implement it, it's not even clear for me if other SIGs had implemented it or not. Probably it's something we'd like to keep an eye on, I think it's likely that we are going to change it in next releases. |
* feat(metrics): add registerMetric and getMetric functionality * fix: getTimeSeries and add more tests * fix: minor * fix: add JSDoc * fix: minor * fix: remove * fix: replace String -> string * fix: avoid casting * fix: use GAUGE_DOUBLE and COUNTER_DOUBLE type * fix: add ValueType to indicate type of the metric * fix: move ValueType.DOUBLE to DEFAULT_METRIC_OPTIONS * fix: use Number.isInteger * fix: log an error instead of throw error * fix: add more test and @todo comment * fix: link open-telemetry#474 isssue
This PR fix the support for lazy events and links.
The idea behind this PR is to have two versions of each class,
Link
andLazyLink
.Link
is constructed using the already calculated attributes, whileLazyLink
receives anlink_formatter
function that returns the attributes when invoked.This PR also moves the class
Event
definition to the SDK because after the changes toadd_lazy_event
it is not used anywhere on the API.Fixes #384.