def test_patch_before_import(self): from oteltrace import patch patch(celery=True) import celery app = celery.Celery() assert Pin.get_from(app) is not None
def test_patch_after_import(self): import celery from oteltrace import patch patch(celery=True) app = celery.Celery() assert Pin.get_from(app) is not None
def test_futures_double_instrumentation(self): # it should not double wrap `ThreadpPoolExecutor.submit` method if # `futures` is already instrumented from oteltrace import patch patch(futures=True) from concurrent.futures import ThreadPoolExecutor from oteltrace.vendor.wrapt import BoundFunctionWrapper fn_wrapper = getattr(ThreadPoolExecutor.submit, '__wrapped__', None) assert not isinstance(fn_wrapper, BoundFunctionWrapper)
def test_patch(self): """ Patching `requests` before `gevent` monkeypatching This is a regression test for https://github.com/opentelemetry/otel-trace-py/issues/506 When using `oteltrace-run` along with `requests` and `gevent` our patching causes `requests` and `urllib3` to get loaded before `gevent` has a chance to monkey patch. This causes `gevent` to show a warning and under certain versions cause a maxiumum recursion exception to be raised. """ # Assert none of our modules have been imported yet # DEV: This regression test depends on being able to control import order of these modules # DEV: This is not entirely necessary but is a nice safe guard self.assertNotIn('oteltrace', sys.modules) self.assertNotIn('gevent', sys.modules) self.assertNotIn('requests', sys.modules) self.assertNotIn('urllib3', sys.modules) try: # Import oteltrace and patch only `requests` # DEV: We do not need to patch `gevent` for the exception to occur from oteltrace import patch patch(requests=True) # Import gevent and monkeypatch from gevent import monkey monkey.patch_all() # This is typically what will fail if `requests` (or `urllib3`) # gets loaded before running `monkey.patch_all()` # DEV: We are testing that no exception gets raised import requests # DEV: We **MUST** use an HTTPS request, that is what causes the issue requests.get('https://httpbin.org/get') finally: # Ensure we always unpatch `requests` when we are done from oteltrace.contrib.requests import unpatch unpatch()
from oteltrace import api_otel_exporter from oteltrace.utils.formats import asbool, get_env from oteltrace.internal.logger import get_logger from oteltrace import constants logs_injection = asbool(get_env('logs', 'injection')) OTEL_LOG_FORMAT = '%(asctime)s %(levelname)s [%(name)s] [%(filename)s:%(lineno)d] {}- %(message)s'.format( '[otel.trace_id=%(otel.trace_id)s otel.span_id=%(otel.span_id)s] ' if logs_injection else '' ) if logs_injection: # immediately patch logging if trace id injected from oteltrace import patch patch(logging=True) debug = os.environ.get('OPENTELEMETRY_TRACE_DEBUG') # Set here a default logging format for basicConfig # DEV: Once basicConfig is called here, future calls to it cannot be used to # change the formatter since it applies the formatter to the root handler only # upon initializing it the first time. # See https://github.com/python/cpython/blob/112e4afd582515fcdcc0cde5012a4866e5cfda12/Lib/logging/__init__.py#L1550 if debug and debug.lower() == 'true': logging.basicConfig(level=logging.DEBUG, format=OTEL_LOG_FORMAT) else: logging.basicConfig(format=OTEL_LOG_FORMAT) log = get_logger(__name__)