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

ext/requests: Add instrumentor #597

Merged
merged 11 commits into from
Apr 27, 2020
Merged

ext/requests: Add instrumentor #597

merged 11 commits into from
Apr 27, 2020

Conversation

mauriciovasquezbernal
Copy link
Member

Implement the BaseInstrumentor interface to make this library compatible with the opentelemetry-auto-instr command.

There is an issue about getting the span when the global tracer provider hasn't been configured, this should be changed in the future once we extend the opentelemetry-auto-instr command to also configure the SDK.

@mauriciovasquezbernal mauriciovasquezbernal added ext instrumentation Related to the instrumentation of third party libraries or frameworks labels Apr 20, 2020
@mauriciovasquezbernal mauriciovasquezbernal marked this pull request as ready for review April 20, 2020 13:05
@mauriciovasquezbernal mauriciovasquezbernal requested a review from a team as a code owner April 20, 2020 13:05
@mauriciovasquezbernal mauriciovasquezbernal added the needs reviewers PRs with this label are ready for review and needs people to review to move forward. label Apr 23, 2020
Implement Instrumentor interface to allow user enabling instrumentation in the
library and to work with autoinstrumentation.
Set span status from http status code.
Copy link
Contributor

@codeboten codeboten left a comment

Choose a reason for hiding this comment

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

This is looking great. I tested it with opentelemetry-auto-instrumentation and got some traces with the following code

from opentelemetry import trace
from opentelemetry.sdk.trace.export import (
    ConsoleSpanExporter,
    SimpleExportSpanProcessor,
)

import requests

trace.get_tracer_provider().add_span_processor(
    SimpleExportSpanProcessor(ConsoleSpanExporter())
)

url = f"https://wikipedia.org"
try:
    res = requests.get(url)
    print(f"Request to {url}, got {len(res.content)} bytes")
except Exception as e:
    print(f"Request to {url} failed {e}")

@@ -28,15 +28,18 @@

# The preferred tracer implementation must be set, as the opentelemetry-api
# defines the interface with a no-op implementation.
# It must be done before instrumenting any library.
Copy link
Contributor

Choose a reason for hiding this comment

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

Will this change once the instrumentor interface supports configuration?

Copy link
Member Author

Choose a reason for hiding this comment

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

In this particular example all the calls to instrument() omit the tracer_provider parameter, it means the current configured is used. If there is not any configured, and OPENTELEMETRY_PYTHON_TRACER_PROVIDER is not set, a default no-op will be used.

