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

[flask] rewrite Flask integration #667

Merged
merged 82 commits into from Nov 6, 2018
Merged

Conversation

brettlangdon
Copy link
Member

@brettlangdon brettlangdon commented Oct 23, 2018

We have decided to rewrite our Flask integration to provide more visibility into the Flask internals as well as to add some auto-instrumentation around user generated code (views, error handlers, etc).

Changes:

  • Trace Flask internals rather than use signals/middleware to trace
  • Add tracing to request lifecycle (request, preprocess, dispatch, postprocess, etc)
  • Add tracing to signals (request_started, request_finished, etc)
  • Add tracing to hooks (before_request, after_request, after_this_request, etc)
  • Add tracing to response helpers (jsonify, send_file, etc)
  • Add tracing to all routes, views, endpoints added to the Flask app
  • Enable Flask tracing by default and move to patch on import

Before

unknown

After

unknown

@brettlangdon
Copy link
Member Author

@Kyle-Verhoog I should have addressed all of your comments :)

@brettlangdon
Copy link
Member Author

ugh, Github is really bad, I think there are a bunch of comments I missed...

ddtrace/pin.py Outdated
@@ -56,6 +56,25 @@ def __repr__(self):
return "Pin(service=%s, app=%s, app_type=%s, tags=%s, tracer=%s)" % (
self.service, self.app, self.app_type, self.tags, self.tracer)

@staticmethod
def find(*objs):
Copy link
Member Author

Choose a reason for hiding this comment

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

@Kyle-Verhoog and @palazzem

I found myself writing a helper get_inherited_pin() with the idea that there was an order to which I would look-up a Pin, either in the wrapped, instance, or maybe flask.current_app, etc.

Not sure if this is a public API we care to expose, seemed "harmless" to add, and potentially useful as we broaden the discussion about pin/config overriding.

Copy link
Member Author

Choose a reason for hiding this comment

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

totally happy to either change my code to not need something like this, or to move it back into a flask specific helper.

Copy link
Member

Choose a reason for hiding this comment

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

I think the API is fine to have on the Pin. However, I think we can keep it private for now since we do document the Pin publicly: http://pypi.datadoghq.com/trace/docs/advanced_usage.html#pin.

But we are going to be deprecating the public Pin api soon anyway.

Kyle-Verhoog
Kyle-Verhoog previously approved these changes Oct 31, 2018
Copy link
Member

@Kyle-Verhoog Kyle-Verhoog left a comment

Choose a reason for hiding this comment

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

Great! ❤️ the tests. They are definitely a model of what our future integrations should look lik.e They give me confidence in the integration.

Just some left over nits, but it's good to go in my opinion. 👍

ddtrace/pin.py Outdated Show resolved Hide resolved
tests/contrib/flask/test_request.py Outdated Show resolved Hide resolved
tests/contrib/flask/test_request.py Outdated Show resolved Hide resolved
signal.send(*args, **kwargs)
return func
finally:
# DEV: There is a bug in `blinker.Signal.disconnect` :(
Copy link
Member

Choose a reason for hiding this comment

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

Is there a link to a bug report that we can reference 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.

there isn't, I should probably open one.

the TL;DR; it has something to do with how they create weak references and when you disconnect they can't find the original function in their list... something like that.

@clutchski
Copy link
Contributor

clutchski commented Oct 31, 2018

@brettlangdon i'd suggest trimming anything that won't be interesting (e.g. dispatch request might never be interesting whereas the method it callsapp.app_index is always interesting)

@brettlangdon
Copy link
Member Author

@Kyle-Verhoog this needs one finally approval... approval gets reset whenever a commit is pushed.

Kyle-Verhoog
Kyle-Verhoog previously approved these changes Nov 5, 2018
@brettlangdon brettlangdon changed the base branch from master to 0.16-dev November 6, 2018 13:21
@brettlangdon brettlangdon merged commit 4c3a745 into 0.16-dev Nov 6, 2018
brettlangdon added a commit that referenced this pull request Nov 8, 2018
* [flask] start work on new patch implementation

