Skip to content

Commit 6fe99cb

Browse files
committed
Fix check-default-configuration check and harden the error case
Root cause: providers_discovery.py used structlog.getLogger() directly. Before structlog.configure() is called (which happens later in settings.py:726), structlog's default PrintLogger writes to stdout with no level filtering. So debug logs during early provider discovery pollute the stdout of airflow config list --default, corrupting the generated config file. Fix: Switched to logging.getLogger() (stdlib). stdlib logging defaults to WARNING level and writes to stderr, so debug logs are suppressed and stdout stays clean. This is also the correct pattern for shared library code — structlog configuration is the application's responsibility.
1 parent ab2a76f commit 6fe99cb

2 files changed

Lines changed: 25 additions & 11 deletions

File tree

scripts/in_container/run_check_default_configuration.py

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,23 +36,37 @@
3636

3737
if __name__ == "__main__":
3838
with tempfile.TemporaryDirectory() as tmp_dir:
39+
# We need to explicitly set the logging level to ERROR to avoid debug logs from "airflow config lint" command that can spoil the output and make the test fail.
40+
# This is needed in case the default config has logging level set to DEBUG, but it does not hurt to set it explicitly in any case to avoid any unexpected debug logs from the command.
41+
env = os.environ.copy()
42+
env["AIRFLOW__LOGGING__LOGGING_LEVEL"] = "ERROR"
43+
3944
# Write default config cmd output to a temporary file
4045
default_config_file = os.path.join(tmp_dir, "airflow.cfg")
4146
with open(default_config_file, "w") as f:
42-
result = subprocess.run(list_default_config_cmd, check=False, stdout=f)
47+
result = subprocess.run(list_default_config_cmd, check=False, stdout=f, env=env)
4348
if result.returncode != 0:
4449
print(f"\033[0;31mERROR: when running `{' '.join(list_default_config_cmd)}`\033[0m\n")
50+
print(result.stdout.decode())
4551
exit(1)
4652
# Run airflow config lint to check the default config
47-
env = os.environ.copy()
4853
env["AIRFLOW_HOME"] = tmp_dir
4954
env["AIRFLOW_CONFIG"] = default_config_file
5055
result = subprocess.run(lint_config_cmd, check=False, capture_output=True, env=env)
5156

52-
output: str = result.stdout.decode().strip()
53-
if result.returncode != 0 or expected_output not in output:
54-
print(f"\033[0;31mERROR: when running `{' '.join(lint_config_cmd)}`\033[0m\n")
55-
print(output)
56-
exit(1)
57-
print(output)
58-
exit(0)
57+
output: str = result.stdout.decode().strip()
58+
if result.returncode != 0 or expected_output not in output:
59+
print(f"\033[0;31mERROR: when running `{' '.join(lint_config_cmd)}`\033[0m\n")
60+
print(output)
61+
# log the stderr as well if available
62+
if result.stderr:
63+
print(f"\033[0;31mERROR: stderr from `{' '.join(lint_config_cmd)}`\033[0m\n")
64+
print(result.stderr.decode())
65+
# log the default config that was generated for debugging
66+
print("\033[0;31mGenerated default config for debugging:\033[0m\n")
67+
with open(default_config_file) as f:
68+
print(f.read())
69+
exit(1)
70+
else:
71+
print(output)
72+
exit(0)

shared/providers_discovery/src/airflow_shared/providers_discovery/providers_discovery.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import contextlib
2323
import json
24+
import logging
2425
import pathlib
2526
from collections.abc import Callable, MutableMapping
2627
from dataclasses import dataclass
@@ -29,12 +30,11 @@
2930
from time import perf_counter
3031
from typing import Any, NamedTuple, ParamSpec, Protocol, cast
3132

32-
import structlog
3333
from packaging.utils import canonicalize_name
3434

3535
from ..module_loading import entry_points_with_dist
3636

37-
log = structlog.getLogger(__name__)
37+
log = logging.getLogger(__name__)
3838

3939

4040
PS = ParamSpec("PS")

0 commit comments

Comments
 (0)