logging_config.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #
  2. # Licensed to the Apache Software Foundation (ASF) under one
  3. # or more contributor license agreements. See the NOTICE file
  4. # distributed with this work for additional information
  5. # regarding copyright ownership. The ASF licenses this file
  6. # to you under the Apache License, Version 2.0 (the
  7. # "License"); you may not use this file except in compliance
  8. # with the License. You may obtain a copy of the License at
  9. #
  10. # http://www.apache.org/licenses/LICENSE-2.0
  11. #
  12. # Unless required by applicable law or agreed to in writing,
  13. # software distributed under the License is distributed on an
  14. # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. # KIND, either express or implied. See the License for the
  16. # specific language governing permissions and limitations
  17. # under the License.
  18. from __future__ import annotations
  19. import logging
  20. import warnings
  21. from logging.config import dictConfig
  22. from airflow.configuration import conf
  23. from airflow.exceptions import AirflowConfigException
  24. from airflow.utils.module_loading import import_string
  25. log = logging.getLogger(__name__)
  26. def configure_logging():
  27. """Configure & Validate Airflow Logging."""
  28. logging_class_path = ""
  29. try:
  30. logging_class_path = conf.get("logging", "logging_config_class")
  31. except AirflowConfigException:
  32. log.debug("Could not find key logging_config_class in config")
  33. if logging_class_path:
  34. try:
  35. logging_config = import_string(logging_class_path)
  36. # Make sure that the variable is in scope
  37. if not isinstance(logging_config, dict):
  38. raise ValueError("Logging Config should be of dict type")
  39. log.info("Successfully imported user-defined logging config from %s", logging_class_path)
  40. except Exception as err:
  41. # Import default logging configurations.
  42. raise ImportError(f"Unable to load custom logging from {logging_class_path} due to {err}")
  43. else:
  44. logging_class_path = "airflow.config_templates.airflow_local_settings.DEFAULT_LOGGING_CONFIG"
  45. logging_config = import_string(logging_class_path)
  46. log.debug("Unable to load custom logging, using default config instead")
  47. try:
  48. # Ensure that the password masking filter is applied to the 'task' handler
  49. # no matter what the user did.
  50. if "filters" in logging_config and "mask_secrets" in logging_config["filters"]:
  51. # But if they replace the logging config _entirely_, don't try to set this, it won't work
  52. task_handler_config = logging_config["handlers"]["task"]
  53. task_handler_config.setdefault("filters", [])
  54. if "mask_secrets" not in task_handler_config["filters"]:
  55. task_handler_config["filters"].append("mask_secrets")
  56. # Try to init logging
  57. dictConfig(logging_config)
  58. except (ValueError, KeyError) as e:
  59. log.error("Unable to load the config, contains a configuration error.")
  60. # When there is an error in the config, escalate the exception
  61. # otherwise Airflow would silently fall back on the default config
  62. raise e
  63. validate_logging_config(logging_config)
  64. return logging_class_path
  65. def validate_logging_config(logging_config):
  66. """Validate the provided Logging Config."""
  67. # Now lets validate the other logging-related settings
  68. task_log_reader = conf.get("logging", "task_log_reader")
  69. logger = logging.getLogger("airflow.task")
  70. def _get_handler(name):
  71. return next((h for h in logger.handlers if h.name == name), None)
  72. if _get_handler(task_log_reader) is None:
  73. # Check for pre 1.10 setting that might be in deployed airflow.cfg files
  74. if task_log_reader == "file.task" and _get_handler("task"):
  75. warnings.warn(
  76. f"task_log_reader setting in [logging] has a deprecated value of {task_log_reader!r}, "
  77. "but no handler with this name was found. Please update your config to use task. "
  78. "Running config has been adjusted to match",
  79. DeprecationWarning,
  80. stacklevel=2,
  81. )
  82. conf.set("logging", "task_log_reader", "task")
  83. else:
  84. raise AirflowConfigException(
  85. f"Configured task_log_reader {task_log_reader!r} was not a handler of "
  86. f"the 'airflow.task' logger."
  87. )