* [flask] trace more internal parts

* [flask] trace more things

* [flask] round out prototype of new tracing

* [flask] replace old patch.py with new_patch.py

* [flask] finish up prototype and deduplicate some code

* [flask] move wrapper helpers to wrappers.py

* [flask] add docstrings

* [flask] remove unused import

* [flask] Update documentation

* [flask] < 0.12.0 does not have Flask.finalize_request

* [flask] handle status code as a string

* [flask] use config API

* [flask] update version parsing

* [flask] patch signal receivers_for and add unpatch()

* [flask] add test for Flask signals

* [flask] fix patching/unpatching lists

* [flask] use template name as span resource name

* [flask] set test template directory

* [flask] add test cases for Flask helpers

* [flask] add test cases for Flask render functions

* [flask] add test helpers to check if something is wrapped

* [flask] simplify pin cloning logic

* [flask] add blueprint tests

* [flask] rename patch.py to monkey.py

* [flask] make sure do to do Pin(tracer=self.tracer) in tests

* [flask] fix spelling

* [flask] add patch/unpatch idempotency tests

* [flask] add initial support for v0.9

* [flask] update tests for v0.9

* [flask] use <= (0, 9) instead of == (0, 9)

* [flask] fix signal names

* [flask] add assertion message

* [flask] skip send_from_directory

* [flask] add find_span_by_name test helper

* [flask] add error handler test cases

* [flask] Use start_response instead of Flask.finalize_request for response code

* [flask] assert bytes equality

* [flask] add test caes for flask.views.View

* [flask] enable by default

* [flask] remove large TODO comment

* [flask] change 404 resource name to '<method> 404'

* [flask] fix py2 vs py3 base exception name

* [flask] add request lifecycle tests

* [flask] support unicode

* [flask] rewrite Flask autopatch tests

* [flask] run py27-flask09 tests in circleci

* [flask] add static file tests

* [flask] rename monkey.py back to patch.py

* [flask] update docstring for flask being enabled by default

* [flask] fix comments and docstrings

* [flask] use ddtrace.utils.importlib.func_name

* [core] modify Pin.get_from to accept multiple objects

* [flask] fix remaining get_arg_or_kwargs

* [flask] only use '<method> 404' if the endpoint is unknown

* [flask] use request.path for http.URL tag

* [flask] remove/fix TODOs

* [flask] Add Pin.find(*objs) helper

* [flask] only use 'def _wrap()' where necessary

* [flask] mark 5xx errors by default, allow config of additional error codes

* Update tests/contrib/flask/test_request.py

Co-Authored-By: brettlangdon <me@brett.is>

* Update tests/contrib/flask/test_template.py

Co-Authored-By: brettlangdon <me@brett.is>

* Update tests/contrib/flask/test_template.py

Co-Authored-By: brettlangdon <me@brett.is>

* [flask] simplify fetching wrapped arg

* [flask] fix spelling mistake

* Update ddtrace/contrib/flask/patch.py

Co-Authored-By: brettlangdon <me@brett.is>

* [flask] remove unnecessary 'func_name(func)' call

* Update tests/contrib/flask/test_blueprint.py

Co-Authored-By: brettlangdon <me@brett.is>

* [flask] fix remaining comments from kyle

* [flask] fix flake8 issues

* [flask] test distributed tracing

* [flask] add find_span_parent helper

* [flask] add hook test cases

* [flask] fix spelling

* [flask] rename Pin.find to Pin._find and add tests

* [flask] one last Pin.find -> Pin._find

* [flask] try to parse endpoint/url rule in Flask.preprocess_request as well

* [flask] fix line too long issue
@brettlangdon brettlangdon deleted the brettlangdon/flask-dev branch November 20, 2018 18:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants