示例#1
0
def patch():
    """
    Tracing function that patches the Tornado web application so that it will be
    traced using the given ``tracer``.
    """
    # patch only once
    if getattr(tornado, '__opentelemetry_patch', False):
        return
    setattr(tornado, '__opentelemetry_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
    oteltrace.tracer.configure(
        context_provider=context_provider,
        wrap_executor=decorators.wrap_executor,
    )
示例#2
0
def patch():
    """Enables Context Propagation between threads"""
    if getattr(futures, '__opentelemetry_patch', False):
        return
    setattr(futures, '__opentelemetry_patch', True)

    _w('concurrent.futures', 'ThreadPoolExecutor.submit', _wrap_submit)
示例#3
0
def _patch(elasticsearch):
    if getattr(elasticsearch, '_opentelemetry_patch', False):
        return
    setattr(elasticsearch, '_opentelemetry_patch', True)
    _w(elasticsearch.transport, 'Transport.perform_request',
       _get_perform_request(elasticsearch))
    Pin(service=metadata.SERVICE, app=metadata.APP,
        app_type=AppTypes.db).onto(elasticsearch.transport.Transport)
def _patch_server():
    if getattr(constants.GRPC_PIN_MODULE_SERVER, '__opentelemetry_patch',
               False):
        return
    setattr(constants.GRPC_PIN_MODULE_SERVER, '__opentelemetry_patch', True)

    Pin(service=config.grpc_server.service_name).onto(
        constants.GRPC_PIN_MODULE_SERVER)

    _w('grpc', 'server', _server_constructor_interceptor)
def patch():
    if getattr(consul, '__opentelemetry_patch', False):
        return
    setattr(consul, '__opentelemetry_patch', True)

    pin = Pin(service=consulx.SERVICE,
              app=consulx.APP,
              app_type=consulx.APP_TYPE)
    pin.onto(consul.Consul.KV)

    for f_name in _KV_FUNCS:
        _w('consul', 'Consul.KV.%s' % f_name, wrap_function(f_name))
示例#6
0
def patch():
    """Patches current loop `create_task()` method to enable spawned tasks to
    parent to the base task context.
    """
    if getattr(asyncio, '_opentelemetry_patch', False):
        return
    setattr(asyncio, '_opentelemetry_patch', True)

    loop = asyncio.get_event_loop()
    if CONTEXTVARS_IS_AVAILABLE:
        _w(loop, 'create_task', wrapped_create_task_contextvars)
    else:
        _w(loop, 'create_task', wrapped_create_task)
def trace_rendering():
    """Patch all Pylons renderers. It supports multiple versions
    of Pylons and multiple renderers.
    """
    # patch only once
    if getattr(pylons.templating, '__opentelemetry_patch', False):
        return
    setattr(pylons.templating, '__opentelemetry_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 the instrumented methods
    """
    if getattr(molten, '_opentelemetry_patch', False):
        return
    setattr(molten, '_opentelemetry_patch', True)

    pin = Pin(
        service=config.molten['service_name'],
        app=config.molten['app'],
        app_type=config.molten['app_type'],
    )

    # add pin to module since many classes use __slots__
    pin.onto(molten)

    _w(molten.BaseApp, '__init__', patch_app_init)
    _w(molten.App, '__call__', patch_app_call)
示例#9
0
def patch():
    if getattr(jinja2, '__opentelemetry_patch', False):
        # already patched
        return
    setattr(jinja2, '__opentelemetry_patch', True)
    Pin(
        service=config.jinja2['service_name'],
        _config=config.jinja2,
    ).onto(jinja2.environment.Environment)
    _w(jinja2, 'environment.Template.render', _wrap_render)
    _w(jinja2, 'environment.Template.generate', _wrap_render)
    _w(jinja2, 'environment.Environment.compile', _wrap_compile)
    _w(jinja2, 'environment.Environment._load_template', _wrap_load_template)
def patch():
    """Activate http calls tracing"""
    if getattr(requests, '__opentelemetry_patch', False):
        return
    setattr(requests, '__opentelemetry_patch', True)

    _w('requests', 'Session.send', _wrap_send)
    Pin(
        service=config.requests['service_name'],
        app='requests',
        app_type=AppTypes.web,
        _config=config.requests,
    ).onto(requests.Session)

    # [Backward compatibility]: `session.distributed_tracing` should point and
    # update the `Pin` configuration instead. This block adds a property so that
    # old implementations work as expected
    fn = property(_distributed_tracing)
    fn = fn.setter(_distributed_tracing_setter)
    requests.Session.distributed_tracing = fn
def patch():
    if algoliasearch_version == (0, 0):
        return

    if getattr(algoliasearch, OTEL_PATCH_ATTR, False):
        return

    setattr(algoliasearch, '_opentelemetry_patch', True)

    pin = Pin(
        service=config.algoliasearch.service_name, app=APP_NAME,
        app_type=AppTypes.db
    )

    if algoliasearch_version < (2, 0) and algoliasearch_version >= (1, 0):
        _w(algoliasearch.index, 'Index.search', _patched_search)
        pin.onto(algoliasearch.index.Index)
    elif algoliasearch_version >= (2, 0) and algoliasearch_version < (3, 0):
        from algoliasearch import search_index
        _w(algoliasearch, 'search_index.SearchIndex.search', _patched_search)
        pin.onto(search_index.SearchIndex)
    else:
        return
def _patch_client():
    if getattr(constants.GRPC_PIN_MODULE_CLIENT, '__opentelemetry_patch',
               False):
        return
    setattr(constants.GRPC_PIN_MODULE_CLIENT, '__opentelemetry_patch', True)

    Pin(service=config.grpc.service_name).onto(
        constants.GRPC_PIN_MODULE_CLIENT)

    _w('grpc', 'insecure_channel', _client_channel_interceptor)
    _w('grpc', 'secure_channel', _client_channel_interceptor)
    _w('grpc', 'intercept_channel', intercept_channel)
示例#13
0
def patch():
    # patch only once
    if getattr(MySQLdb, '__opentelemetry_patch', False):
        return
    setattr(MySQLdb, '__opentelemetry_patch', True)

    # `Connection` and `connect` are aliases for
    # `Connect`; patch them too
    _w('MySQLdb', 'Connect', _connect)
    if hasattr(MySQLdb, 'Connection'):
        _w('MySQLdb', 'Connection', _connect)
    if hasattr(MySQLdb, 'connect'):
        _w('MySQLdb', 'connect', _connect)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import requests

from oteltrace.vendor.wrapt import wrap_function_wrapper as _w

from .connection import _wrap_send


class TracedSession(requests.Session):
    """TracedSession is a requests' Session that is already traced.
    You can use it if you want a finer grained control for your
    HTTP clients.
    """
    pass


# always patch our `TracedSession` when imported
_w(TracedSession, 'send', _wrap_send)
示例#15
0
def patch():
    """
    Patch `flask` module for tracing
    """
    # Check to see if we have patched Flask yet or not
    if getattr(flask, '_opentelemetry_patch', False):
        return
    setattr(flask, '_opentelemetry_patch', True)

    # Attach service pin to `flask.app.Flask`
    Pin(
        service=config.flask['service_name'],
        app=config.flask['app'],
        app_type=config.flask['app_type'],
    ).onto(flask.Flask)

    # flask.app.Flask methods that have custom tracing (add metadata, wrap functions, etc)
    _w('flask', 'Flask.wsgi_app', traced_wsgi_app)
    _w('flask', 'Flask.dispatch_request', request_tracer('dispatch_request'))
    _w('flask', 'Flask.preprocess_request',
       request_tracer('preprocess_request'))
    _w('flask', 'Flask.add_url_rule', traced_add_url_rule)
    _w('flask', 'Flask.endpoint', traced_endpoint)
    _w('flask', 'Flask._register_error_handler', traced_register_error_handler)

    # 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
    _w('flask', 'send_file', simple_tracer('flask.send_file'))

    # flask.json.jsonify
    _w('flask', 'jsonify', traced_jsonify)

    # flask.templating traced functions
    _w('flask.templating', '_render', traced_render)
    _w('flask', 'render_template', traced_render_template)
    _w('flask', 'render_template_string', traced_render_template_string)

    # flask.blueprints.Blueprint traced hook decorators
    bp_hooks = [
        'after_app_request',
        'after_request',
        'before_app_first_request',
        'before_app_request',
        'before_request',
        'teardown_request',
        'teardown_app_request',
    ]
    for hook in bp_hooks:
        _w('flask', 'Blueprint.{}'.format(hook), traced_flask_hook)

    # flask.signals signals
    if config.flask['trace_signals']:
        signals = [
            'template_rendered',
            'request_started',
            'request_finished',
            'request_tearing_down',
            'got_request_exception',
            'appcontext_tearing_down',
        ]
        # These were added in 0.11.0
        if flask_version >= (0, 11):
            signals.append('before_render_template')

        # These were added in 0.10.0
        if flask_version >= (0, 10):
            signals.append('appcontext_pushed')
            signals.append('appcontext_popped')
            signals.append('message_flashed')

        for signal in signals:
            module = 'flask'

            # v0.9 missed importing `appcontext_tearing_down` in `flask/__init__.py`
            #  https://github.com/pallets/flask/blob/0.9/flask/__init__.py#L35-L37
            #  https://github.com/pallets/flask/blob/0.9/flask/signals.py#L52
            # DEV: Version 0.9 doesn't have a patch version
            if flask_version <= (0, 9) and signal == 'appcontext_tearing_down':
                module = 'flask.signals'

            # DEV: Patch `receivers_for` instead of `connect` to ensure we don't mess with `disconnect`
            _w(module, '{}.receivers_for'.format(signal),
               traced_signal_receivers_for(signal))