python改变日志(logging)存放位置的示例
实现了简单版本的logging.config,支持一般的通过config文件进行配置。
感觉还有更好的方法,是直接利用logging.config.fileConfig(log_config_file)方式读进来之后,通过修改handler方式来进行修改。
代码如下:
"""
project trace system
"""
import sys
import ConfigParser
import logging
import logging.config
import warnings
if __name__ == "__main__":
log_config_file = "log.conf"
log_data_file = "logs/run.log"
LEVEL_dic = {
"DEBUG": logging.DEBUG,
"INFO": logging.INFO,
"WARNING": logging.WARNING,
"ERROR": logging.ERROR,
"CRITICAL": logging.CRITICAL
}
class LogConfig(object):
def __init__(self, log_config_file, log_data_file=None):
self.log_config_file = log_config_file
self.log_data_file = log_data_file # for self app
self.log_config = ConfigParser.RawConfigParser()
self.log_config.read(self.log_config_file)
self.logger_prefix = "logger_"
self.handler_prefix = "handler_"
self.formatter_prefix = "formatter_"
self._check_section()
self._parse_option()
def _check_section(self):
# check logger
self.__check_logger()
# check handler
self.__check_handler()
# check formatter
self.__check_formatter()
def _parse_option(self):
# parse formatter option
for formatter, formatter_info in self.formatters.items():
section_name = formatter_info["section_name"]
f = self.log_config.get(section_name, "format")
datefmt = self.log_config.get(section_name, "datefmt")
self.formatters[formatter]["value"] = logging.Formatter(f, datefmt)
# parse handlers
for handler, handler_info in self.handlers.items():
section_name = handler_info["section_name"]
handler_class = self.log_config.get(section_name, "class")
handler_str = self.log_config.get(section_name, "args")
handler_args = eval(self.log_config.get(section_name, "args"))
level = self.log_config.get(section_name, "level")
formatter = self.log_config.get(section_name, "formatter")
_handler = eval("logging."+handler_class)
# only FileHandler has file path paramter.
if isinstance(_handler, logging.FileHandler):
if self.log_data_file:
handler_args[0] = self.log_data_file
else:
warnings.warn("fileHandler found, but log data file is not specified")
self.handlers[handler]["value"] = _handler(*handler_args)
self.handlers[handler]["value"].setLevel(
LEVEL_dic.get(level.upper(), LEVEL_dic["INFO"]))
self.handlers[handler]["value"].setFormatter(
self.formatters[formatter]["value"])
# parse logger
for logger, logger_info in self.loggers.items():
section_name = logger_info["section_name"]
self.__parse_logger(logger, section_name)
def __parse_logger(self, logger_name, section_name):
"""
"""
tuple_items = self.log_config.items(section_name)
logger = logging.getLogger(logger_name)
for k, v in tuple_items:
if k == "handlers":
handlers = filter(None, [h.strip() for h in v.split(",")])
for h in handlers:
logger.addHandler(self.handlers[h]["value"])
if k == "level":
logger.setLevel(LEVEL_dic.get(v, LEVEL_dic["INFO"]))
if k == "propagate" and v:
logger.propagate = int(v)
# here other attributes could be added. TODO
self.loggers[logger_name]['value'] = logger
def __check_logger(self):
_loggers = self.log_config.get("loggers", "keys").split(",")
self.loggers = {}
for logger in _loggers:
logger = logger.strip()
if logger:
logger_section_name = self.logger_prefix + logger
if not self.log_config.has_section(logger_section_name):
raise Exception(
"ERROR: no logger section name: {0}".format(logger_section_name))
self.loggers.setdefault(logger, {})
self.loggers[logger]["section_name"] = logger_section_name
if not self.loggers:
raise Exception(
"ERROR: No logger keys in {0}".format(self.log_config_file))
def __check_handler(self):
_handlers = self.log_config.get("handlers", "keys").split(",")
self.handlers = {}
for handler in _handlers:
handler = handler.strip()
if handler:
handler_section_name = self.handler_prefix + handler
if not self.log_config.has_section(handler_section_name):
raise Exception("ERROR: no handler section name: {0}".format(handler_section_name))
self.handlers.setdefault(handler , {})
self.handlers[handler]["section_name"] = handler_section_name
if not self.handlers:
raise Exception("ERROR: No handler keys in {0}".format(self.log_config_file))
def __check_formatter(self):
_formatters = self.log_config.get("formatters", "keys").split(",")
self.formatters = {}
for formatter in _formatters:
formatter = formatter.strip()
if formatter:
formatter_section_name = self.formatter_prefix + formatter
if not self.log_config.has_section(formatter_section_name):
raise Exception("ERROR: no formatter section name: {0}".format(formatter_section_name))
self.formatters.setdefault(formatter, {})
self.formatters[formatter]["section_name"] = formatter_section_name
if not self.formatters:
raise Exception("ERROR: No formatter keys in {0}".format(self.log_config_file))
def getLogger(self, logger_name="root"):
return self.loggers[logger_name]['value']
class Trace(object):
def __init__(self, log_config_file, log_key="root", log_data_file=None):
self.log_config_file = log_config_file
self.log_data_file = log_data_file
self.log_key = log_key
Log = LogConfig(self.log_config_file, self.log_data_file)
self.logger = Log.getLogger(self.log_key)
def info(self, key, info):
self.logger.info("[{0}]: {1}".format(key, info))
def error(self, key, err_info):
self.logger.error("[{0}]: {1}".format(key, err_info))
def warn(self, key, warn_info):
self.logger.warn("[{0}]: {1}".format(key, warn_info))
def test():
log_key = "root"
t = Trace(log_config_file, log_key, log_data_file)
t.info("TEST TRACE", "OK")
if __name__ == "__main__":
test()
log.conf
代码如下:
[loggers]
keys = root, debug
[handlers]
keys=consoleHandler, timedRotatingFileHandler
[formatters]
keys=simpleFormatter
[logger_root]
level=DEBUG
handlers=consoleHandler, timedRotatingFileHandler
[logger_debug]
level=DEBUG
handlers=consoleHandler
propagate=0
[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)
[handler_timedRotatingFileHandler]
class=handlers.TimedRotatingFileHandler
level=DEBUG
formatter=simpleFormatter
args=("./run.log", 'midnight', 1, 10)
[formatter_simpleFormatter]
format=[%(asctime)s][%(levelname)s][%(process)d:%(thread)d][%(filename)s:%(lineno)d]:%(message)s
datefmt=%Y-%m-%d %H:%M:%S

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

