-
Notifications
You must be signed in to change notification settings - Fork 133
Initial Hybrid Agent Trace implementation #1587
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
base: develop-hybrid-core-tracing
Are you sure you want to change the base?
Conversation
✅MegaLinter analysis: Success
See detailed reports in MegaLinter artifacts |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop-hybrid-core-tracing #1587 +/- ##
==============================================================
Coverage ? 79.94%
==============================================================
Files ? 210
Lines ? 24488
Branches ? 3886
==============================================================
Hits ? 19578
Misses ? 3548
Partials ? 1362 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
13df939 to
b45a7c8
Compare
hmstepanek
left a comment
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.
Just reviewed this one class so far but wanted to get you the feedback now rather than waiting until next week.
| # but for debug purposes, we will raise an error | ||
| _logger.debug("Otel span and NR trace do not match nor correspond to a remote span") | ||
| _logger.debug("otel span: %s\nnewrelic trace: %s", self.otel_parent, current_nr_trace) | ||
| raise ValueError("Unexpected span parent scenario encountered") |
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.
Is this error caught somewhere?
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.
In this case, I cannot think of a scenario where this would happen, so I wanted to keep this here for debug purposes.
| _logger.debug("otel span: %s\nnewrelic trace: %s", self.otel_parent, current_nr_trace) | ||
| raise ValueError("Unexpected span parent scenario encountered") | ||
|
|
||
| if nr_trace_type == FunctionTrace: |
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 have a lot of questions about these. Mainly; shouldn't we be pulling all the attributes out of the OTEL attr list and mapping the here into the appropriate NR equivalents unless there isn't a spot for them in which case they are supposed to become user attributes according to the spec?
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.
That part will come in a separate PR. For now, the attributes are added as custom attributes, but the actual attribute mapping per SpanKind will come in separate PRs. Of course, most of the time, the attributes are not added during initialization, but rather throughout the span's operation, so I will be adding logic to add these when the span is ending.
| elif nr_trace_type == DatastoreTrace: | ||
| trace_kwargs = { | ||
| "product": self.instrumenting_module, | ||
| "target": None, |
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.
It looks like target maps to OTEL's db.name.
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.
It does! The issue with the OTel attributes is that the db.name attribute is usually not set during the creation of the span, but rather later on in the span's operation.
newrelic/api/opentelemetry.py
Outdated
| def record_exception(self, exception, attributes=None, timestamp=None, escaped=False): | ||
| if not hasattr(self, "nr_trace"): | ||
| if exception: | ||
| notice_error((type(exception), exception, exception.__traceback__)) |
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.
Should we be passing attributes here too?
newrelic/api/opentelemetry.py
Outdated
| else: | ||
| notice_error(sys.exc_info(), attributes=attributes) | ||
| else: | ||
| self.nr_trace.notice_error((type(exception), exception, exception.__traceback__), attributes=attributes) |
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.
What if there's no exception here?
| # TODO: not implemented yet | ||
| pass | ||
|
|
||
| def record_exception(self, exception, attributes=None, timestamp=None, escaped=False): |
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.
Should we be doing something with timestamp and escaped here?
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.
It does not seem like we will do anything with the escaped argument, and the timestamp argument will be used for the events/log events (which I have not implemented yet)
| # We will ignore the end_time parameter and use NR's end_time | ||
|
|
||
| # Check to see if New Relic trace ever existed or, | ||
| # if it does, that trace has already ended |
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.
Maybe store this value and simplify the logic rather than calling hasattr a bunch:
nr_trace = hasattr(self, "nr_trace", None)
if not nr_trace or nr_trace and getattr(nr_trace, "end_time", None):
return
Co-authored-by: Hannah Stepanek <[email protected]>
Co-authored-by: Hannah Stepanek <[email protected]>
Co-authored-by: Hannah Stepanek <[email protected]>
Co-authored-by: Hannah Stepanek <[email protected]>
Co-authored-by: Hannah Stepanek <[email protected]>
Co-authored-by: Hannah Stepanek <[email protected]>
Co-authored-by: Hannah Stepanek <[email protected]>
Co-authored-by: Hannah Stepanek <[email protected]>
Co-authored-by: Hannah Stepanek <[email protected]>
Co-authored-by: Hannah Stepanek <[email protected]>

This PR contains a barebones tracing implementation.
Implementation for different transaction types, Distributed Tracing/context propagation, tracer configuration, instrumentation scope attributes, and meters will come in subsequent PRs