prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  KeyError:'db' when capturing elasticsearch span context
  **Describe the bug**: ...
  
  **To Reproduce**
  
  1. Instrument via capture serverless
  2. Perform an async_scan:
  ```python
  async with AsyncElasticsearch(**elastic_context) as client:
      async for doc in async_scan(
            client=client,
            index='XXX',
            query=query,
            _source=['field']
        ):
  ```
  ![image](https://user-images.githubusercontent.com/37186808/219222266-597464b9-9c70-4cea-b5de-f2c4b570cc5f.png)
  
  
  **Environment (please complete the following information)**
  - OS: [e.g. Linux] debian:bullseye-slim (python:3.9-slim container image) x86
  - Python version: 3.9
  - Framework and version [e.g. Django 2.1]: N/A AWS Lambda Function
  - APM Server version: 8.6.1
  - Agent version: 6.14.0
  
  
  **Additional context**
  
  Add any other context about the problem here.
  
  - Agent config options <!-- be careful not to post sensitive information -->
    <details>
      <summary>Click to expand</summary>
  
      ```
      ELASTIC_APM_LOG_LEVEL: warning
      ELASTIC_APM_LAMBDA_APM_SERVER: https://<elastic-cloud-hostname>:443
      ELASTIC_APM_SECRET_TOKEN: ${env:ELASTIC_APM_SECRET_TOKEN}
      ELASTIC_APM_ENVIRONMENT: ${self:provider.stage}
      ELASTIC_APM_SPAN_COMPRESSION_SAME_KIND_MAX_DURATION: 50ms
      ```
    </details>
  - `requirements.txt`:
    <details>
      <summary>Click to expand</summary>
  
      ```toml
      [tool.poetry.dependencies]
      python = "^3.9"
      elasticsearch = "^8"
      elastic-apm = "^6.14"
      tomlkit = "^0.11.1"
      uvloop = "^0.17.0"
      PyYAML = "^6.0"
      aiobotocore = "^2.3"
      urllib3 = "^1.26.10"
      python-dateutil = "^2.8.2"
      pyjarm = "^0.0.5"
      aiohttp = "^3.8"
      multidict = "^6"
      ```
    </details>
  
  
  --- 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/elasticsearch.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 import elasticapm
  32 from elasticapm.instrumentation.packages.asyncio.base import AsyncAbstractInstrumentedModule
  33 from elasticapm.instrumentation.packages.elasticsearch import (
  34     ElasticsearchConnectionInstrumentation,
  35     ElasticsearchTransportInstrumentation,
  36 )
  37 from elasticapm.traces import DroppedSpan, execution_context
  38 
  39 
  40 class ElasticSearchAsyncConnection(ElasticsearchConnectionInstrumentation, AsyncAbstractInstrumentedModule):
  41     name = "elasticsearch_connection"
  42 
  43     def get_instrument_list(self):
  44         try:
  45             import elastic_transport  # noqa: F401
  46 
  47             return [
  48                 ("elastic_transport._node._http_aiohttp", "AiohttpHttpNode.perform_request"),
  49             ]
  50         except ImportError:
  51             return [
  52                 ("elasticsearch_async.connection", "AIOHttpConnection.perform_request"),
  53                 ("elasticsearch._async.http_aiohttp", "AIOHttpConnection.perform_request"),
  54             ]
  55 
  56     async def call(self, module, method, wrapped, instance, args, kwargs):
  57         span = execution_context.get_span()
  58         if not span or isinstance(span, DroppedSpan):
  59             return await wrapped(*args, **kwargs)
  60 
  61         self._update_context_by_request_data(span.context, instance, args, kwargs)
  62 
  63         result = await wrapped(*args, **kwargs)
  64         if hasattr(result, "meta"):  # elasticsearch-py 8.x+
  65             status_code = result.meta.status
  66         else:
  67             status_code = result[0]
  68 
  69         span.context["http"] = {"status_code": status_code}
  70 
  71         return result
  72 
  73 
  74 class ElasticsearchAsyncTransportInstrumentation(
  75     ElasticsearchTransportInstrumentation, AsyncAbstractInstrumentedModule
  76 ):
  77     name = "elasticsearch_connection"
  78 
  79     instrument_list = [
  80         ("elasticsearch._async.transport", "AsyncTransport.perform_request"),
  81     ]
  82 
  83     def get_instrument_list(self):
  84         try:
  85             import elastic_transport  # noqa: F401
  86 
  87             return [
  88                 ("elastic_transport", "AsyncTransport.perform_request"),
  89             ]
  90         except ImportError:
  91             return [
  92                 ("elasticsearch._async.transport", "AsyncTransport.perform_request"),
  93             ]
  94 
  95     async def call(self, module, method, wrapped, instance, args, kwargs):
  96         async with elasticapm.async_capture_span(
  97             self._get_signature(args, kwargs),
  98             span_type="db",
  99             span_subtype="elasticsearch",
  100             span_action="query",
  101             extra={},
  102             skip_frames=2,
  103             leaf=True,
  104         ) as span:
  105             result_data = await wrapped(*args, **kwargs)
  106 
  107             hits = self._get_hits(result_data)
  108             if hits:
  109                 span.context["db"]["rows_affected"] = hits
  110 
  111             return result_data
  112
  ```
  --- 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/elasticsearch.py b/elasticapm/instrumentation/packages/asyncio/elasticsearch.py
  --- a/elasticapm/instrumentation/packages/asyncio/elasticsearch.py
  +++ b/elasticapm/instrumentation/packages/asyncio/elasticsearch.py
  @@ -106,6 +106,6 @@
   
               hits = self._get_hits(result_data)
               if hits:
  -                span.context["db"]["rows_affected"] = hits
  +                span.update_context("db", {"rows_affected": hits})
   
               return result_data
  
verification_info: {"golden_diff": "diff --git a/elasticapm/instrumentation/packages/asyncio/elasticsearch.py b/elasticapm/instrumentation/packages/asyncio/elasticsearch.py\n--- a/elasticapm/instrumentation/packages/asyncio/elasticsearch.py\n+++ b/elasticapm/instrumentation/packages/asyncio/elasticsearch.py\n@@ -106,6 +106,6 @@\n \n             hits = self._get_hits(result_data)\n             if hits:\n-                span.context[\"db\"][\"rows_affected\"] = hits\n+                span.update_context(\"db\", {\"rows_affected\": hits})\n \n             return result_data\n", "issue": "KeyError:'db' when capturing elasticsearch span context\n**Describe the bug**: ...\r\n\r\n**To Reproduce**\r\n\r\n1. Instrument via capture serverless\r\n2. Perform an async_scan:\r\n```python\r\nasync with AsyncElasticsearch(**elastic_context) as client:\r\n    async for doc in async_scan(\r\n          client=client,\r\n          index='XXX',\r\n          query=query,\r\n          _source=['field']\r\n      ):\r\n```\r\n![image](https://user-images.githubusercontent.com/37186808/219222266-597464b9-9c70-4cea-b5de-f2c4b570cc5f.png)\r\n\r\n\r\n**Environment (please complete the following information)**\r\n- OS: [e.g. Linux] debian:bullseye-slim (python:3.9-slim container image) x86\r\n- Python version: 3.9\r\n- Framework and version [e.g. Django 2.1]: N/A AWS Lambda Function\r\n- APM Server version: 8.6.1\r\n- Agent version: 6.14.0\r\n\r\n\r\n**Additional context**\r\n\r\nAdd any other context about the problem here.\r\n\r\n- Agent config options <!-- be careful not to post sensitive information -->\r\n  <details>\r\n    <summary>Click to expand</summary>\r\n\r\n    ```\r\n    ELASTIC_APM_LOG_LEVEL: warning\r\n    ELASTIC_APM_LAMBDA_APM_SERVER: https://<elastic-cloud-hostname>:443\r\n    ELASTIC_APM_SECRET_TOKEN: ${env:ELASTIC_APM_SECRET_TOKEN}\r\n    ELASTIC_APM_ENVIRONMENT: ${self:provider.stage}\r\n    ELASTIC_APM_SPAN_COMPRESSION_SAME_KIND_MAX_DURATION: 50ms\r\n    ```\r\n  </details>\r\n- `requirements.txt`:\r\n  <details>\r\n    <summary>Click to expand</summary>\r\n\r\n    ```toml\r\n    [tool.poetry.dependencies]\r\n    python = \"^3.9\"\r\n    elasticsearch = \"^8\"\r\n    elastic-apm = \"^6.14\"\r\n    tomlkit = \"^0.11.1\"\r\n    uvloop = \"^0.17.0\"\r\n    PyYAML = \"^6.0\"\r\n    aiobotocore = \"^2.3\"\r\n    urllib3 = \"^1.26.10\"\r\n    python-dateutil = \"^2.8.2\"\r\n    pyjarm = \"^0.0.5\"\r\n    aiohttp = \"^3.8\"\r\n    multidict = \"^6\"\r\n    ```\r\n  </details>\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\nimport elasticapm\nfrom elasticapm.instrumentation.packages.asyncio.base import AsyncAbstractInstrumentedModule\nfrom elasticapm.instrumentation.packages.elasticsearch import (\n    ElasticsearchConnectionInstrumentation,\n    ElasticsearchTransportInstrumentation,\n)\nfrom elasticapm.traces import DroppedSpan, execution_context\n\n\nclass ElasticSearchAsyncConnection(ElasticsearchConnectionInstrumentation, AsyncAbstractInstrumentedModule):\n    name = \"elasticsearch_connection\"\n\n    def get_instrument_list(self):\n        try:\n            import elastic_transport  # noqa: F401\n\n            return [\n                (\"elastic_transport._node._http_aiohttp\", \"AiohttpHttpNode.perform_request\"),\n            ]\n        except ImportError:\n            return [\n                (\"elasticsearch_async.connection\", \"AIOHttpConnection.perform_request\"),\n                (\"elasticsearch._async.http_aiohttp\", \"AIOHttpConnection.perform_request\"),\n            ]\n\n    async def call(self, module, method, wrapped, instance, args, kwargs):\n        span = execution_context.get_span()\n        if not span or isinstance(span, DroppedSpan):\n            return await wrapped(*args, **kwargs)\n\n        self._update_context_by_request_data(span.context, instance, args, kwargs)\n\n        result = await wrapped(*args, **kwargs)\n        if hasattr(result, \"meta\"):  # elasticsearch-py 8.x+\n            status_code = result.meta.status\n        else:\n            status_code = result[0]\n\n        span.context[\"http\"] = {\"status_code\": status_code}\n\n        return result\n\n\nclass ElasticsearchAsyncTransportInstrumentation(\n    ElasticsearchTransportInstrumentation, AsyncAbstractInstrumentedModule\n):\n    name = \"elasticsearch_connection\"\n\n    instrument_list = [\n        (\"elasticsearch._async.transport\", \"AsyncTransport.perform_request\"),\n    ]\n\n    def get_instrument_list(self):\n        try:\n            import elastic_transport  # noqa: F401\n\n            return [\n                (\"elastic_transport\", \"AsyncTransport.perform_request\"),\n            ]\n        except ImportError:\n            return [\n                (\"elasticsearch._async.transport\", \"AsyncTransport.perform_request\"),\n            ]\n\n    async def call(self, module, method, wrapped, instance, args, kwargs):\n        async with elasticapm.async_capture_span(\n            self._get_signature(args, kwargs),\n            span_type=\"db\",\n            span_subtype=\"elasticsearch\",\n            span_action=\"query\",\n            extra={},\n            skip_frames=2,\n            leaf=True,\n        ) as span:\n            result_data = await wrapped(*args, **kwargs)\n\n            hits = self._get_hits(result_data)\n            if hits:\n                span.context[\"db\"][\"rows_affected\"] = hits\n\n            return result_data\n", "path": "elasticapm/instrumentation/packages/asyncio/elasticsearch.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\nimport elasticapm\nfrom elasticapm.instrumentation.packages.asyncio.base import AsyncAbstractInstrumentedModule\nfrom elasticapm.instrumentation.packages.elasticsearch import (\n    ElasticsearchConnectionInstrumentation,\n    ElasticsearchTransportInstrumentation,\n)\nfrom elasticapm.traces import DroppedSpan, execution_context\n\n\nclass ElasticSearchAsyncConnection(ElasticsearchConnectionInstrumentation, AsyncAbstractInstrumentedModule):\n    name = \"elasticsearch_connection\"\n\n    def get_instrument_list(self):\n        try:\n            import elastic_transport  # noqa: F401\n\n            return [\n                (\"elastic_transport._node._http_aiohttp\", \"AiohttpHttpNode.perform_request\"),\n            ]\n        except ImportError:\n            return [\n                (\"elasticsearch_async.connection\", \"AIOHttpConnection.perform_request\"),\n                (\"elasticsearch._async.http_aiohttp\", \"AIOHttpConnection.perform_request\"),\n            ]\n\n    async def call(self, module, method, wrapped, instance, args, kwargs):\n        span = execution_context.get_span()\n        if not span or isinstance(span, DroppedSpan):\n            return await wrapped(*args, **kwargs)\n\n        self._update_context_by_request_data(span.context, instance, args, kwargs)\n\n        result = await wrapped(*args, **kwargs)\n        if hasattr(result, \"meta\"):  # elasticsearch-py 8.x+\n            status_code = result.meta.status\n        else:\n            status_code = result[0]\n\n        span.context[\"http\"] = {\"status_code\": status_code}\n\n        return result\n\n\nclass ElasticsearchAsyncTransportInstrumentation(\n    ElasticsearchTransportInstrumentation, AsyncAbstractInstrumentedModule\n):\n    name = \"elasticsearch_connection\"\n\n    instrument_list = [\n        (\"elasticsearch._async.transport\", \"AsyncTransport.perform_request\"),\n    ]\n\n    def get_instrument_list(self):\n        try:\n            import elastic_transport  # noqa: F401\n\n            return [\n                (\"elastic_transport\", \"AsyncTransport.perform_request\"),\n            ]\n        except ImportError:\n            return [\n                (\"elasticsearch._async.transport\", \"AsyncTransport.perform_request\"),\n            ]\n\n    async def call(self, module, method, wrapped, instance, args, kwargs):\n        async with elasticapm.async_capture_span(\n            self._get_signature(args, kwargs),\n            span_type=\"db\",\n            span_subtype=\"elasticsearch\",\n            span_action=\"query\",\n            extra={},\n            skip_frames=2,\n            leaf=True,\n        ) as span:\n            result_data = await wrapped(*args, **kwargs)\n\n            hits = self._get_hits(result_data)\n            if hits:\n                span.update_context(\"db\", {\"rows_affected\": hits})\n\n            return result_data\n", "path": "elasticapm/instrumentation/packages/asyncio/elasticsearch.py"}]}