def get_logging_config(verbosity: int): """Return a configuration dict usable with `logging.config.dictConfig`. :param verbosity: See `get_logging_level`. """ # Customise loggers and such depending on the environment. is_dev = is_dev_environment() # Build the configuration suitable for `dictConfig`. return { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'stdout': { 'format': DEFAULT_LOG_FORMAT, 'datefmt': DEFAULT_LOG_FORMAT_DATE, }, 'syslog': { 'format': '%(name)s: [%(levelname)s] %(message)s', }, }, 'handlers': { 'stdout': { 'class': 'logging.StreamHandler', 'stream': sys.__stdout__, 'formatter': 'stdout', }, 'syslog': { 'class': 'logging.handlers.SysLogHandler', 'facility': logging.handlers.SysLogHandler.LOG_DAEMON, 'address': get_syslog_address_path(), 'formatter': 'syslog', }, }, 'root': { 'level': get_logging_level(verbosity), 'handlers': ['stdout'], }, 'loggers': { # The `maas` logger is used to provide a "nice to read" log of # MAAS's toing and froings. It logs to syslog and syslog only in # production. In development environments it propagates only to # the root logger and does not go to syslog. 'maas': { 'level': get_logging_level(verbosity), 'handlers': [] if is_dev else ['syslog'], 'propagate': is_dev, }, # The `requests` and `urllib3` modules talk too much. 'requests': { 'level': get_logging_level(verbosity - 1), }, 'urllib3': { 'level': get_logging_level(verbosity - 1), }, # Keep `nose` relatively quiet in tests. 'nose': { 'level': get_logging_level(verbosity - 1), }, }, }
def get_logging_config(verbosity: int): """Return a configuration dict usable with `logging.config.dictConfig`. :param verbosity: See `get_logging_level`. """ # Customise loggers and such depending on the environment. is_dev = is_dev_environment() # Build the configuration suitable for `dictConfig`. return { "version": 1, "disable_existing_loggers": False, "formatters": { "stdout": { "format": DEFAULT_LOG_FORMAT, "datefmt": DEFAULT_LOG_FORMAT_DATE, }, "syslog": { "format": "%(name)s: [%(levelname)s] %(message)s" }, }, "handlers": { "stdout": { "class": "logging.StreamHandler", "stream": sys.__stdout__, "formatter": "stdout", }, "syslog": { "class": "provisioningserver.logger.MAASSysLogHandler", "facility": logging.handlers.SysLogHandler.LOG_DAEMON, "address": get_syslog_address_path(), "formatter": "syslog", }, }, "root": { "level": get_logging_level(verbosity), "handlers": ["stdout"], }, "loggers": { # The `maas` logger is used to provide a "nice to read" log of # MAAS's toing and froings. It logs to syslog and syslog only in # production. In development environments it propagates only to # the root logger and does not go to syslog. "maas": { "level": get_logging_level(verbosity), "handlers": [] if is_dev else ["syslog"], "propagate": is_dev, }, # The `requests` and `urllib3` modules talk too much. "requests": { "level": get_logging_level(verbosity - 1) }, "urllib3": { "level": get_logging_level(verbosity - 1) }, # Keep `nose` relatively quiet in tests. "nose": { "level": get_logging_level(verbosity - 1) }, }, }
def configure_django_logging(verbosity: int, mode: LoggingMode): """Do basic logging configuration for Django, if possible. Then destroy Django's ability to mess with logging configuration. We have to do this by monkey-patching because changing Django's settings at run-time is not supported. If Django is not installed this is a no-op. :param verbosity: See `get_logging_level`. :param mode: The mode in which to configure logging. See `LoggingMode`. """ try: from django.utils import log except ImportError: # Django not installed; nothing to be done. return # Django's default logging configuration is not great. For example it # wants to email request errors and security issues to the site admins, # but fails silently. Throw it all away. warn_unless( hasattr(log, "DEFAULT_LOGGING"), "No DEFAULT_LOGGING attribute found in Django; please investigate!", ) log.DEFAULT_LOGGING = {"version": 1, "disable_existing_loggers": False} # Prevent Django from meddling with `warnings`. There's no configuration # option for this so we have to get invasive. We also skip running-in # Django's default log configuration even though we threw it away already. def configure_logging(logging_config, logging_settings): """Reduced variant of Django's configure_logging.""" if logging_config is not None: logging_config_func = log.import_string(logging_config) logging_config_func(logging_settings) warn_unless( hasattr(log, "configure_logging"), "No configure_logging function found in Django; please investigate!", ) log.configure_logging = configure_logging # Outside of the development environment ensure that deprecation warnings # from Django are silenced. End users are _not_ interested in deprecation # warnings from Django. Developers are, however. if not is_dev_environment(): from django.utils.deprecation import RemovedInNextVersionWarning warnings.simplefilter("ignore", RemovedInNextVersionWarning)