-
Notifications
You must be signed in to change notification settings - Fork 628
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 net.peer.ip in requests & urllib3 instrumentations. #661
Conversation
What's up with these pylint errors? |
Any chance we can add this functionality to http utils? We already have that package to contain common http functionality. |
I think that should not be a technical problem. It will add a dependency on asgiref though and so far util-http only instruments server-side libs. If you prefer I can merge the new http-base package into util-http. |
@lzchen I'll go ahead and change the package. |
fa04708
to
b0437e3
Compare
@lzchen Done. Instead of adding a new package, I now extend the util-http package, like you suggested. |
logger = logging.getLogger(__name__) | ||
|
||
|
||
class HttpClientInstrumentor(BaseInstrumentor): |
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'm not too sure how this is supposed to be used by the user. Is this Instrumentor
instantiated as well along side RequestsInstrumentor
? Or is RequestsInstrumentor
supposed to extend this class?
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.
Oh, actually now that you say it, this was the reason why it was in a separate package...
This is not supposed to be used by the user at all. Instead it should just be loaded by the instrumentation infrastructure and then it does its thing behind the scentes. The requests and urllib3 instrumentations are the actual users of this code, since they register their wish to have the IP set onto a span which this instrumentation fulfills once the standard library httplib opens a socket.
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 I have to add an entrypoint to the setup.cfg of util-http as well as the other instrumentation boilerplate. Do you think it would be better to keep it as separate package?
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 mind having an entrypoint in http libraries for this, unless you feel strongly having another package. I personally don't like having many packages :).
Do all client libraries have a "send" method? If not, maybe we can just have trysetip
and set_ip_on_next_http_connection
as utility functions, and decorate the request functions directly? How come we need to create a new instrumentor for this feature?
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.
How come we need to create a new instrumentor for this feature?
Because this instruments the standard library httplib.client. I could put it in the urllib3 instrumentation, but if we ever want to instrument another library based on httplib.client (e.g. there is a urllib instrumentation here that could also be enhanched with this), then where should we put it if not in a separate, independent instrumentor?
Do all client libraries have a "send" method?
No, just (those based on) httplib.client, which applies to requests and urllib3 at least.
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.
Even the tests have:
HttpClientInstrumentor().instrument() URLLib3Instrumentor().instrument()
Yes. The tests need to call HttpClientInstrumentor().instrument()
manually since no distribution (is it called that?) is loaded that auto-enables the instrumentation. URLLib3Instrumentor().instrument()
cannot call HttpClientInstrumentor().instrument()
IIUC, as that would lead to double instrumentation. Also, I wanted to have the feature optional. If users disable the HttpClientInstrumentor (not sure if this is possible today), they won't get net.peer.ip and potential associated overhead and bugs.
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 confirming here. As a user, if I manually instrument code, and load the RequestsInstrumentor
, I will also need to manually load the HttpClientInstrumentor
myself correct?
Would it be possible to call trysetip
from the requests/urlib3 code and skip the additional instrumentor? Or is the problem that those libraries don't have access to the underlying socket to pull IP information from it?
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.
Yes, the main reason was that its not easy to get the underlying socket. I did not check for every library separately, in some it may be possible to use some undocumented properties or instrument some constructors to get to the socket. Instrumenting httplib.client, although also awkward, seemed like the most clean way.
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.
Got it, that makes sense. Thanks!
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.
@codeboten To follow up here: Is manually using the instrumentors common enough that it would make sense to add a hint to use HttpClientInstrumentor to the READMEs of the requests and urllib3 instrumentations?
Sorry I might be missing something. Where is the dependency for |
The code in this PR does not depend on asgiref, but the util-http package does. |
@lzchen You are right, seems I somehow looked in the wrong place 😄 |
@@ -40,3 +40,7 @@ packages=find_namespace: | |||
|
|||
[options.packages.find] | |||
where = src | |||
|
|||
[options.entry_points] | |||
opentelemetry_instrumentor = |
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.
Compared to the original PR version with a separate package for this:
On the minus side, this now means that everyone depending on util-http will get the httplib.client instrumentation, even if they don't use it. The overhead should be small though. On the plus side, there is no new package.
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.
The benefit of not having a new package outweighs the small overhead I feel :)
@@ -40,3 +40,7 @@ packages=find_namespace: | |||
|
|||
[options.packages.find] | |||
where = src | |||
|
|||
[options.entry_points] | |||
opentelemetry_instrumentor = |
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.
BTW, is there some integration test that loads the urllib3 or requests instrumentation via the entrypoint, that I could extend to assert on the net.peer.ip attribute being present, so I could verify the wiring is not messed up 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.
Just to clarify, you are wanting to test if attribute is present if auto-instrumentation is used? If so, I don't believe we have integration tests for those. We currently only have unit tests for auto-instrumentation.
Is there anything I can do to move this forward? |
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.
The code looks good, just one clarifying question regarding the flow of how the instrumentation is used.
logger = logging.getLogger(__name__) | ||
|
||
|
||
class HttpClientInstrumentor(BaseInstrumentor): |
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 confirming here. As a user, if I manually instrument code, and load the RequestsInstrumentor
, I will also need to manually load the HttpClientInstrumentor
myself correct?
Would it be possible to call trysetip
from the requests/urlib3 code and skip the additional instrumentor? Or is the problem that those libraries don't have access to the underlying socket to pull IP information from it?
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.
👍
logger = logging.getLogger(__name__) | ||
|
||
|
||
class HttpClientInstrumentor(BaseInstrumentor): |
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.
Got it, that makes sense. Thanks!
Description
Capture net.peer.ip in requests & urllib3 instrumentations, using a shared new
packageinstrumentor for httplib.client that could also be used to easily add net.peer.ip to other instrumentations based on the stdlib's httplib.client (but this PR starts with only the aforementioned two).opentelemetry-instrumentation-http-base
Type of change
Please delete options that are not relevant.
How Has This Been Tested?
Unit tests included. Due to how sharing of test code is currently set up, this requires a change to the main repo to add the test base class.
Does This PR Require a Core Repo Change?
Checklist:
Documentation has been updated