Feature/urllib instrumentation#222
Conversation
|
|
2cbd7ba to
6f20f48
Compare
toumorokoshi
left a comment
There was a problem hiding this comment.
Overall looks good! A couple questions around coding decisions, but nothing that would change functionality.
...on/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py
Outdated
Show resolved
Hide resolved
| opener_open = OpenerDirector.open | ||
|
|
||
| @functools.wraps(opener_open) | ||
| def instrumented_request(opener, fullurl, data=None, timeout=None): |
There was a problem hiding this comment.
it might make sense to allow *args / *kwargs here, since new methods may be added that need to be passed through to open.
Does that make sense here?
There was a problem hiding this comment.
Not sure, as AFAIK open does not support specific arguments open(self, fullurl, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT). I'd preferred left it as is. We can always add *args, **kwargs by request.
There was a problem hiding this comment.
The issue with that approach is that you're fixing an issue for people once it breaks them. I'm a bit wary of inconveniencing users knowingly.
That all said, this will probably only change over major version of Python, so the likelyhood is lower.
...on/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py
Show resolved
Hide resolved
| if not span_name or not isinstance(span_name, str): | ||
| span_name = get_default_span_name(method) | ||
|
|
||
| recorder = URLLibInstrumentor().metric_recorder |
There was a problem hiding this comment.
this feels a bit weird, to assume that a class has the appropriate field instantiated without actually being a method in that class.
Any reason not to move this method into URLLibInstrumentor, or pass a reference to the metric_recorder object that would be used the by the instrumented method?
There was a problem hiding this comment.
Sorry by I didn't catch the idea, metric_recorder is initialized inside main class in _instrument method. Or you are talking about a specific method like
get_metric_recorder(self): ?
There was a problem hiding this comment.
I'm referring to the fact that you're instantiating a ne wURLLibInstrumentor class, just to retrieve metric_recorder. This requires a reader to know:
- URLLibInstrumentor is a singleton, which requires reading more code about instrumentors
- understanding that this is safe because _instrument will only be called by URLLibInstrumentor, which may not be clear to someone who modifies this code later.
It would be much clearer if you put this code in as a method into URLLibInstrumentor because:
- you wouldn't have to instantiate a new URLLibInstrumentor, you could just reference it via
self._metric_recorder - It's much clearer to a reader that this method is intended to only be used with URLLibInstrumentor, because it's in the class.
| span_name = "" | ||
| if name_callback is not None: | ||
| span_name = name_callback() | ||
| if not span_name or not isinstance(span_name, str): |
There was a problem hiding this comment.
is this ok as a falsey check? I suppose an empty string span name being an actual desired span name is unlikely, but it might be better to just clarify the expected type here.
|
|
||
| token = context.attach( | ||
| context.set_value( | ||
| _SUPPRESS_URLLIB_INSTRUMENTATION_KEY, True |
There was a problem hiding this comment.
can you clarify why this is needed? It seems to me that, as this is the request being sent, it would be impossible really to have subsequent logic also fire another span, or do something that would create such spans.
There was a problem hiding this comment.
That's right, but here we only wrap this request or I've missing something ?
There was a problem hiding this comment.
I believe we do this for requests because some of the request calls have the same code path (but we instrument all of them) so we add this context variable to avoid duplicates. I'm not sure if urllib has the same issue though.
There was a problem hiding this comment.
We had a situation where this was needed in the botocore instrumentation to avoid infinite recursion. You can use botocore to send traces to our X-Ray backend using botocore.client('x-ray').put_trace_segments(). We had created our own exporter for the traces to not use the OTel Collector. So we would have:
- Send trace using our exporter and
botocore.put_trace_segments() BotocoreInstrumentorintercepts call tobotocoreand generates a new trace A.- Send trace A using our exporter and
botocore.put_trace_segments()to X-Ray. BotocoreInstrumentorintercepts call tobotocoreand generates a new trace B.- Send trace B using our exporter and
botocore.put_trace_segments()to X-Ray.
etc.
I imagine if someone exports using urllib they would encounter a similar problem.
There was a problem hiding this comment.
That makes sense. But isn't the solution in that scenario to have the exporter and instrumentation honor the "suppress_instrumentation" value?
@NathanielRN in the scenario you stated, the put_trace_segements in 1 should not have emitted a trace, avoiding this whole loop. If the BotocoreInstrumentor checks for the "suppress_instrumentation" context value, it should have emitted nothing.
instrumentation/opentelemetry-instrumentation-urllib/tests/test_urllib_integration.py
Show resolved
Hide resolved
|
Could we merge this code to the upstream without changes as no major issues were found. |
instrumentation/opentelemetry-instrumentation-urllib/CHANGELOG.md
Outdated
Show resolved
Hide resolved
...on/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py
Outdated
Show resolved
Hide resolved
...on/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py
Show resolved
Hide resolved
...on/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py
Outdated
Show resolved
Hide resolved
...ion/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/version.py
Outdated
Show resolved
Hide resolved
46785de to
ce69a70
Compare
...on/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py
Outdated
Show resolved
Hide resolved
|
@moaddib666 |
Thank you, sure, no rush as we already have workaround to deploy this instrumentation. |
toumorokoshi
left a comment
There was a problem hiding this comment.
Still have a couple changes I'd personally like to see (the URLLibInstrumentor() call in _instrumentor really bugs me), but not strong enough to request changes.
Thanks!
|
|
||
| token = context.attach( | ||
| context.set_value( | ||
| _SUPPRESS_URLLIB_INSTRUMENTATION_KEY, True |
There was a problem hiding this comment.
That makes sense. But isn't the solution in that scenario to have the exporter and instrumentation honor the "suppress_instrumentation" value?
@NathanielRN in the scenario you stated, the put_trace_segements in 1 should not have emitted a trace, avoiding this whole loop. If the BotocoreInstrumentor checks for the "suppress_instrumentation" context value, it should have emitted nothing.
instrumentation/opentelemetry-instrumentation-urllib/tests/test_urllib_integration.py
Show resolved
Hide resolved
|
@moaddib666 |
Sure, sorry for delay, I have limited internet connection right now, will update the PR early next week. |
Co-authored-by: Leighton Chen <lechen@microsoft.com>
…elemetry/instrumentation/urllib/__init__.py Co-authored-by: Leighton Chen <lechen@microsoft.com>
Co-authored-by: Leighton Chen <lechen@microsoft.com>
…elemetry/instrumentation/urllib/__init__.py Co-authored-by: Leighton Chen <lechen@microsoft.com>
…elemetry/instrumentation/urllib/version.py Co-authored-by: Leighton Chen <lechen@microsoft.com>
Co-authored-by: Leighton Chen <lechen@microsoft.com>
…elemetry/instrumentation/urllib/__init__.py Co-authored-by: Leighton Chen <lechen@microsoft.com>
fb74916 to
4c16255
Compare
|
Hi @lzchen, repo has been updated all tests were successfully passed. |
|
@moaddib666 Just one more thing, we've started using a consolidated top-level CHANGELOG so can you add your entry to that instead of creating a new one? |
|
@lzchen I just have email that PR was merged, thanks for your help ! |
Description
Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.
Fixes # (issue)
Type of change
Please delete options that are not relevant.
How Has This Been Tested?
Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
Does This PR Require a Core Repo Change?
Checklist:
See contributing.md for styleguide, changelog guidelines, and more.