I think the common approach we should suggest in the examples is.

  1. trace.set_tracer_provider(TracerProvider()) (We don't want to mess up with env variables in the examples)
  2. instrument the libraries
  3. configure the span processor and exporters
  4. use of the instrumented framework.

opentelemetry.ext.http_requests.enable(TracerProvider())
response = requests.get(url='https://www.example.org/')
# You can optionally pass a custom TracerProvider to RequestInstrumentor.instrument()
opentelemetry.ext.http_requests.RequestInstrumentor.instrument()
Copy link
Contributor

Choose a reason for hiding this comment

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

should this example show how to pass a TracerProvider?

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't think so. Passing a TracerProvider is an advanced use case, we don't expect it to be common.

Copy link
Member

Choose a reason for hiding this comment

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

how about the example with the kwarg as none: instrument(tracer_prover=None). If I saw that comment, I would have no idea what the argument name is for passing my own TracerProvider.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think this documentation should be as simple as possible and the documentation about the parameters of such function should be on the generated documentation, that we don't know how to do right now: https://github.com/open-telemetry/opentelemetry-python/issues/617.

_tracer = None


def _http_status_to_canonical_code(code: int, allow_redirect: bool = True):
Copy link
Contributor

Choose a reason for hiding this comment

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

nice!

Copy link
Member

Choose a reason for hiding this comment

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

should we follow up and move this somewhere up the packages? this is duplicated in 4-5 places now.

I hesitate to suggest the api package, which is the only common dependency. Or maybe an opentelemetry-instrumentor-utils?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think we should move that to a new package in the future, I'd like to avoid doing that on this PR as I want this to be in asap. By the way, I opened an issue to initiate the discussion about that #610, I think an utils package for instrumentors is the best idea.

@@ -103,12 +110,12 @@ def instrumented_request(self, method, url, *args, **kwargs):

span.set_attribute("http.status_code", result.status_code)
span.set_attribute("http.status_text", result.reason)
span.set_status(
Status(_http_status_to_canonical_code(result.status_code))
Copy link
Contributor

Choose a reason for hiding this comment

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

did you want to pass an argument for allow_redirect here?

Copy link
Member Author

Choose a reason for hiding this comment

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

I took the code from

def http_status_to_canonical_code(code: int, allow_redirect: bool = True):
, I'm not sure if I should set the flag here.

Copy link
Member

Choose a reason for hiding this comment

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

Looking at that code, it only applies to the 399 status code, which is unassigned. @Oberon00 any insight into the rationalle for the parameter, and the 399 status code? Looks like you were one of the authors of that commit.

@@ -29,23 +30,25 @@ class TestRequestsIntegration(TestBase):

def setUp(self):
super().setUp()
opentelemetry.ext.http_requests.enable(self.tracer_provider)
http_requests.RequestsInstrumentor().instrument()
Copy link
Contributor

Choose a reason for hiding this comment

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

should this be passing in the tracer_provider?

Copy link
Member Author

Choose a reason for hiding this comment

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

TestBase is doing trace.set_tracer_provider(cls.tracer_provider), so it's the same.

@mauriciovasquezbernal
Copy link
Member Author

@codeboten just as a reference, the example you provided requires OPENTELEMETRY_PYTHON_TRACER_PROVIDER=sdk_tracer_provider to be set in order to work.

@mauriciovasquezbernal mauriciovasquezbernal changed the title ext/requests: Implement BaseInstrumentor interface ext/requests: Add instrumentor Apr 24, 2020
opentelemetry.ext.http_requests.enable(TracerProvider())
response = requests.get(url='https://www.example.org/')
# You can optionally pass a custom TracerProvider to RequestInstrumentor.instrument()
opentelemetry.ext.http_requests.RequestInstrumentor.instrument()
Copy link
Member

Choose a reason for hiding this comment

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

how about the example with the kwarg as none: instrument(tracer_prover=None). If I saw that comment, I would have no idea what the argument name is for passing my own TracerProvider.

@@ -103,12 +110,12 @@ def instrumented_request(self, method, url, *args, **kwargs):

span.set_attribute("http.status_code", result.status_code)
span.set_attribute("http.status_text", result.reason)
span.set_status(
Status(_http_status_to_canonical_code(result.status_code))
Copy link
Member

Choose a reason for hiding this comment

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

Looking at that code, it only applies to the 399 status code, which is unassigned. @Oberon00 any insight into the rationalle for the parameter, and the 399 status code? Looks like you were one of the authors of that commit.

_tracer = None


def _http_status_to_canonical_code(code: int, allow_redirect: bool = True):
Copy link
Member

Choose a reason for hiding this comment

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

should we follow up and move this somewhere up the packages? this is duplicated in 4-5 places now.

I hesitate to suggest the api package, which is the only common dependency. Or maybe an opentelemetry-instrumentor-utils?

Copy link
Contributor

@lzchen lzchen left a comment

Choose a reason for hiding this comment

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

LGTM! Just a few non-blocking questions/comments. Good work!

@toumorokoshi toumorokoshi merged commit 8e3ed35 into open-telemetry:master Apr 27, 2020
srikanthccv pushed a commit to srikanthccv/opentelemetry-python that referenced this pull request Nov 1, 2020
* chore(plugin-https): sync https tests with http

* chore: use Http instead typeof http

* chore: review finding, improve https detection

* chore: fix node 8

* chore: fix path to test files
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
instrumentation Related to the instrumentation of third party libraries or frameworks needs reviewers PRs with this label are ready for review and needs people to review to move forward.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants