prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  aioredis instrumentation: AttributeError: 'str' object has no attribute 'decode'
  **Describe the bug**
  In some cases `aioredis` passes `str` commands to its `aioredis.Redis.execute()` method rather than `bytes` commands, like e.g. when executing `aioredis.Redis.ping()`, which is unacceptable by `elastic-apm`.  
  
  **Current workaround**
  Disable `aioredis` instrumenting (set environment variable `SKIP_INSTRUMENT_AIOREDIS="true"`) prior `elasticapm.instrument()` is called.
  
  **To Reproduce**
  ```python3
  import asyncio
  
  import aioredis
  import elasticapm
  
  REDIS_URL = "redis://localhost:6379"
  
  
  async def main():
      elasticapm.instrument()
  
      client = await aioredis.create_redis_pool(REDIS_URL)
      elastic_apm_client = elasticapm.Client()
  
      elastic_apm_client.begin_transaction("redis-ping")
      try:
          assert await client.ping() == b"PONG"
      finally:
          client.close()
          await client.wait_closed()
          elastic_apm_client.end_transaction("redis-ping")
  
  if __name__ == "__main__":
      asyncio.run(main())
  ```
  
  **Expected result**
  No exception is raised.
  
  **Actual result**
  ```python3
  Traceback (most recent call last):
    File "<...>/test.py", line 24, in <module>
      asyncio.run(main())
    File "/usr/local/lib/python3.8/asyncio/runners.py", line 44, in run
      return loop.run_until_complete(main)
    File "/usr/local/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
      return future.result()
    File "<...>/test.py", line 17, in main
      assert await client.ping() == b"PONG"
    File "<...>/venv/lib/python3.8/site-packages/aioredis/commands/__init__.py", line 114, in ping
      return self.execute('PING', *args, encoding=encoding)
    File "<...>/venv/lib/python3.8/site-packages/aioredis/commands/__init__.py", line 51, in execute
      return self._pool_or_conn.execute(command, *args, **kwargs)
    File "<...>/venv/lib/python3.8/site-packages/elasticapm/instrumentation/packages/base.py", line 210, in call_if_sampling
      return self.call(module, method, wrapped, instance, args, kwargs)
    File "<...>/venv/lib/python3.8/site-packages/elasticapm/instrumentation/packages/asyncio/aioredis.py", line 46, in call
      wrapped_name = args[0].decode()
  AttributeError: 'str' object has no attribute 'decode'
  ```
  
  **Environment**
  - OS: Ubuntu 18.04.5 LTS
  - Python version: 3.8.9
  - Framework and version: `aioredis==1.3.1`
  - APM Server version: --
  - Agent version: `elasticapm==6.3.3`
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `elasticapm/instrumentation/packages/asyncio/aioredis.py`
  Content:
  ```
  1 #  BSD 3-Clause License
  2 #
  3 #  Copyright (c) 2019, Elasticsearch BV
  4 #  All rights reserved.
  5 #
  6 #  Redistribution and use in source and binary forms, with or without
  7 #  modification, are permitted provided that the following conditions are met:
  8 #
  9 #  * Redistributions of source code must retain the above copyright notice, this
  10 #    list of conditions and the following disclaimer.
  11 #
  12 #  * Redistributions in binary form must reproduce the above copyright notice,
  13 #    this list of conditions and the following disclaimer in the documentation
  14 #    and/or other materials provided with the distribution.
  15 #
  16 #  * Neither the name of the copyright holder nor the names of its
  17 #    contributors may be used to endorse or promote products derived from
  18 #    this software without specific prior written permission.
  19 #
  20 #  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  21 #  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22 #  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  23 #  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  24 #  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  25 #  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  26 #  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  27 #  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  28 #  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29 #  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30 
  31 from __future__ import absolute_import
  32 
  33 from elasticapm.contrib.asyncio.traces import async_capture_span
  34 from elasticapm.instrumentation.packages.base import AbstractInstrumentedModule
  35 from elasticapm.traces import execution_context
  36 
  37 
  38 class RedisConnectionPoolInstrumentation(AbstractInstrumentedModule):
  39     name = "aioredis"
  40 
  41     instrument_list = [("aioredis.pool", "ConnectionsPool.execute"),
  42                        ("aioredis.pool", "ConnectionsPool.execute_pubsub")]
  43 
  44     def call(self, module, method, wrapped, instance, args, kwargs):
  45         if len(args) > 0:
  46             wrapped_name = args[0].decode()
  47         else:
  48             wrapped_name = self.get_wrapped_name(wrapped, instance, method)
  49 
  50         with async_capture_span(
  51             wrapped_name, span_type="db", span_subtype="redis", span_action="query", leaf=True
  52         ) as span:
  53             span.context["destination"] = _get_destination_info(instance)
  54 
  55             return wrapped(*args, **kwargs)
  56 
  57 
  58 class RedisPipelineInstrumentation(AbstractInstrumentedModule):
  59     name = "aioredis"
  60 
  61     instrument_list = [("aioredis.commands.transaction", "Pipeline.execute")]
  62 
  63     def call(self, module, method, wrapped, instance, args, kwargs):
  64         wrapped_name = self.get_wrapped_name(wrapped, instance, method)
  65 
  66         with async_capture_span(
  67             wrapped_name, span_type="db", span_subtype="redis", span_action="query", leaf=True
  68         ) as span:
  69             span.context["destination"] = _get_destination_info(instance)
  70 
  71             return wrapped(*args, **kwargs)
  72 
  73 
  74 class RedisConnectionInstrumentation(AbstractInstrumentedModule):
  75     name = "aioredis"
  76 
  77     instrument_list = (("aioredis.connection", "RedisConnection.execute"),
  78                        ("aioredis.pool", "ConnectionsPool.execute_pubsub"))
  79 
  80     def call(self, module, method, wrapped, instance, args, kwargs):
  81         span = execution_context.get_span()
  82         if span and span.subtype == "aioredis":
  83             span.context["destination"] = _get_destination_info(instance)
  84         return wrapped(*args, **kwargs)
  85 
  86 
  87 def _get_destination_info(connection):
  88     destination_info = {"service": {"name": "aioredis", "resource": "redis", "type": "db"}}
  89 
  90     if hasattr(connection, "_pool_or_conn"):
  91         destination_info["port"] = connection._pool_or_conn.address[1]
  92         destination_info["address"] = connection._pool_or_conn.address[0]
  93     else:
  94         destination_info["port"] = connection.address[1]
  95         destination_info["address"] = connection.address[0]
  96 
  97     return destination_info
  98
  ```
  --- 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/elasticapm/instrumentation/packages/asyncio/aioredis.py b/elasticapm/instrumentation/packages/asyncio/aioredis.py
  --- a/elasticapm/instrumentation/packages/asyncio/aioredis.py
  +++ b/elasticapm/instrumentation/packages/asyncio/aioredis.py
  @@ -38,12 +38,16 @@
   class RedisConnectionPoolInstrumentation(AbstractInstrumentedModule):
       name = "aioredis"
   
  -    instrument_list = [("aioredis.pool", "ConnectionsPool.execute"),
  -                       ("aioredis.pool", "ConnectionsPool.execute_pubsub")]
  +    instrument_list = [
  +        ("aioredis.pool", "ConnectionsPool.execute"),
  +        ("aioredis.pool", "ConnectionsPool.execute_pubsub"),
  +    ]
   
       def call(self, module, method, wrapped, instance, args, kwargs):
           if len(args) > 0:
  -            wrapped_name = args[0].decode()
  +            wrapped_name = args[0]
  +            if isinstance(wrapped_name, bytes):
  +                wrapped_name = wrapped_name.decode()
           else:
               wrapped_name = self.get_wrapped_name(wrapped, instance, method)
   
  @@ -74,8 +78,10 @@
   class RedisConnectionInstrumentation(AbstractInstrumentedModule):
       name = "aioredis"
   
  -    instrument_list = (("aioredis.connection", "RedisConnection.execute"),
  -                       ("aioredis.pool", "ConnectionsPool.execute_pubsub"))
  +    instrument_list = (
  +        ("aioredis.connection", "RedisConnection.execute"),
  +        ("aioredis.pool", "ConnectionsPool.execute_pubsub"),
  +    )
   
       def call(self, module, method, wrapped, instance, args, kwargs):
           span = execution_context.get_span()
  
verification_info: {"golden_diff": "diff --git a/elasticapm/instrumentation/packages/asyncio/aioredis.py b/elasticapm/instrumentation/packages/asyncio/aioredis.py\n--- a/elasticapm/instrumentation/packages/asyncio/aioredis.py\n+++ b/elasticapm/instrumentation/packages/asyncio/aioredis.py\n@@ -38,12 +38,16 @@\n class RedisConnectionPoolInstrumentation(AbstractInstrumentedModule):\n     name = \"aioredis\"\n \n-    instrument_list = [(\"aioredis.pool\", \"ConnectionsPool.execute\"),\n-                       (\"aioredis.pool\", \"ConnectionsPool.execute_pubsub\")]\n+    instrument_list = [\n+        (\"aioredis.pool\", \"ConnectionsPool.execute\"),\n+        (\"aioredis.pool\", \"ConnectionsPool.execute_pubsub\"),\n+    ]\n \n     def call(self, module, method, wrapped, instance, args, kwargs):\n         if len(args) > 0:\n-            wrapped_name = args[0].decode()\n+            wrapped_name = args[0]\n+            if isinstance(wrapped_name, bytes):\n+                wrapped_name = wrapped_name.decode()\n         else:\n             wrapped_name = self.get_wrapped_name(wrapped, instance, method)\n \n@@ -74,8 +78,10 @@\n class RedisConnectionInstrumentation(AbstractInstrumentedModule):\n     name = \"aioredis\"\n \n-    instrument_list = ((\"aioredis.connection\", \"RedisConnection.execute\"),\n-                       (\"aioredis.pool\", \"ConnectionsPool.execute_pubsub\"))\n+    instrument_list = (\n+        (\"aioredis.connection\", \"RedisConnection.execute\"),\n+        (\"aioredis.pool\", \"ConnectionsPool.execute_pubsub\"),\n+    )\n \n     def call(self, module, method, wrapped, instance, args, kwargs):\n         span = execution_context.get_span()\n", "issue": "aioredis instrumentation: AttributeError: 'str' object has no attribute 'decode'\n**Describe the bug**\r\nIn some cases `aioredis` passes `str` commands to its `aioredis.Redis.execute()` method rather than `bytes` commands, like e.g. when executing `aioredis.Redis.ping()`, which is unacceptable by `elastic-apm`.  \r\n\r\n**Current workaround**\r\nDisable `aioredis` instrumenting (set environment variable `SKIP_INSTRUMENT_AIOREDIS=\"true\"`) prior `elasticapm.instrument()` is called.\r\n\r\n**To Reproduce**\r\n```python3\r\nimport asyncio\r\n\r\nimport aioredis\r\nimport elasticapm\r\n\r\nREDIS_URL = \"redis://localhost:6379\"\r\n\r\n\r\nasync def main():\r\n    elasticapm.instrument()\r\n\r\n    client = await aioredis.create_redis_pool(REDIS_URL)\r\n    elastic_apm_client = elasticapm.Client()\r\n\r\n    elastic_apm_client.begin_transaction(\"redis-ping\")\r\n    try:\r\n        assert await client.ping() == b\"PONG\"\r\n    finally:\r\n        client.close()\r\n        await client.wait_closed()\r\n        elastic_apm_client.end_transaction(\"redis-ping\")\r\n\r\nif __name__ == \"__main__\":\r\n    asyncio.run(main())\r\n```\r\n\r\n**Expected result**\r\nNo exception is raised.\r\n\r\n**Actual result**\r\n```python3\r\nTraceback (most recent call last):\r\n  File \"<...>/test.py\", line 24, in <module>\r\n    asyncio.run(main())\r\n  File \"/usr/local/lib/python3.8/asyncio/runners.py\", line 44, in run\r\n    return loop.run_until_complete(main)\r\n  File \"/usr/local/lib/python3.8/asyncio/base_events.py\", line 616, in run_until_complete\r\n    return future.result()\r\n  File \"<...>/test.py\", line 17, in main\r\n    assert await client.ping() == b\"PONG\"\r\n  File \"<...>/venv/lib/python3.8/site-packages/aioredis/commands/__init__.py\", line 114, in ping\r\n    return self.execute('PING', *args, encoding=encoding)\r\n  File \"<...>/venv/lib/python3.8/site-packages/aioredis/commands/__init__.py\", line 51, in execute\r\n    return self._pool_or_conn.execute(command, *args, **kwargs)\r\n  File \"<...>/venv/lib/python3.8/site-packages/elasticapm/instrumentation/packages/base.py\", line 210, in call_if_sampling\r\n    return self.call(module, method, wrapped, instance, args, kwargs)\r\n  File \"<...>/venv/lib/python3.8/site-packages/elasticapm/instrumentation/packages/asyncio/aioredis.py\", line 46, in call\r\n    wrapped_name = args[0].decode()\r\nAttributeError: 'str' object has no attribute 'decode'\r\n```\r\n\r\n**Environment**\r\n- OS: Ubuntu 18.04.5 LTS\r\n- Python version: 3.8.9\r\n- Framework and version: `aioredis==1.3.1`\r\n- APM Server version: --\r\n- Agent version: `elasticapm==6.3.3`\r\n\n", "before_files": [{"content": "#  BSD 3-Clause License\n#\n#  Copyright (c) 2019, Elasticsearch BV\n#  All rights reserved.\n#\n#  Redistribution and use in source and binary forms, with or without\n#  modification, are permitted provided that the following conditions are met:\n#\n#  * Redistributions of source code must retain the above copyright notice, this\n#    list of conditions and the following disclaimer.\n#\n#  * Redistributions in binary form must reproduce the above copyright notice,\n#    this list of conditions and the following disclaimer in the documentation\n#    and/or other materials provided with the distribution.\n#\n#  * Neither the name of the copyright holder nor the names of its\n#    contributors may be used to endorse or promote products derived from\n#    this software without specific prior written permission.\n#\n#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n#  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n#  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n#  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n#  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n#  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n#  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n#  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nfrom __future__ import absolute_import\n\nfrom elasticapm.contrib.asyncio.traces import async_capture_span\nfrom elasticapm.instrumentation.packages.base import AbstractInstrumentedModule\nfrom elasticapm.traces import execution_context\n\n\nclass RedisConnectionPoolInstrumentation(AbstractInstrumentedModule):\n    name = \"aioredis\"\n\n    instrument_list = [(\"aioredis.pool\", \"ConnectionsPool.execute\"),\n                       (\"aioredis.pool\", \"ConnectionsPool.execute_pubsub\")]\n\n    def call(self, module, method, wrapped, instance, args, kwargs):\n        if len(args) > 0:\n            wrapped_name = args[0].decode()\n        else:\n            wrapped_name = self.get_wrapped_name(wrapped, instance, method)\n\n        with async_capture_span(\n            wrapped_name, span_type=\"db\", span_subtype=\"redis\", span_action=\"query\", leaf=True\n        ) as span:\n            span.context[\"destination\"] = _get_destination_info(instance)\n\n            return wrapped(*args, **kwargs)\n\n\nclass RedisPipelineInstrumentation(AbstractInstrumentedModule):\n    name = \"aioredis\"\n\n    instrument_list = [(\"aioredis.commands.transaction\", \"Pipeline.execute\")]\n\n    def call(self, module, method, wrapped, instance, args, kwargs):\n        wrapped_name = self.get_wrapped_name(wrapped, instance, method)\n\n        with async_capture_span(\n            wrapped_name, span_type=\"db\", span_subtype=\"redis\", span_action=\"query\", leaf=True\n        ) as span:\n            span.context[\"destination\"] = _get_destination_info(instance)\n\n            return wrapped(*args, **kwargs)\n\n\nclass RedisConnectionInstrumentation(AbstractInstrumentedModule):\n    name = \"aioredis\"\n\n    instrument_list = ((\"aioredis.connection\", \"RedisConnection.execute\"),\n                       (\"aioredis.pool\", \"ConnectionsPool.execute_pubsub\"))\n\n    def call(self, module, method, wrapped, instance, args, kwargs):\n        span = execution_context.get_span()\n        if span and span.subtype == \"aioredis\":\n            span.context[\"destination\"] = _get_destination_info(instance)\n        return wrapped(*args, **kwargs)\n\n\ndef _get_destination_info(connection):\n    destination_info = {\"service\": {\"name\": \"aioredis\", \"resource\": \"redis\", \"type\": \"db\"}}\n\n    if hasattr(connection, \"_pool_or_conn\"):\n        destination_info[\"port\"] = connection._pool_or_conn.address[1]\n        destination_info[\"address\"] = connection._pool_or_conn.address[0]\n    else:\n        destination_info[\"port\"] = connection.address[1]\n        destination_info[\"address\"] = connection.address[0]\n\n    return destination_info\n", "path": "elasticapm/instrumentation/packages/asyncio/aioredis.py"}], "after_files": [{"content": "#  BSD 3-Clause License\n#\n#  Copyright (c) 2019, Elasticsearch BV\n#  All rights reserved.\n#\n#  Redistribution and use in source and binary forms, with or without\n#  modification, are permitted provided that the following conditions are met:\n#\n#  * Redistributions of source code must retain the above copyright notice, this\n#    list of conditions and the following disclaimer.\n#\n#  * Redistributions in binary form must reproduce the above copyright notice,\n#    this list of conditions and the following disclaimer in the documentation\n#    and/or other materials provided with the distribution.\n#\n#  * Neither the name of the copyright holder nor the names of its\n#    contributors may be used to endorse or promote products derived from\n#    this software without specific prior written permission.\n#\n#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n#  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n#  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n#  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n#  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n#  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n#  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n#  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nfrom __future__ import absolute_import\n\nfrom elasticapm.contrib.asyncio.traces import async_capture_span\nfrom elasticapm.instrumentation.packages.base import AbstractInstrumentedModule\nfrom elasticapm.traces import execution_context\n\n\nclass RedisConnectionPoolInstrumentation(AbstractInstrumentedModule):\n    name = \"aioredis\"\n\n    instrument_list = [\n        (\"aioredis.pool\", \"ConnectionsPool.execute\"),\n        (\"aioredis.pool\", \"ConnectionsPool.execute_pubsub\"),\n    ]\n\n    def call(self, module, method, wrapped, instance, args, kwargs):\n        if len(args) > 0:\n            wrapped_name = args[0]\n            if isinstance(wrapped_name, bytes):\n                wrapped_name = wrapped_name.decode()\n        else:\n            wrapped_name = self.get_wrapped_name(wrapped, instance, method)\n\n        with async_capture_span(\n            wrapped_name, span_type=\"db\", span_subtype=\"redis\", span_action=\"query\", leaf=True\n        ) as span:\n            span.context[\"destination\"] = _get_destination_info(instance)\n\n            return wrapped(*args, **kwargs)\n\n\nclass RedisPipelineInstrumentation(AbstractInstrumentedModule):\n    name = \"aioredis\"\n\n    instrument_list = [(\"aioredis.commands.transaction\", \"Pipeline.execute\")]\n\n    def call(self, module, method, wrapped, instance, args, kwargs):\n        wrapped_name = self.get_wrapped_name(wrapped, instance, method)\n\n        with async_capture_span(\n            wrapped_name, span_type=\"db\", span_subtype=\"redis\", span_action=\"query\", leaf=True\n        ) as span:\n            span.context[\"destination\"] = _get_destination_info(instance)\n\n            return wrapped(*args, **kwargs)\n\n\nclass RedisConnectionInstrumentation(AbstractInstrumentedModule):\n    name = \"aioredis\"\n\n    instrument_list = (\n        (\"aioredis.connection\", \"RedisConnection.execute\"),\n        (\"aioredis.pool\", \"ConnectionsPool.execute_pubsub\"),\n    )\n\n    def call(self, module, method, wrapped, instance, args, kwargs):\n        span = execution_context.get_span()\n        if span and span.subtype == \"aioredis\":\n            span.context[\"destination\"] = _get_destination_info(instance)\n        return wrapped(*args, **kwargs)\n\n\ndef _get_destination_info(connection):\n    destination_info = {\"service\": {\"name\": \"aioredis\", \"resource\": \"redis\", \"type\": \"db\"}}\n\n    if hasattr(connection, \"_pool_or_conn\"):\n        destination_info[\"port\"] = connection._pool_or_conn.address[1]\n        destination_info[\"address\"] = connection._pool_or_conn.address[0]\n    else:\n        destination_info[\"port\"] = connection.address[1]\n        destination_info[\"address\"] = connection.address[0]\n\n    return destination_info\n", "path": "elasticapm/instrumentation/packages/asyncio/aioredis.py"}]}