哪里是logging.config.dictConfig的完整示例?

如何使用dictConfig?我应该如何指定它的输入config字典?

99537 次浏览

这里怎么样!对应的文档引用是configuration-dictionary-schema

LOGGING_CONFIG = {
'version': 1,
'disable_existing_loggers': True,
'formatters': {
'standard': {
'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
},
},
'handlers': {
'default': {
'level': 'INFO',
'formatter': 'standard',
'class': 'logging.StreamHandler',
'stream': 'ext://sys.stdout',  # Default is stderr
},
},
'loggers': {
'': {  # root logger
'handlers': ['default'],
'level': 'WARNING',
'propagate': False
},
'my.packg': {
'handlers': ['default'],
'level': 'INFO',
'propagate': False
},
'__main__': {  # if __name__ == '__main__'
'handlers': ['default'],
'level': 'DEBUG',
'propagate': False
},
}
}

用法:

import logging.config


# Run once at startup:
logging.config.dictConfig(LOGGING_CONFIG)


# Include in each module:
log = logging.getLogger(__name__)
log.debug("Logging is configured.")

如果你看到太多来自第三方包的日志,请确保使用logging.config.dictConfig(LOGGING_CONFIG) 之前运行此配置,第三方包被导入。

要使用日志过滤器向每条日志消息添加额外的自定义信息,请考虑这个答案

公认的答案很好!但如果我们可以从不那么复杂的东西开始呢?日志模块是非常强大的东西,文档是有点压倒性的,特别是对于新手。但是一开始不需要配置格式化程序和处理程序。等你想好了再加吧。

例如:

import logging.config


DEFAULT_LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'loggers': {
'': {
'level': 'INFO',
},
'another.module': {
'level': 'DEBUG',
},
}
}


logging.config.dictConfig(DEFAULT_LOGGING)


logging.info('Hello, log')

我在下面找到了Django v1.11.15的默认配置,希望它能有所帮助

DEFAULT_LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse',
},
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
},
},
'formatters': {
'django.server': {
'()': 'django.utils.log.ServerFormatter',
'format': '[%(server_time)s] %(message)s',
}
},
'handlers': {
'console': {
'level': 'INFO',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
},
'django.server': {
'level': 'INFO',
'class': 'logging.StreamHandler',
'formatter': 'django.server',
},
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
}
},
'loggers': {
'django': {
'handlers': ['console', 'mail_admins'],
'level': 'INFO',
},
'django.server': {
'handlers': ['django.server'],
'level': 'INFO',
'propagate': False,
},
}
}

示例与流处理程序,文件处理程序,旋转文件处理程序和SMTP处理程序

from logging.config import dictConfig


LOGGING_CONFIG = {
'version': 1,
'loggers': {
'': {  # root logger
'level': 'NOTSET',
'handlers': ['debug_console_handler', 'info_rotating_file_handler', 'error_file_handler', 'critical_mail_handler'],
},
'my.package': {
'level': 'WARNING',
'propagate': False,
'handlers': ['info_rotating_file_handler', 'error_file_handler' ],
},
},
'handlers': {
'debug_console_handler': {
'level': 'DEBUG',
'formatter': 'info',
'class': 'logging.StreamHandler',
'stream': 'ext://sys.stdout',
},
'info_rotating_file_handler': {
'level': 'INFO',
'formatter': 'info',
'class': 'logging.handlers.RotatingFileHandler',
'filename': 'info.log',
'mode': 'a',
'maxBytes': 1048576,
'backupCount': 10
},
'error_file_handler': {
'level': 'WARNING',
'formatter': 'error',
'class': 'logging.FileHandler',
'filename': 'error.log',
'mode': 'a',
},
'critical_mail_handler': {
'level': 'CRITICAL',
'formatter': 'error',
'class': 'logging.handlers.SMTPHandler',
'mailhost' : 'localhost',
'fromaddr': 'monitoring@domain.com',
'toaddrs': ['dev@domain.com', 'qa@domain.com'],
'subject': 'Critical error with application name'
}
},
'formatters': {
'info': {
'format': '%(asctime)s-%(levelname)s-%(name)s::%(module)s|%(lineno)s:: %(message)s'
},
'error': {
'format': '%(asctime)s-%(levelname)s-%(name)s-%(process)d::%(module)s|%(lineno)s:: %(message)s'
},
},


}


