This is an automated email from the ASF dual-hosted git repository.
vatsrahul1001 pushed a commit to branch v3-3-test
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/v3-3-test by this push:
new 7e13aaa1be5 [v3-3-test] Fix missing HTTP access logs when api-server
omits the core app (#72026) (#72808)
7e13aaa1be5 is described below
commit 7e13aaa1be52a5457ef46a4e9e879079c74c5879
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Thu Sep 10 13:29:00 2026 +0530
[v3-3-test] Fix missing HTTP access logs when api-server omits the core app
(#72026) (#72808)
* 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
---------
(cherry picked from commit 860233f3c72dcc3637c43c64223e57e078c84d55)
Co-authored-by: manish1337 <[email protected]>
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 233965bd56e..d180cb7ca17 100644
--- a/airflow-core/src/airflow/api_fastapi/app.py
+++ b/airflow-core/src/airflow/api_fastapi/app.py
@@ -28,6 +28,7 @@ from fastapi.routing import Mount
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,
@@ -151,6 +152,8 @@ def create_app(apps: str = "all") -> FastAPI:
init_error_handlers(app)
init_middlewares(app)
+ init_access_logging(app)
+
init_config(app)
return app
@@ -218,6 +221,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 961f13fbc71..63280e1ba81 100644
--- a/airflow-core/src/airflow/api_fastapi/core_api/app.py
+++ b/airflow-core/src/airflow/api_fastapi/core_api/app.py
@@ -173,7 +173,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)
@@ -181,9 +180,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 9fd9a3edad1..5c65fb772c6 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
pytestmark = pytest.mark.db_test
@@ -86,6 +87,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.