This is an automated email from the ASF dual-hosted git repository.
potiuk pushed a commit to branch v2-11-test
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/v2-11-test by this push:
new 996c7408021 [v2-11-test] Move use_historical_filename_templates from
core to logging section (#62647)
996c7408021 is described below
commit 996c74080210dfb8892513cbde9977a94f417f4d
Author: Jarek Potiuk <[email protected]>
AuthorDate: Sat Feb 28 22:31:46 2026 +0100
[v2-11-test] Move use_historical_filename_templates from core to logging
section (#62647)
* Move use_historical_filename_templates from core to logging section
The option was defined in [logging] in config.yml but read from [core]
in code. Move code references to [logging] and deprecate [core] location
so existing configs still work with a deprecation warning.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* Add test for deprecated core.use_historical_filename_templates
Verify that reading from the old [core] section triggers a
DeprecationWarning, both via environment variable and config file.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* Rename newsfragment to match PR number 62647
Co-Authored-By: Claude Opus 4.6 <[email protected]>
---------
Co-authored-by: Claude Opus 4.6 <[email protected]>
---
airflow/configuration.py | 5 ++++
airflow/models/dagrun.py | 2 +-
newsfragments/62647.bugfix.rst | 1 +
tests/core/test_configuration.py | 36 ++++++++++++++++++++++++++
tests/utils/log/test_file_processor_handler.py | 2 +-
tests/utils/log/test_log_reader.py | 10 +++----
tests/utils/test_log_handlers.py | 4 +--
tests/www/views/test_views_log.py | 2 +-
8 files changed, 52 insertions(+), 10 deletions(-)
diff --git a/airflow/configuration.py b/airflow/configuration.py
index fdb8e3821dd..55c314e76e0 100644
--- a/airflow/configuration.py
+++ b/airflow/configuration.py
@@ -375,6 +375,11 @@ class AirflowConfigParser(ConfigParser):
"2.0.0",
),
("logging", "task_log_reader"): ("core", "task_log_reader", "2.0.0"),
+ ("logging", "use_historical_filename_templates"): (
+ "core",
+ "use_historical_filename_templates",
+ "2.11.2",
+ ),
("metrics", "metrics_allow_list"): ("metrics", "statsd_allow_list",
"2.6.0"),
("metrics", "metrics_block_list"): ("metrics", "statsd_block_list",
"2.6.0"),
("metrics", "statsd_on"): ("scheduler", "statsd_on", "2.0.0"),
diff --git a/airflow/models/dagrun.py b/airflow/models/dagrun.py
index 224f7b79ed7..89d1da128e5 100644
--- a/airflow/models/dagrun.py
+++ b/airflow/models/dagrun.py
@@ -1655,7 +1655,7 @@ class DagRun(Base, LoggingMixin):
def get_log_template(
self, session: Session = NEW_SESSION
) -> LogTemplate | LogTemplatePydantic | LogTemplateDataClass:
- if airflow_conf.getboolean("core",
"use_historical_filename_templates", fallback=False):
+ if airflow_conf.getboolean("logging",
"use_historical_filename_templates", fallback=False):
return self.get_db_log_template(session=session)
else:
return LogTemplateDataClass(
diff --git a/newsfragments/62647.bugfix.rst b/newsfragments/62647.bugfix.rst
new file mode 100644
index 00000000000..3ff5b13d9c8
--- /dev/null
+++ b/newsfragments/62647.bugfix.rst
@@ -0,0 +1 @@
+In 2.11.1 by mistake ``core.use_historical_filename_templates`` was read by
Airflow instead of ``logging.use_historical_filename_templates``. The ``core``
option is deprecated in Airflow 2.11.2. Both options are removed in Airflow 3
as historical templates are supported and does not cause low-severity security
issue in Airflow 3.
diff --git a/tests/core/test_configuration.py b/tests/core/test_configuration.py
index cceef50a313..1b2d6ffe8c1 100644
--- a/tests/core/test_configuration.py
+++ b/tests/core/test_configuration.py
@@ -1023,6 +1023,42 @@ class TestDeprecatedConf:
with pytest.warns(DeprecationWarning), conf_vars({("core",
"logging_level"): "VALUE"}):
assert conf.get("logging", "logging_level") == "VALUE"
+ @conf_vars(
+ {
+ ("logging", "use_historical_filename_templates"): None,
+ ("core", "use_historical_filename_templates"): None,
+ }
+ )
+ def test_deprecated_use_historical_filename_templates(self):
+ """Test that core.use_historical_filename_templates is deprecated in
favor of logging section."""
+ with set_deprecated_options(
+ deprecated_options={
+ ("logging", "use_historical_filename_templates"): (
+ "core",
+ "use_historical_filename_templates",
+ "2.11.2",
+ )
+ }
+ ):
+ conf.remove_option("core", "use_historical_filename_templates")
+ conf.remove_option("logging", "use_historical_filename_templates")
+
+ with pytest.warns(DeprecationWarning):
+ with mock.patch.dict("os.environ",
AIRFLOW__CORE__USE_HISTORICAL_FILENAME_TEMPLATES="True"):
+ assert conf.get("logging",
"use_historical_filename_templates") == "True"
+
+ with pytest.warns(
+ DeprecationWarning,
+ match=r"The use_historical_filename_templates option in
\[core\]",
+ ):
+ with mock.patch.dict("os.environ",
AIRFLOW__CORE__USE_HISTORICAL_FILENAME_TEMPLATES="True"):
+ assert conf.get("core",
"use_historical_filename_templates") == "True"
+
+ with pytest.warns(DeprecationWarning), conf_vars(
+ {("core", "use_historical_filename_templates"): "True"}
+ ):
+ assert conf.get("logging",
"use_historical_filename_templates") == "True"
+
@conf_vars(
{
("celery", "result_backend"): None,
diff --git a/tests/utils/log/test_file_processor_handler.py
b/tests/utils/log/test_file_processor_handler.py
index 9e7504e098d..38b0f8acb06 100644
--- a/tests/utils/log/test_file_processor_handler.py
+++ b/tests/utils/log/test_file_processor_handler.py
@@ -61,7 +61,7 @@ class TestFileProcessorHandler:
handler.set_context(filename=os.path.join(self.dag_dir, "logfile"))
assert os.path.exists(os.path.join(path, "logfile.log"))
- @conf_vars({("core", "use_historical_filename_templates"): "True"})
+ @conf_vars({("logging", "use_historical_filename_templates"): "True"})
def test_symlink_latest_log_directory(self):
handler = FileProcessorHandler(base_log_folder=self.base_log_folder,
filename_template=self.filename)
handler.dag_dir = self.dag_dir
diff --git a/tests/utils/log/test_log_reader.py
b/tests/utils/log/test_log_reader.py
index 6e9bd2d3ca8..8294e83b4fe 100644
--- a/tests/utils/log/test_log_reader.py
+++ b/tests/utils/log/test_log_reader.py
@@ -120,7 +120,7 @@ class TestLogView:
session.delete(log_template)
session.commit()
- @conf_vars({("core", "use_historical_filename_templates"): "True"})
+ @conf_vars({("logging", "use_historical_filename_templates"): "True"})
def test_test_read_log_chunks_should_read_one_try(self):
task_log_reader = TaskLogReader()
ti = copy.copy(self.ti)
@@ -138,7 +138,7 @@ class TestLogView:
]
assert metadatas == {"end_of_log": True, "log_pos": 13}
- @conf_vars({("core", "use_historical_filename_templates"): "True"})
+ @conf_vars({("logging", "use_historical_filename_templates"): "True"})
def test_test_read_log_chunks_should_read_all_files(self):
task_log_reader = TaskLogReader()
ti = copy.copy(self.ti)
@@ -154,7 +154,7 @@ class TestLogView:
assert f"try_number={i + 1}." in logs[i][0][1]
assert metadatas == {"end_of_log": True, "log_pos": 13}
- @conf_vars({("core", "use_historical_filename_templates"): "True"})
+ @conf_vars({("logging", "use_historical_filename_templates"): "True"})
def test_test_test_read_log_stream_should_read_one_try(self):
task_log_reader = TaskLogReader()
ti = copy.copy(self.ti)
@@ -166,7 +166,7 @@ class TestLogView:
" INFO - ::endgroup::\ntry_number=1.\n"
]
- @conf_vars({("core", "use_historical_filename_templates"): "True"})
+ @conf_vars({("logging", "use_historical_filename_templates"): "True"})
def test_test_test_read_log_stream_should_read_all_logs(self):
task_log_reader = TaskLogReader()
self.ti.state = TaskInstanceState.SUCCESS # Ensure mocked instance is
completed to return stream
@@ -266,7 +266,7 @@ class TestLogView:
mock_prop.return_value = True
assert task_log_reader.supports_external_link
- @conf_vars({("core", "use_historical_filename_templates"): "True"})
+ @conf_vars({("logging", "use_historical_filename_templates"): "True"})
def test_task_log_filename_unique(self, dag_maker):
"""Ensure the default log_filename_template produces a unique filename.
diff --git a/tests/utils/test_log_handlers.py b/tests/utils/test_log_handlers.py
index ab546332e3d..392b1b51487 100644
--- a/tests/utils/test_log_handlers.py
+++ b/tests/utils/test_log_handlers.py
@@ -589,7 +589,7 @@ class TestFileTaskLogHandler:
class TestFilenameRendering:
- @conf_vars({("core", "use_historical_filename_templates"): "True"})
+ @conf_vars({("logging", "use_historical_filename_templates"): "True"})
def test_python_formatting(self, create_log_template,
create_task_instance):
create_log_template("{dag_id}/{task_id}/{execution_date}/{try_number}.log")
filename_rendering_ti = create_task_instance(
@@ -624,7 +624,7 @@ class TestFilenameRendering:
rendered_filename = fth._render_filename(filename_rendering_ti, 42)
assert expected_filename == rendered_filename
- @conf_vars({("core", "use_historical_filename_templates"): "True"})
+ @conf_vars({("logging", "use_historical_filename_templates"): "True"})
def test_jinja_rendering(self, create_log_template, create_task_instance):
create_log_template("{{ ti.dag_id }}/{{ ti.task_id }}/{{ ts }}/{{
try_number }}.log")
filename_rendering_ti = create_task_instance(
diff --git a/tests/www/views/test_views_log.py
b/tests/www/views/test_views_log.py
index c2fa9bffd65..95ed5fd460c 100644
--- a/tests/www/views/test_views_log.py
+++ b/tests/www/views/test_views_log.py
@@ -299,7 +299,7 @@ def dag_run_with_log_filename(tis):
session.query(LogTemplate).filter(LogTemplate.id ==
log_template.id).delete()
-@conf_vars({("core", "use_historical_filename_templates"): "True"})
+@conf_vars({("logging", "use_historical_filename_templates"): "True"})
def test_get_logs_for_changed_filename_format_db(
log_admin_client, dag_run_with_log_filename, create_expected_log_file
):