-
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
Cherrypy instrumentation #1410
base: main
Are you sure you want to change the base?
Cherrypy instrumentation #1410
Conversation
@@ -0,0 +1,140 @@ | |||
from email.policy import default |
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.
?
) | ||
from opentelemetry import trace, context | ||
from opentelemetry.semconv.trace import SpanAttributes | ||
from opentelemetry.instrumentation.falcon.version import __version__ |
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.
?
return _instruments | ||
|
||
def _instrument(self, **kwargs): | ||
self._original_cherrypy_application = cherrypy._cptree.Application |
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.
There should be a better way to do this. We can't use the private symbols because they are not guaranteed to remain backward compatible.
def _instrument(self, **kwargs): | ||
self._original_cherrypy_application = cherrypy._cptree.Application | ||
cherrypy._cptree.Application = _InstrumentedCherryPyApplication | ||
cherrypy.Application = _InstrumentedCherryPyApplication |
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.
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.
Issue with these hooks are that they needed to be called for every paths that we want to use them for. They do not apply directly to everywhere. source
@@ -0,0 +1,3 @@ | |||
_instruments = ("cherrypy >= 1.0",) |
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.
Please also pin the upper version, there can be breaking changes b/w major version changes.
span.set_attributes(custom_attributes) | ||
|
||
if self.response_hook: | ||
self.response_hook(span, status, response_headers) |
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.
Please add tests. If the PR is not ready then please mark it a draft.
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.
Hey, I'm really sorry. I forgot to mark this PR draft. There's still lot of work required in this PR.
ea77939
to
4933b32
Compare
* added new testcases related to basic rest api calls and spans check for instrumentation * added tox changes and metrices testcases and fixed review comments * added metrices testcases and review comments fixed * added fixes for review comments Co-authored-by: rahmukhe <rahmukhe@appdynamics.com>
…ul756/opentelemetry-python-contrib into cherrypy-instrumentation
I've came up with three different approaches for instrumentation in cherrypy and I wanted to discuss all three of them with there pros and cons. Instrumentation with CherryPy HooksUnlike other frameworks, CherryPy does not have support for custom middleware. Instead, CherryPy provides some hook points where you can add your functions. Datadog uses this approach for instrumentation. But all the endpoints for which tools need to be used must be decorated by that tool.
Because of it, this approach can only be used for manual instrumentation, not auto-instrumentation. Although there are some workarounds that I came up with (like monkey patching the expose function) but they were also not covering all the possible cases (what if the function is not exposed with expose decorator Instrumentation with CherryPy Publisher Subscriber
Various channels are available in CherryPy, but only two were helpful to us, i.e. Instrumentation by Patching CherryPy Application classThis is how we have instrumented various frameworks, and this approach can also be done here. New Relics and Appdynamics agent also uses this approach. The issue with this approach is
I've implemented all three approaches and tested them to understand their pros and cons. The first two approaches will also come with other challenges, such as handling exceptions. And the third approach, although being backward incompatible, is tried and tested and guarantees to work. |
I am not against the idea of patching the Application class but I don't think it is a good idea to patch the private/internals of the framework.
What is guaranteed here? Overall, I don't think it's a good idea to patch the private/internals of the library. We have seen this fail with a few instrumentations, so they either had to be pinned to some minor version which works or rewritten to not patch private symbols and get it to work in general. I would like to hear others thoughts on this @open-telemetry/opentelemetry-python-contrib-approvers . |
* added new testcases related to basic rest api calls and spans check for instrumentation * added tox changes and metrices testcases and fixed review comments * added metrices testcases and review comments fixed * added fixes for review comments * added custom header testcases for instrumentation * removed print statements * added return statement to cherrypy app Co-authored-by: rahmukhe <rahmukhe@appdynamics.com>
Sorry for the misunderstanding. What I mean by 'guarantee' here is that with other approaches, some loopholes could be there with instrumentation, like some exceptions could be missed or the way the endpoints are exposed could affect the instrumentation. And this approach covers all the possible cases.
I understand your concern, which is why I tried instrumenting with other approaches, but nothing seems to work completely unless someone has a better idea. |
@@ -0,0 +1,40 @@ | |||
OpenTelemetry CherryPy Tracing |
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.
Please add an example how to use this instrumentation
from typing import Collection | ||
|
||
from opentelemetry.util.http import parse_excluded_urls, get_excluded_urls, get_traced_request_attrs | ||
import cherrypy |
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.
organize the import statement properly
|
||
|
||
class CherryPyInstrumentor(BaseInstrumentor): | ||
"""An instrumentor for FastAPI |
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.
Change the docstring from FastAPI to CherryPy. Also please add an example how to use it
activation.__exit__(None, None, None) | ||
else: | ||
activation.__exit__( | ||
type(exc), |
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.
you should use exception instead of exc just to make it more readable
for key, _ in not_expected.items(): | ||
self.assertNotIn(key, server_span.attributes) | ||
|
||
class TestNonRecordingSpanWithCustomHeaders(TestBase, helper.CPWebCase): |
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 dont you inherit this class from the TestCherryPyBase and override all functions? This will remove some redundant code
Also resolve the build checks |
@open-telemetry/opentelemetry-python-contrib-approvers Please share your thoughts on this. |
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 #1130
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.