This is an automated email from the ASF dual-hosted git repository.

vatsrahul1001 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new 860233f3c72 Fix missing HTTP access logs when api-server omits the 
core app (#72026)
860233f3c72 is described below

commit 860233f3c72dcc3637c43c64223e57e078c84d55
Author: manish1337 <[email protected]>
AuthorDate: Wed Sep 9 19:19:34 2026 +0530

    Fix missing HTTP access logs when api-server omits the core app (#72026)
    
    * Fix missing HTTP access logs when api-server omits the core app
    
    An api-server started without the core app -- for example `--apps 
execution`,
    the shape used to run the Task Execution API as its own deployment -- served
    requests but recorded none of them. That leaves the component every running 
task
    depends on for heartbeats, state transitions and XComs with no per-request
    telemetry, which is the primary signal for diagnosing heartbeat stalls.
    
    Both server backends disable their own access logger, and the built-in 
access
    loggers are muted in the logging config, all on the premise that
    HttpAccessLogMiddleware handles access logging. That premise only held 
while the
    middleware was installed by the core app branch, so no configuration could
    recover the records. Installing it for every apps selection makes the 
premise
    true again instead of adding a fourth conditional that would give 
execution-only
    deployments a different log format from every other deployment.
    
    * Lock in HttpAccessLog outermost ordering with a positional assertion
    
    * Trim redundant caveat from init_middlewares ordering note
    
    ---------
    
    Co-authored-by: pierrejeambrun <[email protected]>
---
 airflow-core/src/airflow/api_fastapi/app.py          |  8 ++++++++
 airflow-core/src/airflow/api_fastapi/core_api/app.py |  8 +++-----
 airflow-core/tests/unit/api_fastapi/test_app.py      | 13 +++++++++++++
 3 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/airflow-core/src/airflow/api_fastapi/app.py 
b/airflow-core/src/airflow/api_fastapi/app.py
index 55ec201b9ee..524cb32cac2 100644
--- a/airflow-core/src/airflow/api_fastapi/app.py
+++ b/airflow-core/src/airflow/api_fastapi/app.py
@@ -29,6 +29,7 @@ from starlette.middleware import Middleware
 
 from airflow.api_fastapi.common.dagbag import create_dag_bag
 from airflow.api_fastapi.common.exceptions import init_error_handlers
+from airflow.api_fastapi.common.http_access_log import HttpAccessLogMiddleware
 from airflow.api_fastapi.core_api.app import (
     init_config,
     init_flask_plugins,
@@ -152,6 +153,8 @@ def create_app(apps: str = "all") -> FastAPI:
         init_error_handlers(app)
         init_middlewares(app)
 
+    init_access_logging(app)
+
     init_config(app)
 
     return app
@@ -219,6 +222,11 @@ def get_auth_manager() -> BaseAuthManager:
     return _AuthManagerState.instance
 
 
+def init_access_logging(app: FastAPI) -> None:
+    """Install the access log middleware, the only producer of access 
records."""
+    app.add_middleware(HttpAccessLogMiddleware)
+
+
 def init_plugins(app: FastAPI) -> None:
     """Integrate FastAPI app, middlewares and UI plugins."""
     from airflow import plugins_manager
diff --git a/airflow-core/src/airflow/api_fastapi/core_api/app.py 
b/airflow-core/src/airflow/api_fastapi/core_api/app.py
index 8ceea05828b..eac48ccbd7c 100644
--- a/airflow-core/src/airflow/api_fastapi/core_api/app.py
+++ b/airflow-core/src/airflow/api_fastapi/core_api/app.py
@@ -175,7 +175,6 @@ def init_config(app: FastAPI) -> None:
 def init_middlewares(app: FastAPI) -> None:
     from airflow.api_fastapi.app import get_auth_manager
     from airflow.api_fastapi.auth.middlewares.refresh_token import 
JWTRefreshMiddleware
-    from airflow.api_fastapi.common.http_access_log import 
HttpAccessLogMiddleware
 
     app.add_middleware(JWTRefreshMiddleware)
 
@@ -183,9 +182,8 @@ def init_middlewares(app: FastAPI) -> None:
         app.add_middleware(middleware_cls, **middleware_kwargs)
 
     # GZipMiddleware must be inside HttpAccessLogMiddleware so that access 
logs capture
-    # the full end-to-end duration including compression time.
+    # the full end-to-end duration including compression time. 
HttpAccessLogMiddleware is
+    # installed by ``init_access_logging`` in ``create_app``, which runs after 
this
+    # function — do not reorder those calls.
     # See https://github.com/apache/airflow/issues/60165
     app.add_middleware(GZipMiddleware, minimum_size=1024, compresslevel=5)
-    # HttpAccessLogMiddleware must be outermost (added last) so it times the 
full
-    # request lifecycle including all inner middleware.
-    app.add_middleware(HttpAccessLogMiddleware)
diff --git a/airflow-core/tests/unit/api_fastapi/test_app.py 
b/airflow-core/tests/unit/api_fastapi/test_app.py
index 26e505021da..19174592e65 100644
--- a/airflow-core/tests/unit/api_fastapi/test_app.py
+++ b/airflow-core/tests/unit/api_fastapi/test_app.py
@@ -24,6 +24,7 @@ from fastapi import FastAPI
 
 import airflow.api_fastapi.app as app_module
 import airflow.plugins_manager as plugins_manager
+from airflow.api_fastapi.common.http_access_log import HttpAccessLogMiddleware
 
 from tests_common.test_utils.config import conf_vars
 
@@ -88,6 +89,18 @@ def test_all_apps(mock_create_task_exec_api, 
mock_init_plugins, mock_init_views,
     mock_create_task_exec_api.assert_called_once_with()
 
 
[email protected]("apps", ["all", "core", "execution"])
+def 
test_access_log_middleware_installed_outermost_for_every_apps_selection(apps, 
client):
+    """Both server backends disable their own access logger, so a selection 
that skips this
+    middleware has no access logging at all. It must also stay outermost so it 
times the full
+    request including inner middlewares (GZip compression in particular — see 
#60165); the
+    test default config has no CORS so index 0 is HttpAccessLogMiddleware."""
+    installed = [m.cls for m in client(apps=apps).app.user_middleware]
+
+    assert installed.count(HttpAccessLogMiddleware) == 1
+    assert installed[0] is HttpAccessLogMiddleware
+
+
 def test_catch_all_route_last(client):
     """
     Ensure the catch all route that returns the initial html is the last route 
in the fastapi app.

Reply via email to