From f26e90f7128652905a7c9f21fdea3ce148e0cfc2 Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Tue, 23 Apr 2024 15:50:13 +0200 Subject: [PATCH 1/3] Log start and end of request Configurable via `use_access_logging_middleware`. Looks like this: ``` galaxy.webapps.base.api DEBUG 2024-04-23 17:14:43,776 [pN:main,p:73562,tN:MainThread] GET /history/current_history_json?since=2024-04-22T17:24:13.936493 f8c75e2c-30eb-4fcb-9b96-25bd4b2df435 galaxy.webapps.base.api DEBUG 2024-04-23 17:14:48,719 [pN:main,p:73562,tN:MainThread] GET /history/current_history_json?since=2024-04-22T17:24:13.936493 f8c75e2c-30eb-4fcb-9b96-25bd4b2df435 200 galaxy.webapps.base.api DEBUG 2024-04-23 17:14:51,767 [pN:main,p:73562,tN:MainThread] GET /history/current_history_json?since=2024-04-22T17:24:13.936493 2fe6094c-67bb-4144-a19f-cbb4a1b18fb4 galaxy.webapps.base.api DEBUG 2024-04-23 17:14:51,786 [pN:main,p:73562,tN:MainThread] GET /history/current_history_json?since=2024-04-22T17:24:13.936493 2fe6094c-67bb-4144-a19f-cbb4a1b18fb4 200 galaxy.webapps.base.api DEBUG 2024-04-23 17:14:53,139 [pN:main,p:73562,tN:MainThread] GET /api/entry_points?running=true 763693e9-4fd3-4a97-a100-a3c259b4b4c8 ``` --- doc/source/admin/galaxy_options.rst | 14 ++++++-- lib/galaxy/config/sample/galaxy.yml.sample | 4 +++ lib/galaxy/config/schemas/config_schema.yml | 7 ++++ lib/galaxy/webapps/base/api.py | 36 ++++++++++++++++++++- lib/galaxy/webapps/galaxy/fast_app.py | 6 +++- 5 files changed, 62 insertions(+), 5 deletions(-) diff --git a/doc/source/admin/galaxy_options.rst b/doc/source/admin/galaxy_options.rst index f3021dc25d4..4e2fca9c11d 100644 --- a/doc/source/admin/galaxy_options.rst +++ b/doc/source/admin/galaxy_options.rst @@ -3030,6 +3030,17 @@ :Type: bool +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``use_access_logging_middleware`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:Description: + Log request start as well as request end. Disables uvicorn access + log handler. +:Default: ``false`` +:Type: bool + + ~~~~~~~~~~~~ ``use_lint`` ~~~~~~~~~~~~ @@ -5477,6 +5488,3 @@ This requires the help_forum_api_url to be set. :Default: ``false`` :Type: bool - - - diff --git a/lib/galaxy/config/sample/galaxy.yml.sample b/lib/galaxy/config/sample/galaxy.yml.sample index 21b325bdb49..fef52325c76 100644 --- a/lib/galaxy/config/sample/galaxy.yml.sample +++ b/lib/galaxy/config/sample/galaxy.yml.sample @@ -1743,6 +1743,10 @@ galaxy: # job is complete. #debug: false + # Log request start as well as request end. Disables uvicorn access + # log handler. + #use_access_logging_middleware: false + # Check for WSGI compliance. #use_lint: false diff --git a/lib/galaxy/config/schemas/config_schema.yml b/lib/galaxy/config/schemas/config_schema.yml index ea25af4fc4c..81078d8aef6 100644 --- a/lib/galaxy/config/schemas/config_schema.yml +++ b/lib/galaxy/config/schemas/config_schema.yml @@ -2193,6 +2193,13 @@ mapping: causes the files used by PBS/SGE (submission script, output, and error) to remain on disk after the job is complete. + use_access_logging_middleware: + type: bool + default: false + required: false + desc: | + Log request start as well as request end. Disables uvicorn access log handler. + use_lint: type: bool default: false diff --git a/lib/galaxy/webapps/base/api.py b/lib/galaxy/webapps/base/api.py index 7923fc29733..df779127f0c 100644 --- a/lib/galaxy/webapps/base/api.py +++ b/lib/galaxy/webapps/base/api.py @@ -1,6 +1,8 @@ import os import stat import typing +import uuid +from logging import getLogger import anyio from fastapi import ( @@ -15,8 +17,12 @@ from starlette.responses import ( FileResponse, Response, ) +from starlette_context import context from starlette_context.middleware import RawContextMiddleware -from starlette_context.plugins import RequestIdPlugin +from starlette_context.plugins import ( + Plugin, + RequestIdPlugin, +) from galaxy.exceptions import MessageException from galaxy.exceptions.utils import api_error_to_dict @@ -32,6 +38,9 @@ if typing.TYPE_CHECKING: ) +log = getLogger(__name__) + + # Copied from https://github.com/tiangolo/fastapi/issues/1240#issuecomment-1055396884 def _get_range_header(range_header: str, file_size: int) -> typing.Tuple[int, int]: def _invalid_range(): @@ -192,6 +201,31 @@ def add_exception_handler(app: FastAPI) -> None: return get_error_response_for_request(request, exc) +class AccessLoggingMiddleware(Plugin): + + key = "access_line" + + async def process_request(self, request): + scope = request.scope + path = scope["root_path"] + scope["path"] + if scope["query_string"]: + path = f"{path}?{scope['query_string'].decode('ascii')}" + access_line = f"{scope['method']} {path} {uuid.uuid4()}" + log.debug(access_line) + return access_line + + async def enrich_response(self, response) -> None: + access_line = context.get("access_line") + if status := response.get("status"): + log.debug(f"{access_line} {status}") + + +def add_raw_context_middlewares(app: FastAPI): + getLogger("uvicorn.access").handlers = [] + plugins = (RequestIdPlugin(force_new_uuid=True), AccessLoggingMiddleware()) + app.add_middleware(RawContextMiddleware, plugins=plugins) + + def add_request_id_middleware(app: FastAPI): app.add_middleware(RawContextMiddleware, plugins=(RequestIdPlugin(force_new_uuid=True),)) diff --git a/lib/galaxy/webapps/galaxy/fast_app.py b/lib/galaxy/webapps/galaxy/fast_app.py index 0a2e0e26ec1..4409708ed8d 100644 --- a/lib/galaxy/webapps/galaxy/fast_app.py +++ b/lib/galaxy/webapps/galaxy/fast_app.py @@ -16,6 +16,7 @@ from galaxy.schema.invocation import CustomJsonSchema from galaxy.version import VERSION from galaxy.webapps.base.api import ( add_exception_handler, + add_raw_context_middlewares, add_request_id_middleware, GalaxyFileResponse, include_all_package_routers, @@ -179,7 +180,10 @@ def initialize_fast_app(gx_wsgi_webapp, gx_app): app = get_fastapi_instance(root_path=root_path) add_exception_handler(app) add_galaxy_middleware(app, gx_app) - add_request_id_middleware(app) + if gx_app.config.use_access_logging_middleware: + add_raw_context_middlewares(app) + else: + add_request_id_middleware(app) include_all_package_routers(app, "galaxy.webapps.galaxy.api") include_legacy_openapi(app, gx_app) wsgi_handler = WSGIMiddleware(gx_wsgi_webapp) From 64be33ebc9c0e6244f32f9aa587d3a8b1a976651 Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Wed, 24 Apr 2024 17:11:53 +0200 Subject: [PATCH 2/3] Update k8s-version --- .github/workflows/integration.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration.yaml b/.github/workflows/integration.yaml index 58aa81dd63c..e90a4ea836b 100644 --- a/.github/workflows/integration.yaml +++ b/.github/workflows/integration.yaml @@ -62,7 +62,7 @@ jobs: id: minikube uses: CodingNagger/minikube-setup-action@v1.0.6 with: - k8s-version: '1.19.16' + k8s-version: '1.23.0' - name: Launch Minikube run: eval ${{ steps.minikube.outputs.launcher }} - name: Check pods From ab087383c8a3f9fa59df101afa35f3978cf74257 Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Wed, 24 Apr 2024 17:38:58 +0200 Subject: [PATCH 3/3] Update setup-miniconda@v3 action --- .github/workflows/osx_startup.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/osx_startup.yaml b/.github/workflows/osx_startup.yaml index ccc17526f87..5c0ffbe2b53 100644 --- a/.github/workflows/osx_startup.yaml +++ b/.github/workflows/osx_startup.yaml @@ -50,7 +50,7 @@ jobs: path: .tox key: tox-cache-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('galaxy root/requirements.txt') }}-osx - name: Install miniconda # use this job to test using Python from a conda environment - uses: conda-incubator/setup-miniconda@v2 + uses: conda-incubator/setup-miniconda@v3 with: activate-environment: '' - name: Restore client cache