python改变日志(logging)存放位置的示例
发布时间:2023-07-04 06:37:58
实现了简单版本的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


猜你喜欢
- 前言如果想分布式执行用例,用例设计必须遵循以下原则:1、用例之间都是独立的,2、用例a不要去依赖用例b3、用例执行没先后顺序,4、随机都能执
- 1.首先引入import { Toast } from 'vant'写个小列子绑定一个click事件2.写事件在method
- 利用三元运算符实现登录注册效果切换,供大家参考,具体内容如下直接上代码wxml:<view class='top'&g
- 在师兄的推荐下入坑vue.js ,发现不知如何运行GitHub上的开源项目,很尴尬。通过查阅网上教程,成功搭建好项目环境,同时对前段工程化有
- Step 1. 获取混淆矩阵#首先定义一个 分类数*分类数 的空混淆矩阵 conf_matrix = torch.zeros(Emotion
- 废话不多说,直接上代码吧!#python中,while语句用于循环执行程序,即在某个条件下,循环执行某段程序,以处理需要重复处理的相同任务。
- driver = webdriver.Chrome()报错driver = webdriver.Chrome()是因为没有chromedri
- 一、前言在Python提供了强大的模块支持,主要体现为不仅在Python标准库中包含了大量的模块(称为标准模块),而且还有很多第三方模块,另
- 简介最近在整理我们项目代码的时候,发现有很多活动的代码在结构和提供的功能上都非常相似。为了方便今后的开发,我花了一点时间编写了一个生成代码框
- 常见到网上博文有错误理论,包括身边很多朋友都曾认同“可访问性(Accessibility)是为残障人士准备”的观点。其实在互联网技术领域远不
- 一、安装pip install pymysql二、连接数据库三种连接数据库的方式import pymysql# 方式一conn = pymy
- 以下所有代码全是在<head>...</head>之间,具体内容有:1,<title>…</tit
- 目录项目地址:简介使用主要代码项目地址:https://github.com/king-xw/Face_Recogntion简介本仓库是使用
- 然而有些情况只需要传递几个文件,而且文件体积并不太大,这种情况下使用组件则有点牛刀杀鸡的感觉,通过html自带的<input type
- 随着网络的普及,基于网络的应用也越来越多。网络数据库就是其中之一。通过一台或几台服务器可以为很多客户提供服务,这种方式给人们带来了很多方便,
- PostgreSQL是一种特性非常齐全的自由软件的对象-关系型数据库管理系统(ORDBMS),是以加州大学计算机系开发的POSTGRES,4
- 本文借用HTML的css语法,将样式表应用到窗口部件。这里只是个简单的例子,实际上样式表的语法很丰富。以下类似于css: StyleShee
- 一、预备知识1.1、JS数据类型基本数据类型:Boolean、String、Number、null、undefined引用数据类型:Obje
- 看了下函数本身的docgetattr(object, name[, default]) -> valueGet a named att
- asp之家注:本文介绍的长文章分页方法不错,作者分析的很详细,用分页符来手动为长文章分页,应该是最好的长文章分页方法,我们不必担心会把一些代