prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  dd-trace-py messes with the root logger
  ```
  has anyone else run into the issue of ddtrace-py turning on all default loggers for everything when running `patch_all()`? Weirdly, I can only replicate it within Docker, but it's definitely the `patch_all()` command that's causing it
  
  [8:50 PM] 
  same thing happens if i run a single `patch()` on any library, it seems
  
  [8:52 PM] 
  thinking it might be caused by this line: https://github.com/DataDog/dd-trace-py/blob/a50b5f5422716fae1c54b589cd448dc295b32757/ddtrace/monkey.py#L77
  
  [8:53 PM] 
  any reason that's `logging.info(...)` on the `logging` module instead of getting a logger and calling `.info()` on that?
  ```
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `ddtrace/contrib/mysql/__init__.py`
  Content:
  ```
  1 """Instrumeent mysql to report MySQL queries.
  2 
  3 ``patch_all`` will automatically patch your mysql connection to make it work.
  4 ::
  5 
  6     from ddtrace import Pin, patch
  7     from mysql.connector import connect
  8 
  9     # If not patched yet, you can patch mysql specifically
  10     patch(mysql=True)
  11 
  12     # This will report a span with the default settings
  13     conn = connect(user="alice", password="b0b", host="localhost", port=3306, database="test")
  14     cursor = conn.cursor()
  15     cursor.execute("SELECT 6*7 AS the_answer;")
  16 
  17     # Use a pin to specify metadata related to this connection
  18     Pin.override(conn, service='mysql-users')
  19 
  20 This package works for mysql.connector version 2.1.x.
  21 Only the default full-Python integration works. The binary C connector,
  22 provided by _mysql_connector, is not supported yet.
  23 
  24 Help on mysql.connector can be found on:
  25 https://dev.mysql.com/doc/connector-python/en/
  26 """
  27 import logging
  28 
  29 from ..util import require_modules
  30 
  31 # check `MySQL-python` availability
  32 required_modules = ['_mysql']
  33 
  34 with require_modules(required_modules) as missing_modules:
  35     if not missing_modules:
  36         # MySQL-python package is not supported at the moment
  37         logging.debug('failed to patch mysql-python: integration not available')
  38 
  39 # check `mysql-connector` availability
  40 required_modules = ['mysql.connector']
  41 
  42 with require_modules(required_modules) as missing_modules:
  43     if not missing_modules:
  44         from .patch import patch
  45         from .tracers import get_traced_mysql_connection
  46 
  47         __all__ = ['get_traced_mysql_connection', 'patch']
  48
  ```
  
  Path: `ddtrace/monkey.py`
  Content:
  ```
  1 """Patch librairies to be automatically instrumented.
  2 
  3 It can monkey patch supported standard libraries and third party modules.
  4 A patched module will automatically report spans with its default configuration.
  5 
  6 A library instrumentation can be configured (for instance, to report as another service)
  7 using Pin. For that, check its documentation.
  8 """
  9 import logging
  10 import importlib
  11 import threading
  12 
  13 
  14 # Default set of modules to automatically patch or not
  15 PATCH_MODULES = {
  16     'boto': False,
  17     'botocore': False,
  18     'bottle': False,
  19     'cassandra': True,
  20     'celery': True,
  21     'elasticsearch': True,
  22     'mongoengine': True,
  23     'mysql': True,
  24     'psycopg': True,
  25     'pylibmc': True,
  26     'pymongo': True,
  27     'redis': True,
  28     'requests': False,  # Not ready yet
  29     'sqlalchemy': False,  # Prefer DB client instrumentation
  30     'sqlite3': True,
  31     'aiohttp': True,  # requires asyncio (Python 3.4+)
  32 
  33     # Ignore some web framework integrations that might be configured explicitly in code
  34     "django": False,
  35     "flask": False,
  36     "falcon": False,
  37     "pylons": False,
  38     "pyramid": False,
  39 }
  40 
  41 _LOCK = threading.Lock()
  42 _PATCHED_MODULES = set()
  43 
  44 
  45 class PatchException(Exception):
  46     """Wraps regular `Exception` class when patching modules"""
  47     pass
  48 
  49 
  50 def patch_all(**patch_modules):
  51     """Automatically patches all available modules.
  52 
  53     :param dict \**patch_modules: Override whether particular modules are patched or not.
  54 
  55         >>> patch_all({'redis': False, 'cassandra': False})
  56     """
  57     modules = PATCH_MODULES.copy()
  58     modules.update(patch_modules)
  59 
  60     patch(raise_errors=False, **modules)
  61 
  62 def patch(raise_errors=True, **patch_modules):
  63     """Patch only a set of given modules.
  64 
  65     :param bool raise_errors: Raise error if one patch fail.
  66     :param dict \**patch_modules: List of modules to patch.
  67 
  68         >>> patch({'psycopg': True, 'elasticsearch': True})
  69     """
  70     modules = [m for (m, should_patch) in patch_modules.items() if should_patch]
  71     count = 0
  72     for module in modules:
  73         patched = patch_module(module, raise_errors=raise_errors)
  74         if patched:
  75             count += 1
  76 
  77     logging.info("patched %s/%s modules (%s)",
  78         count,
  79         len(modules),
  80         ",".join(get_patched_modules()))
  81 
  82 
  83 def patch_module(module, raise_errors=True):
  84     """Patch a single module
  85 
  86     Returns if the module got properly patched.
  87     """
  88     try:
  89         return _patch_module(module)
  90     except Exception as exc:
  91         if raise_errors:
  92             raise
  93         logging.debug("failed to patch %s: %s", module, exc)
  94         return False
  95 
  96 def get_patched_modules():
  97     """Get the list of patched modules"""
  98     with _LOCK:
  99         return sorted(_PATCHED_MODULES)
  100 
  101 def _patch_module(module):
  102     """_patch_module will attempt to monkey patch the module.
  103 
  104     Returns if the module got patched.
  105     Can also raise errors if it fails.
  106     """
  107     path = 'ddtrace.contrib.%s' % module
  108     with _LOCK:
  109         if module in _PATCHED_MODULES:
  110             logging.debug("already patched: %s", path)
  111             return False
  112 
  113         try:
  114             imported_module = importlib.import_module(path)
  115             imported_module.patch()
  116         except ImportError:
  117             # if the import fails, the integration is not available
  118             raise PatchException('integration not available')
  119         except AttributeError:
  120             # if patch() is not available in the module, it means
  121             # that the library is not installed in the environment
  122             raise PatchException('module not installed')
  123 
  124         _PATCHED_MODULES.add(module)
  125         return True
  126
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/ddtrace/contrib/mysql/__init__.py b/ddtrace/contrib/mysql/__init__.py
  --- a/ddtrace/contrib/mysql/__init__.py
  +++ b/ddtrace/contrib/mysql/__init__.py
  @@ -28,13 +28,16 @@
   
   from ..util import require_modules
   
  +
  +log = logging.getLogger(__name__)
  +
   # check `MySQL-python` availability
   required_modules = ['_mysql']
   
   with require_modules(required_modules) as missing_modules:
       if not missing_modules:
           # MySQL-python package is not supported at the moment
  -        logging.debug('failed to patch mysql-python: integration not available')
  +        log.debug('failed to patch mysql-python: integration not available')
   
   # check `mysql-connector` availability
   required_modules = ['mysql.connector']
  diff --git a/ddtrace/monkey.py b/ddtrace/monkey.py
  --- a/ddtrace/monkey.py
  +++ b/ddtrace/monkey.py
  @@ -11,6 +11,8 @@
   import threading
   
   
  +log = logging.getLogger(__name__)
  +
   # Default set of modules to automatically patch or not
   PATCH_MODULES = {
       'boto': False,
  @@ -74,7 +76,7 @@
           if patched:
               count += 1
   
  -    logging.info("patched %s/%s modules (%s)",
  +    log.info("patched %s/%s modules (%s)",
           count,
           len(modules),
           ",".join(get_patched_modules()))
  @@ -90,7 +92,7 @@
       except Exception as exc:
           if raise_errors:
               raise
  -        logging.debug("failed to patch %s: %s", module, exc)
  +        log.debug("failed to patch %s: %s", module, exc)
           return False
   
   def get_patched_modules():
  @@ -107,7 +109,7 @@
       path = 'ddtrace.contrib.%s' % module
       with _LOCK:
           if module in _PATCHED_MODULES:
  -            logging.debug("already patched: %s", path)
  +            log.debug("already patched: %s", path)
               return False
   
           try:
  
verification_info: {"golden_diff": "diff --git a/ddtrace/contrib/mysql/__init__.py b/ddtrace/contrib/mysql/__init__.py\n--- a/ddtrace/contrib/mysql/__init__.py\n+++ b/ddtrace/contrib/mysql/__init__.py\n@@ -28,13 +28,16 @@\n \n from ..util import require_modules\n \n+\n+log = logging.getLogger(__name__)\n+\n # check `MySQL-python` availability\n required_modules = ['_mysql']\n \n with require_modules(required_modules) as missing_modules:\n     if not missing_modules:\n         # MySQL-python package is not supported at the moment\n-        logging.debug('failed to patch mysql-python: integration not available')\n+        log.debug('failed to patch mysql-python: integration not available')\n \n # check `mysql-connector` availability\n required_modules = ['mysql.connector']\ndiff --git a/ddtrace/monkey.py b/ddtrace/monkey.py\n--- a/ddtrace/monkey.py\n+++ b/ddtrace/monkey.py\n@@ -11,6 +11,8 @@\n import threading\n \n \n+log = logging.getLogger(__name__)\n+\n # Default set of modules to automatically patch or not\n PATCH_MODULES = {\n     'boto': False,\n@@ -74,7 +76,7 @@\n         if patched:\n             count += 1\n \n-    logging.info(\"patched %s/%s modules (%s)\",\n+    log.info(\"patched %s/%s modules (%s)\",\n         count,\n         len(modules),\n         \",\".join(get_patched_modules()))\n@@ -90,7 +92,7 @@\n     except Exception as exc:\n         if raise_errors:\n             raise\n-        logging.debug(\"failed to patch %s: %s\", module, exc)\n+        log.debug(\"failed to patch %s: %s\", module, exc)\n         return False\n \n def get_patched_modules():\n@@ -107,7 +109,7 @@\n     path = 'ddtrace.contrib.%s' % module\n     with _LOCK:\n         if module in _PATCHED_MODULES:\n-            logging.debug(\"already patched: %s\", path)\n+            log.debug(\"already patched: %s\", path)\n             return False\n \n         try:\n", "issue": "dd-trace-py messes with the root logger\n```\r\nhas anyone else run into the issue of ddtrace-py turning on all default loggers for everything when running `patch_all()`? Weirdly, I can only replicate it within Docker, but it's definitely the `patch_all()` command that's causing it\r\n\r\n[8:50 PM] \r\nsame thing happens if i run a single `patch()` on any library, it seems\r\n\r\n[8:52 PM] \r\nthinking it might be caused by this line: https://github.com/DataDog/dd-trace-py/blob/a50b5f5422716fae1c54b589cd448dc295b32757/ddtrace/monkey.py#L77\r\n\r\n[8:53 PM] \r\nany reason that's `logging.info(...)` on the `logging` module instead of getting a logger and calling `.info()` on that?\r\n```\n", "before_files": [{"content": "\"\"\"Instrumeent mysql to report MySQL queries.\n\n``patch_all`` will automatically patch your mysql connection to make it work.\n::\n\n    from ddtrace import Pin, patch\n    from mysql.connector import connect\n\n    # If not patched yet, you can patch mysql specifically\n    patch(mysql=True)\n\n    # This will report a span with the default settings\n    conn = connect(user=\"alice\", password=\"b0b\", host=\"localhost\", port=3306, database=\"test\")\n    cursor = conn.cursor()\n    cursor.execute(\"SELECT 6*7 AS the_answer;\")\n\n    # Use a pin to specify metadata related to this connection\n    Pin.override(conn, service='mysql-users')\n\nThis package works for mysql.connector version 2.1.x.\nOnly the default full-Python integration works. The binary C connector,\nprovided by _mysql_connector, is not supported yet.\n\nHelp on mysql.connector can be found on:\nhttps://dev.mysql.com/doc/connector-python/en/\n\"\"\"\nimport logging\n\nfrom ..util import require_modules\n\n# check `MySQL-python` availability\nrequired_modules = ['_mysql']\n\nwith require_modules(required_modules) as missing_modules:\n    if not missing_modules:\n        # MySQL-python package is not supported at the moment\n        logging.debug('failed to patch mysql-python: integration not available')\n\n# check `mysql-connector` availability\nrequired_modules = ['mysql.connector']\n\nwith require_modules(required_modules) as missing_modules:\n    if not missing_modules:\n        from .patch import patch\n        from .tracers import get_traced_mysql_connection\n\n        __all__ = ['get_traced_mysql_connection', 'patch']\n", "path": "ddtrace/contrib/mysql/__init__.py"}, {"content": "\"\"\"Patch librairies to be automatically instrumented.\n\nIt can monkey patch supported standard libraries and third party modules.\nA patched module will automatically report spans with its default configuration.\n\nA library instrumentation can be configured (for instance, to report as another service)\nusing Pin. For that, check its documentation.\n\"\"\"\nimport logging\nimport importlib\nimport threading\n\n\n# Default set of modules to automatically patch or not\nPATCH_MODULES = {\n    'boto': False,\n    'botocore': False,\n    'bottle': False,\n    'cassandra': True,\n    'celery': True,\n    'elasticsearch': True,\n    'mongoengine': True,\n    'mysql': True,\n    'psycopg': True,\n    'pylibmc': True,\n    'pymongo': True,\n    'redis': True,\n    'requests': False,  # Not ready yet\n    'sqlalchemy': False,  # Prefer DB client instrumentation\n    'sqlite3': True,\n    'aiohttp': True,  # requires asyncio (Python 3.4+)\n\n    # Ignore some web framework integrations that might be configured explicitly in code\n    \"django\": False,\n    \"flask\": False,\n    \"falcon\": False,\n    \"pylons\": False,\n    \"pyramid\": False,\n}\n\n_LOCK = threading.Lock()\n_PATCHED_MODULES = set()\n\n\nclass PatchException(Exception):\n    \"\"\"Wraps regular `Exception` class when patching modules\"\"\"\n    pass\n\n\ndef patch_all(**patch_modules):\n    \"\"\"Automatically patches all available modules.\n\n    :param dict \\**patch_modules: Override whether particular modules are patched or not.\n\n        >>> patch_all({'redis': False, 'cassandra': False})\n    \"\"\"\n    modules = PATCH_MODULES.copy()\n    modules.update(patch_modules)\n\n    patch(raise_errors=False, **modules)\n\ndef patch(raise_errors=True, **patch_modules):\n    \"\"\"Patch only a set of given modules.\n\n    :param bool raise_errors: Raise error if one patch fail.\n    :param dict \\**patch_modules: List of modules to patch.\n\n        >>> patch({'psycopg': True, 'elasticsearch': True})\n    \"\"\"\n    modules = [m for (m, should_patch) in patch_modules.items() if should_patch]\n    count = 0\n    for module in modules:\n        patched = patch_module(module, raise_errors=raise_errors)\n        if patched:\n            count += 1\n\n    logging.info(\"patched %s/%s modules (%s)\",\n        count,\n        len(modules),\n        \",\".join(get_patched_modules()))\n\n\ndef patch_module(module, raise_errors=True):\n    \"\"\"Patch a single module\n\n    Returns if the module got properly patched.\n    \"\"\"\n    try:\n        return _patch_module(module)\n    except Exception as exc:\n        if raise_errors:\n            raise\n        logging.debug(\"failed to patch %s: %s\", module, exc)\n        return False\n\ndef get_patched_modules():\n    \"\"\"Get the list of patched modules\"\"\"\n    with _LOCK:\n        return sorted(_PATCHED_MODULES)\n\ndef _patch_module(module):\n    \"\"\"_patch_module will attempt to monkey patch the module.\n\n    Returns if the module got patched.\n    Can also raise errors if it fails.\n    \"\"\"\n    path = 'ddtrace.contrib.%s' % module\n    with _LOCK:\n        if module in _PATCHED_MODULES:\n            logging.debug(\"already patched: %s\", path)\n            return False\n\n        try:\n            imported_module = importlib.import_module(path)\n            imported_module.patch()\n        except ImportError:\n            # if the import fails, the integration is not available\n            raise PatchException('integration not available')\n        except AttributeError:\n            # if patch() is not available in the module, it means\n            # that the library is not installed in the environment\n            raise PatchException('module not installed')\n\n        _PATCHED_MODULES.add(module)\n        return True\n", "path": "ddtrace/monkey.py"}], "after_files": [{"content": "\"\"\"Instrumeent mysql to report MySQL queries.\n\n``patch_all`` will automatically patch your mysql connection to make it work.\n::\n\n    from ddtrace import Pin, patch\n    from mysql.connector import connect\n\n    # If not patched yet, you can patch mysql specifically\n    patch(mysql=True)\n\n    # This will report a span with the default settings\n    conn = connect(user=\"alice\", password=\"b0b\", host=\"localhost\", port=3306, database=\"test\")\n    cursor = conn.cursor()\n    cursor.execute(\"SELECT 6*7 AS the_answer;\")\n\n    # Use a pin to specify metadata related to this connection\n    Pin.override(conn, service='mysql-users')\n\nThis package works for mysql.connector version 2.1.x.\nOnly the default full-Python integration works. The binary C connector,\nprovided by _mysql_connector, is not supported yet.\n\nHelp on mysql.connector can be found on:\nhttps://dev.mysql.com/doc/connector-python/en/\n\"\"\"\nimport logging\n\nfrom ..util import require_modules\n\n\nlog = logging.getLogger(__name__)\n\n# check `MySQL-python` availability\nrequired_modules = ['_mysql']\n\nwith require_modules(required_modules) as missing_modules:\n    if not missing_modules:\n        # MySQL-python package is not supported at the moment\n        log.debug('failed to patch mysql-python: integration not available')\n\n# check `mysql-connector` availability\nrequired_modules = ['mysql.connector']\n\nwith require_modules(required_modules) as missing_modules:\n    if not missing_modules:\n        from .patch import patch\n        from .tracers import get_traced_mysql_connection\n\n        __all__ = ['get_traced_mysql_connection', 'patch']\n", "path": "ddtrace/contrib/mysql/__init__.py"}, {"content": "\"\"\"Patch librairies to be automatically instrumented.\n\nIt can monkey patch supported standard libraries and third party modules.\nA patched module will automatically report spans with its default configuration.\n\nA library instrumentation can be configured (for instance, to report as another service)\nusing Pin. For that, check its documentation.\n\"\"\"\nimport logging\nimport importlib\nimport threading\n\n\nlog = logging.getLogger(__name__)\n\n# Default set of modules to automatically patch or not\nPATCH_MODULES = {\n    'boto': False,\n    'botocore': False,\n    'bottle': False,\n    'cassandra': True,\n    'celery': True,\n    'elasticsearch': True,\n    'mongoengine': True,\n    'mysql': True,\n    'psycopg': True,\n    'pylibmc': True,\n    'pymongo': True,\n    'redis': True,\n    'requests': False,  # Not ready yet\n    'sqlalchemy': False,  # Prefer DB client instrumentation\n    'sqlite3': True,\n    'aiohttp': True,  # requires asyncio (Python 3.4+)\n\n    # Ignore some web framework integrations that might be configured explicitly in code\n    \"django\": False,\n    \"flask\": False,\n    \"falcon\": False,\n    \"pylons\": False,\n    \"pyramid\": False,\n}\n\n_LOCK = threading.Lock()\n_PATCHED_MODULES = set()\n\n\nclass PatchException(Exception):\n    \"\"\"Wraps regular `Exception` class when patching modules\"\"\"\n    pass\n\n\ndef patch_all(**patch_modules):\n    \"\"\"Automatically patches all available modules.\n\n    :param dict \\**patch_modules: Override whether particular modules are patched or not.\n\n        >>> patch_all({'redis': False, 'cassandra': False})\n    \"\"\"\n    modules = PATCH_MODULES.copy()\n    modules.update(patch_modules)\n\n    patch(raise_errors=False, **modules)\n\ndef patch(raise_errors=True, **patch_modules):\n    \"\"\"Patch only a set of given modules.\n\n    :param bool raise_errors: Raise error if one patch fail.\n    :param dict \\**patch_modules: List of modules to patch.\n\n        >>> patch({'psycopg': True, 'elasticsearch': True})\n    \"\"\"\n    modules = [m for (m, should_patch) in patch_modules.items() if should_patch]\n    count = 0\n    for module in modules:\n        patched = patch_module(module, raise_errors=raise_errors)\n        if patched:\n            count += 1\n\n    log.info(\"patched %s/%s modules (%s)\",\n        count,\n        len(modules),\n        \",\".join(get_patched_modules()))\n\n\ndef patch_module(module, raise_errors=True):\n    \"\"\"Patch a single module\n\n    Returns if the module got properly patched.\n    \"\"\"\n    try:\n        return _patch_module(module)\n    except Exception as exc:\n        if raise_errors:\n            raise\n        log.debug(\"failed to patch %s: %s\", module, exc)\n        return False\n\ndef get_patched_modules():\n    \"\"\"Get the list of patched modules\"\"\"\n    with _LOCK:\n        return sorted(_PATCHED_MODULES)\n\ndef _patch_module(module):\n    \"\"\"_patch_module will attempt to monkey patch the module.\n\n    Returns if the module got patched.\n    Can also raise errors if it fails.\n    \"\"\"\n    path = 'ddtrace.contrib.%s' % module\n    with _LOCK:\n        if module in _PATCHED_MODULES:\n            log.debug(\"already patched: %s\", path)\n            return False\n\n        try:\n            imported_module = importlib.import_module(path)\n            imported_module.patch()\n        except ImportError:\n            # if the import fails, the integration is not available\n            raise PatchException('integration not available')\n        except AttributeError:\n            # if patch() is not available in the module, it means\n            # that the library is not installed in the environment\n            raise PatchException('module not installed')\n\n        _PATCHED_MODULES.add(module)\n        return True\n", "path": "ddtrace/monkey.py"}]}