Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def trace_rendering():
"""Patch all Pylons renderers. It supports multiple versions
of Pylons and multiple renderers.
"""
# patch only once
if getattr(pylons.templating, '__datadog_patch', False):
return
setattr(pylons.templating, '__datadog_patch', True)
if legacy_pylons:
# Pylons <= 0.9.7
_w('pylons.templating', 'render', _traced_renderer)
else:
# Pylons > 0.9.7
_w('pylons.templating', 'render_mako', _traced_renderer)
_w('pylons.templating', 'render_mako_def', _traced_renderer)
_w('pylons.templating', 'render_genshi', _traced_renderer)
_w('pylons.templating', 'render_jinja2', _traced_renderer)
def patch():
""" Patch monkey patches psycopg's connection function
so that the connection's functions are traced.
"""
if getattr(psycopg2, '_datadog_patch', False):
return
setattr(psycopg2, '_datadog_patch', True)
wrapt.wrap_function_wrapper(psycopg2, 'connect', patched_connect)
_patch_extensions(_psycopg2_extensions) # do this early just in case
"""
# patch only once
if getattr(tornado, '__datadog_patch', False):
return
setattr(tornado, '__datadog_patch', True)
# patch Application to initialize properly our settings and tracer
_w('tornado.web', 'Application.__init__', application.tracer_config)
# patch RequestHandler to trace all Tornado handlers
_w('tornado.web', 'RequestHandler._execute', handlers.execute)
_w('tornado.web', 'RequestHandler.on_finish', handlers.on_finish)
_w('tornado.web', 'RequestHandler.log_exception', handlers.log_exception)
# patch Template system
_w('tornado.template', 'Template.generate', template.generate)
# patch Python Futures if available when an Executor pool is used
compat.wrap_futures()
# configure the global tracer
ddtrace.tracer.configure(
context_provider=context_provider,
wrap_executor=decorators.wrap_executor,
)
def patch():
if getattr(mako, '__datadog_patch', False):
# already patched
return
setattr(mako, '__datadog_patch', True)
Pin(service='mako', app='mako').onto(Template)
_w(mako, 'template.Template.render', _wrap_render)
_w(mako, 'template.Template.render_unicode', _wrap_render)
_w(mako, 'template.Template.render_context', _wrap_render)
def patch():
"""Enables Context Propagation between threads"""
if getattr(futures, '__datadog_patch', False):
return
setattr(futures, '__datadog_patch', True)
_w('concurrent.futures', 'ThreadPoolExecutor.submit', _wrap_submit)
# flask.blueprints.Blueprint methods that have custom tracing (add metadata, wrap functions, etc)
_w('flask', 'Blueprint.register', traced_blueprint_register)
_w('flask', 'Blueprint.add_url_rule', traced_blueprint_add_url_rule)
# flask.app.Flask traced hook decorators
flask_hooks = [
'before_request',
'before_first_request',
'after_request',
'teardown_request',
'teardown_appcontext',
]
for hook in flask_hooks:
_w('flask', 'Flask.{}'.format(hook), traced_flask_hook)
_w('flask', 'after_this_request', traced_flask_hook)
# flask.app.Flask traced methods
flask_app_traces = [
'process_response',
'handle_exception',
'handle_http_exception',
'handle_user_exception',
'try_trigger_before_first_request_functions',
'do_teardown_request',
'do_teardown_appcontext',
'send_static_file',
]
for name in flask_app_traces:
_w('flask', 'Flask.{}'.format(name), simple_tracer('flask.{}'.format(name)))
# flask static file helpers
# 3.6: https://github.com/python/cpython/blob/3.6/Lib/importlib/_bootstrap.py#L936-L960
# 3.7: https://github.com/python/cpython/blob/3.7/Lib/importlib/_bootstrap.py#L948-L972
# 3.8: https://github.com/python/cpython/blob/3.8/Lib/importlib/_bootstrap.py#L956-L980
# DEV: Python 3 has multiple entrypoints for importing a module, but `_find_and_load_unlocked`
# is a common base/required function needed by anyone to import a module.
# e.g. `__import__` which calls `importlib._bootstrap._find_and_load()`
# `importlib.__import__/importlib._bootstrap.__import__` which calls `importlib._bootstrap._gcd_import()`
# `importlib.import_module` which calls `importliob._bootstrap._gcd_import()`
wrapt.wrap_function_wrapper('importlib._bootstrap', '_find_and_load_unlocked', wrapped_find_and_load_unlocked)
# 3.4: https://github.com/python/cpython/blob/3.4/Lib/importlib/__init__.py#L115-L156
# 3.5: https://github.com/python/cpython/blob/3.5/Lib/importlib/__init__.py#L132-L173
# 3.6: https://github.com/python/cpython/blob/3.6/Lib/importlib/__init__.py#L132-L173
# 3.7: https://github.com/python/cpython/blob/3.7/Lib/importlib/__init__.py#L133-L176
# 3.8: https://github.com/python/cpython/blob/3.8/Lib/importlib/__init__.py#L133-L176
wrapt.wrap_function_wrapper('importlib', 'reload', wrapped_reload)
# 2.7
# DEV: Slightly more direct approach of patching `__import__` and `reload` functions
elif sys.version_info >= (2, 7):
# https://github.com/python/cpython/blob/2.7/Python/bltinmodule.c#L35-L68
__builtins__['__import__'] = wrapt.FunctionWrapper(__builtins__['__import__'], wrapped_import)
# https://github.com/python/cpython/blob/2.7/Python/bltinmodule.c#L2147-L2160
__builtins__['reload'] = wrapt.FunctionWrapper(__builtins__['reload'], wrapped_reload)
# Update after we have successfully patched
_patched = True
def patch():
"""
Patch aiohttp third party modules:
* aiohttp_jinja2
"""
if template_module:
if getattr(aiohttp_jinja2, '__datadog_patch', False):
return
setattr(aiohttp_jinja2, '__datadog_patch', True)
_w = wrapt.wrap_function_wrapper
_w('aiohttp_jinja2', 'render_template', _trace_render_template)
Pin(app='aiohttp', service=None).onto(aiohttp_jinja2)
def patch():
"""Patch the instrumented methods
This duplicated doesn't look nice. The nicer alternative is to use an ObjectProxy on top
of Kombu. However, it means that any "import kombu.Connection" won't be instrumented.
"""
if getattr(kombu, '_datadog_patch', False):
return
setattr(kombu, '_datadog_patch', True)
_w = wrapt.wrap_function_wrapper
# We wrap the _publish method because the publish method:
# * defines defaults in its kwargs
# * potentially overrides kwargs with values from self
# * extracts/normalizes things like exchange
_w(kombux.TYPE, 'Producer._publish', traced_publish)
_w(kombux.TYPE, 'Consumer.receive', traced_receive)
Pin(
service=config.kombu['service_name'],
app='kombu'
).onto(kombu.messaging.Producer)
Pin(
service=config.kombu['service_name'],
app='kombu'
).onto(kombu.messaging.Consumer)
of Pylons and multiple renderers.
"""
# patch only once
if getattr(pylons.templating, '__datadog_patch', False):
return
setattr(pylons.templating, '__datadog_patch', True)
if legacy_pylons:
# Pylons <= 0.9.7
_w('pylons.templating', 'render', _traced_renderer)
else:
# Pylons > 0.9.7
_w('pylons.templating', 'render_mako', _traced_renderer)
_w('pylons.templating', 'render_mako_def', _traced_renderer)
_w('pylons.templating', 'render_genshi', _traced_renderer)
_w('pylons.templating', 'render_jinja2', _traced_renderer)