prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  MLServer to hide http health request logs to avoid polluting the logs
  As part of the Seldon Core addition https://github.com/SeldonIO/seldon-core/pull/4028 which moves the TCP ready checks into proper HTTP request ready checks to `v2/health/ready` there is now a lot of noise from the readiness checks every 5 seconds. We should explore ways in which we avoid this noise, perhaps making it completely silent by default, or eventually once the prometheus server is created on a separate server this could also be added (And both of  them could be muted)
  
  ![image](https://user-images.githubusercontent.com/1447507/161749439-3e96c417-a630-4208-80d6-5fc5f262fcd3.png)
  
  
  </issue>
  <code>
  [start of mlserver/rest/server.py]
  1 import uvicorn
  2 
  3 from ..settings import Settings
  4 from ..handlers import DataPlane, ModelRepositoryHandlers, get_custom_handlers
  5 from ..model import MLModel
  6 
  7 from .utils import matches
  8 from .app import create_app
  9 from .logging import logger
  10 from typing import Optional
  11 
  12 
  13 class _NoSignalServer(uvicorn.Server):
  14     def install_signal_handlers(self):
  15         pass
  16 
  17 
  18 class RESTServer:
  19     def __init__(
  20         self,
  21         settings: Settings,
  22         data_plane: DataPlane,
  23         model_repository_handlers: ModelRepositoryHandlers,
  24     ):
  25         self._settings = settings
  26         self._data_plane = data_plane
  27         self._model_repository_handlers = model_repository_handlers
  28         self._app = create_app(
  29             self._settings,
  30             data_plane=self._data_plane,
  31             model_repository_handlers=self._model_repository_handlers,
  32         )
  33 
  34     async def add_custom_handlers(self, model: MLModel) -> MLModel:
  35         handlers = get_custom_handlers(model)
  36         for custom_handler, handler_method in handlers:
  37             self._app.add_api_route(
  38                 custom_handler.rest_path,
  39                 handler_method,
  40                 methods=[custom_handler.rest_method],
  41             )
  42 
  43         return model
  44 
  45     async def delete_custom_handlers(self, model: MLModel) -> MLModel:
  46         handlers = get_custom_handlers(model)
  47         if len(handlers) == 0:
  48             return model
  49 
  50         # NOTE: Loop in reverse, so that it's quicker to find all the recently
  51         # added routes and we can remove routes on-the-fly
  52         for i, route in reversed(list(enumerate(self._app.routes))):
  53             for j, (custom_handler, handler_method) in enumerate(handlers):
  54                 if matches(route, custom_handler, handler_method):  # type: ignore
  55                     self._app.routes.pop(i)
  56                     handlers.pop(j)
  57 
  58         return model
  59 
  60     async def start(self):
  61         cfg = self._get_config()
  62         self._server = _NoSignalServer(cfg)
  63         await self._server.serve()
  64 
  65     def _get_config(self):
  66         kwargs = {}
  67 
  68         if self._settings._custom_rest_server_settings:
  69             logger.warning(
  70                 "REST custom configuration is out of support. Use as your own risk"
  71             )
  72             kwargs.update(self._settings._custom_rest_server_settings)
  73 
  74         kwargs.update(
  75             {
  76                 "host": self._settings.host,
  77                 "port": self._settings.http_port,
  78                 "root_path": self._settings.root_path,
  79                 "access_log": self._settings.debug,
  80             }
  81         )
  82 
  83         if self._settings.logging_settings:
  84             # If not None, use ours. Otherwise, let Uvicorn fall back on its
  85             # own config.
  86             kwargs.update({"log_config": self._settings.logging_settings})
  87 
  88         return uvicorn.Config(self._app, **kwargs)
  89 
  90     async def stop(self, sig: Optional[int] = None):
  91         self._server.handle_exit(sig=sig, frame=None)
  92
  [end of mlserver/rest/server.py]
  [start of mlserver/rest/logging.py]
  1 import logging
  2 
  3 loggerName = "mlserver.rest"
  4 logger = logging.getLogger(loggerName)
  5
  [end of mlserver/rest/logging.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/mlserver/rest/logging.py b/mlserver/rest/logging.py
  --- a/mlserver/rest/logging.py
  +++ b/mlserver/rest/logging.py
  @@ -1,4 +1,35 @@
   import logging
   
  +
  +class HealthEndpointFilter(logging.Filter):
  +    """
  +    Filter to avoid logging health endpoints.
  +    From:
  +        https://github.com/encode/starlette/issues/864#issuecomment-653076434
  +    """
  +
  +    def filter(self, record: logging.LogRecord) -> bool:
  +        if not isinstance(record.args, tuple):
  +            return True
  +
  +        if len(record.args) < 3:
  +            return True
  +
  +        request_method = record.args[1]
  +        query_string = record.args[2]
  +        if request_method != "GET":
  +            return True
  +
  +        if query_string in ["/v2/health/live", "/v2/health/ready"]:
  +            return False
  +
  +        return True
  +
  +
  +def disable_health_access_logs() -> None:
  +    uvicorn_logger = logging.getLogger("uvicorn.access")
  +    uvicorn_logger.addFilter(HealthEndpointFilter())
  +
  +
   loggerName = "mlserver.rest"
   logger = logging.getLogger(loggerName)
  diff --git a/mlserver/rest/server.py b/mlserver/rest/server.py
  --- a/mlserver/rest/server.py
  +++ b/mlserver/rest/server.py
  @@ -6,7 +6,7 @@
   
   from .utils import matches
   from .app import create_app
  -from .logging import logger
  +from .logging import logger, disable_health_access_logs
   from typing import Optional
   
   
  @@ -60,6 +60,9 @@
       async def start(self):
           cfg = self._get_config()
           self._server = _NoSignalServer(cfg)
  +        if not self._settings.debug:
  +            disable_health_access_logs()
  +
           await self._server.serve()
   
       def _get_config(self):
  
verification_info: {"golden_diff": "diff --git a/mlserver/rest/logging.py b/mlserver/rest/logging.py\n--- a/mlserver/rest/logging.py\n+++ b/mlserver/rest/logging.py\n@@ -1,4 +1,35 @@\n import logging\n \n+\n+class HealthEndpointFilter(logging.Filter):\n+    \"\"\"\n+    Filter to avoid logging health endpoints.\n+    From:\n+        https://github.com/encode/starlette/issues/864#issuecomment-653076434\n+    \"\"\"\n+\n+    def filter(self, record: logging.LogRecord) -> bool:\n+        if not isinstance(record.args, tuple):\n+            return True\n+\n+        if len(record.args) < 3:\n+            return True\n+\n+        request_method = record.args[1]\n+        query_string = record.args[2]\n+        if request_method != \"GET\":\n+            return True\n+\n+        if query_string in [\"/v2/health/live\", \"/v2/health/ready\"]:\n+            return False\n+\n+        return True\n+\n+\n+def disable_health_access_logs() -> None:\n+    uvicorn_logger = logging.getLogger(\"uvicorn.access\")\n+    uvicorn_logger.addFilter(HealthEndpointFilter())\n+\n+\n loggerName = \"mlserver.rest\"\n logger = logging.getLogger(loggerName)\ndiff --git a/mlserver/rest/server.py b/mlserver/rest/server.py\n--- a/mlserver/rest/server.py\n+++ b/mlserver/rest/server.py\n@@ -6,7 +6,7 @@\n \n from .utils import matches\n from .app import create_app\n-from .logging import logger\n+from .logging import logger, disable_health_access_logs\n from typing import Optional\n \n \n@@ -60,6 +60,9 @@\n     async def start(self):\n         cfg = self._get_config()\n         self._server = _NoSignalServer(cfg)\n+        if not self._settings.debug:\n+            disable_health_access_logs()\n+\n         await self._server.serve()\n \n     def _get_config(self):\n", "issue": "MLServer to hide http health request logs to avoid polluting the logs\nAs part of the Seldon Core addition https://github.com/SeldonIO/seldon-core/pull/4028 which moves the TCP ready checks into proper HTTP request ready checks to `v2/health/ready` there is now a lot of noise from the readiness checks every 5 seconds. We should explore ways in which we avoid this noise, perhaps making it completely silent by default, or eventually once the prometheus server is created on a separate server this could also be added (And both of  them could be muted)\r\n\r\n![image](https://user-images.githubusercontent.com/1447507/161749439-3e96c417-a630-4208-80d6-5fc5f262fcd3.png)\r\n\n", "before_files": [{"content": "import uvicorn\n\nfrom ..settings import Settings\nfrom ..handlers import DataPlane, ModelRepositoryHandlers, get_custom_handlers\nfrom ..model import MLModel\n\nfrom .utils import matches\nfrom .app import create_app\nfrom .logging import logger\nfrom typing import Optional\n\n\nclass _NoSignalServer(uvicorn.Server):\n    def install_signal_handlers(self):\n        pass\n\n\nclass RESTServer:\n    def __init__(\n        self,\n        settings: Settings,\n        data_plane: DataPlane,\n        model_repository_handlers: ModelRepositoryHandlers,\n    ):\n        self._settings = settings\n        self._data_plane = data_plane\n        self._model_repository_handlers = model_repository_handlers\n        self._app = create_app(\n            self._settings,\n            data_plane=self._data_plane,\n            model_repository_handlers=self._model_repository_handlers,\n        )\n\n    async def add_custom_handlers(self, model: MLModel) -> MLModel:\n        handlers = get_custom_handlers(model)\n        for custom_handler, handler_method in handlers:\n            self._app.add_api_route(\n                custom_handler.rest_path,\n                handler_method,\n                methods=[custom_handler.rest_method],\n            )\n\n        return model\n\n    async def delete_custom_handlers(self, model: MLModel) -> MLModel:\n        handlers = get_custom_handlers(model)\n        if len(handlers) == 0:\n            return model\n\n        # NOTE: Loop in reverse, so that it's quicker to find all the recently\n        # added routes and we can remove routes on-the-fly\n        for i, route in reversed(list(enumerate(self._app.routes))):\n            for j, (custom_handler, handler_method) in enumerate(handlers):\n                if matches(route, custom_handler, handler_method):  # type: ignore\n                    self._app.routes.pop(i)\n                    handlers.pop(j)\n\n        return model\n\n    async def start(self):\n        cfg = self._get_config()\n        self._server = _NoSignalServer(cfg)\n        await self._server.serve()\n\n    def _get_config(self):\n        kwargs = {}\n\n        if self._settings._custom_rest_server_settings:\n            logger.warning(\n                \"REST custom configuration is out of support. Use as your own risk\"\n            )\n            kwargs.update(self._settings._custom_rest_server_settings)\n\n        kwargs.update(\n            {\n                \"host\": self._settings.host,\n                \"port\": self._settings.http_port,\n                \"root_path\": self._settings.root_path,\n                \"access_log\": self._settings.debug,\n            }\n        )\n\n        if self._settings.logging_settings:\n            # If not None, use ours. Otherwise, let Uvicorn fall back on its\n            # own config.\n            kwargs.update({\"log_config\": self._settings.logging_settings})\n\n        return uvicorn.Config(self._app, **kwargs)\n\n    async def stop(self, sig: Optional[int] = None):\n        self._server.handle_exit(sig=sig, frame=None)\n", "path": "mlserver/rest/server.py"}, {"content": "import logging\n\nloggerName = \"mlserver.rest\"\nlogger = logging.getLogger(loggerName)\n", "path": "mlserver/rest/logging.py"}]}