win10的日志可以帮助用户详细的了解系统使用情况,很多的用户在寻找自己的管理日志的时候,肯定都遇到过日志6013吧,那么这个代码的意思是什么呢,下面就来介绍一下。win10日志6013是什么:1、这个是正常的日志。这个日志的信息并不是表示你的计算机重启了,而是说明自从上次启动以来,系统运行了多长的时间了。该日志会每天12点整出现一次。如何查看系统运行多长时间了,可以在cmd中输入systeminfo。其中有一行就是。

作用是:给工程师们反馈使用信息与记录便于分析问题(开发时使用的);由于用户本身不是经常产生上传日志,所以对用户无用。日志记录缓冲区是小型的、用于短期存储将写入到磁盘上的重做日志的变更向量的临时区域。日志缓冲区对磁盘的一次写入是来自多个事务的一批变更向量。即使如此,日志缓冲区中的变更向量也是接近实时地写入磁盘,当会话发出COMMIT语句时,会实时执行日志缓冲区写操作。

win10的日志可以帮助用户详细的了解系统使用情况,很多的用户在寻找自己的管理日志的时候,肯定都看到过很多的错误日志吧,那么该怎么解决他们呢,下面就一起来看看吧。win10日志事件7034怎么解决:1、点击“开始”打开“控制面板”2、找到“管理工具”3、点击“服务”4、找到HDZBCommServiceForV2.0右击“停止服务”,并改为“手动启动”

随着互联网和Web应用的迅猛发展,日志管理越来越重要。在开发Web应用时,如何查找和定位问题是一个非常关键的问题。日志系统是一种非常有效的工具,可以帮助我们实现这些任务。ThinkPHP6提供了一个强大的日志系统,可以帮助应用程序开发人员更好地管理和跟踪应用程序中发生的事件。本文将介绍如何在ThinkPHP6中使用日志系统,以及如何利用日志系统

iPhone可让您在“健康”App中添加药物,以便跟踪和管理您每天服用的药物、维生素和补充剂。然后,您可以在设备上收到通知时记录已服用或跳过的药物。记录用药后,您可以查看您服用或跳过用药的频率,以帮助您跟踪自己的健康状况。在这篇文章中,我们将指导您在iPhone上的健康应用程序中查看所选药物的日志历史记录。如何在“健康”App中查看用药日志历史记录简短指南:前往“健康”App>浏览“>用药”>用药“>选择一种用药>”选项“&a

在Linux系统中,可以使用以下命令来查看日志文件的内容:tail命令:tail命令用于显示日志文件的末尾内容。它是查看最新日志信息的常用命令。tail[选项][文件名]常用的选项包括:-n:指定要显示的行数,默认为10行。-f:实时监视文件内容,并在文件更新时自动显示新的内容。示例:tail-n20logfile.txt#显示logfile.txt文件的最后20行内容tail-flogfile.txt#实时监视logfile.txt文件的更新内容head命令:head命令用于显示日志文件的开头

win10的日志有着很多丰富的内容,很多的用户在寻找自己的管理日志的时候,肯定都见到过事件ID455显示错误,那么它到底是什么意思呢,下面就一起来看看。win10日志中事件ID455是什么:1、ID455是信息存储打开日志文件时<文件>发生的错误<错误>

Linux日志文件种类及配置方法在Linux系统中,日志文件是非常重要的,它记录了系统的运行状态、用户的操作以及各种事件的发生情况。通过查看日志文件,系统管理员可以及时发现问题并进行相应的处理。本文将介绍Linux系统中常见的日志文件种类及如何配置日志记录。一、日志文件种类系统日志:系统日志是记录系统运行状态的日志文件,包括系统启动、关机、服务启动和停止等信