dictConfig(LOGGING_CONFIG)

有一个更新的例子,声明logging.config.dictConfig() 字典模式隐藏在日志记录手册示例. config. dictconfig()中。从烹饪书链接向上滚动,查看dictConfig()的用法。

下面是一个将日志记录到stdout和“logs"子目录使用StreamHandler和RotatingFileHandler自定义formatdatefmt

  1. 导入模块并建立跨平台的绝对路径到"logs"子目录

    from os.path import abspath, dirname, join
    import logging
    from logging.config import dictConfig
    base_dir = abspath(dirname(__file__))
    logs_target = join(base_dir + "\logs", "python_logs.log")
    
  2. 根据字典模式文档建立模式。

    logging_schema = {
    # Always 1. Schema versioning may be added in a future release of logging
    "version": 1,
    # "Name of formatter" : {Formatter Config Dict}
    "formatters": {
    # Formatter Name
    "standard": {
    # class is always "logging.Formatter"
    "class": "logging.Formatter",
    # Optional: logging output format
    "format": "%(asctime)s\t%(levelname)s\t%(filename)s\t%(message)s",
    # Optional: asctime format
    "datefmt": "%d %b %y %H:%M:%S"
    }
    },
    # Handlers use the formatter names declared above
    "handlers": {
    # Name of handler
    "console": {
    # The class of logger. A mixture of logging.config.dictConfig() and
    # logger class-specific keyword arguments (kwargs) are passed in here.
    "class": "logging.StreamHandler",
    # This is the formatter name declared above
    "formatter": "standard",
    "level": "INFO",
    # The default is stderr
    "stream": "ext://sys.stdout"
    },
    # Same as the StreamHandler example above, but with different
    # handler-specific kwargs.
    "file": {
    "class": "logging.handlers.RotatingFileHandler",
    "formatter": "standard",
    "level": "INFO",
    "filename": logs_target,
    "mode": "a",
    "encoding": "utf-8",
    "maxBytes": 500000,
    "backupCount": 4
    }
    },
    # Loggers use the handler names declared above
    "loggers" : {
    "__main__": {  # if __name__ == "__main__"
    # Use a list even if one handler is used
    "handlers": ["console", "file"],
    "level": "INFO",
    "propagate": False
    }
    },
    # Just a standalone kwarg for the root logger
    "root" : {
    "level": "INFO",
    "handlers": ["file"]
    }
    }
    
  3. 用字典模式配置logging

    dictConfig(logging_schema)
    
  4. 尝试一些测试用例,看看是否一切都正常工作

    if __name__ == "__main__":
    logging.info("testing an info log entry")
    logging.warning("testing a warning log entry")
    

[编辑回答@baxx的问题]

  1. 要在代码库中重用此设置,请在调用dictConfig()的脚本中实例化一个记录器,然后将该记录器导入到其他地方

     # my_module/config/my_config.py
    dictConfig(logging_schema)
    my_logger = getLogger(__name__)
    

然后在另一个脚本中

    from my_module.config.my_config import my_logger as logger
logger.info("Hello world!")

还有一件事,如果从现有的记录器的配置开始是有用的,当前的配置字典是可以通过

import logging
logger = logging.getLogger()
current_config = logger.__dict__  # <-- yes, it's just the dict


print(current_config)

大概是这样的:

{'filters': [], 'name': 'root', 'level': 30, 'parent': None, 'propagate': True, 'handlers': [], 'disabled': False, '_cache': {}}

然后,如果你这样做

new_config=current_config


new_config['version']=1
new_config['name']='fubar'
new_config['level']=20
#  ...and whatever other changes you wish


logging.config.dictConfig(new_config)

你会发现:

print(logger.__dict__)

这是你所希望的吗

{'filters': [], 'name': 'fubar', 'level': 20, 'parent': None, 'propagate': True, 'handlers': [], 'disabled': False, '_cache': {}, 'version': 1}