python改变日志(logging)存放位置的示例


Posted in Python onMarch 27, 2014

实现了简单版本的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
Python 相关文章推荐
为Python的web框架编写MVC配置来使其运行的教程
Apr 30 Python
Windows中安装使用Virtualenv来创建独立Python环境
May 31 Python
Python中执行存储过程及获取存储过程返回值的方法
Oct 07 Python
Scrapy爬虫实例讲解_校花网
Oct 23 Python
关于python写入文件自动换行的问题
Jun 23 Python
python性能测量工具cProfile使用解析
Sep 26 Python
python读文件的步骤
Oct 08 Python
python 图片二值化处理(处理后为纯黑白的图片)
Nov 01 Python
python实现字符串和数字拼接
Mar 02 Python
Python如何使用vars返回对象的属性列表
Oct 17 Python
GitHub上值得推荐的8个python 项目
Oct 30 Python
python实现马丁策略回测3000只股票的实例代码
Jan 22 Python
使用python删除nginx缓存文件示例(python文件操作)
Mar 26 #Python
python实现ip查询示例
Mar 26 #Python
python fabric实现远程操作和部署示例
Mar 25 #Python
python基础教程之数字处理(math)模块详解
Mar 25 #Python
python操作摄像头截图实现远程监控的例子
Mar 25 #Python
python基础教程之字典操作详解
Mar 25 #Python
python基础教程之元组操作使用详解
Mar 25 #Python
You might like
php设计模式小结
2013/02/15 PHP
浅析SVN常见问题及解决方法
2013/06/21 PHP
md5 16位二进制与32位字符串相互转换示例
2013/12/30 PHP
php魔术变量用法实例详解
2014/11/13 PHP
简单PHP会话(session)说明介绍
2016/08/21 PHP
php使用json_decode后数字对象转换成了科学计数法的解决方法
2017/02/20 PHP
PHP数据库操作三:redis用法分析
2017/08/16 PHP
Laravel框架源码解析之反射的使用详解
2020/05/14 PHP
javascript HTMLEncode HTMLDecode的完整实例(兼容ie和火狐)
2009/06/02 Javascript
Javascript 匿名函数及其代码模式原理
2010/03/19 Javascript
JS模板实现方法
2013/04/03 Javascript
jquery获取div距离窗口和父级dv的距离示例
2013/10/10 Javascript
js实现iGoogleDivDrag模块拖动层拖动特效的方法
2015/03/04 Javascript
js实现带圆角的两级导航菜单效果代码
2015/08/24 Javascript
jQuery实现鼠标滑过点击事件音效试听
2015/08/31 Javascript
JavaScript操作XML/HTML比较常用的对象属性集锦
2015/10/30 Javascript
jQuery mobile 移动web(4)
2015/12/20 Javascript
使用JavaScript为Kindeditor自定义按钮增加Audio标签
2016/03/18 Javascript
jQuery.cookie.js实现记录最近浏览过的商品功能示例
2017/01/23 Javascript
浅谈Angular路由守卫
2017/08/26 Javascript
atom-design(Vue.js移动端组件库)手势组件使用教程
2019/05/16 Javascript
使用kbone解决Vue项目同时支持小程序问题
2019/11/08 Javascript
解决iview table组件里的 固定列 表格不自适应的问题
2020/11/13 Javascript
vue3自定义dialog、modal组件的方法
2021/01/04 Vue.js
[45:40]Ti4 冒泡赛第二天NEWBEE vs NaVi 1
2014/07/15 DOTA
[41:52]2018DOTA2亚洲邀请赛3月29日 小组赛A组 TNC VS OpTic
2018/03/30 DOTA
[01:02:30]Mineski vs Secret 2019国际邀请赛淘汰赛 败者组 BO3 第三场 8.22
2019/09/05 DOTA
跟老齐学Python之Import 模块
2014/10/13 Python
Python中文竖排显示的方法
2015/07/28 Python
python装饰器与递归算法详解
2016/02/18 Python
Python中import机制详解
2017/11/14 Python
使用python操作lmdb对数据读取的实例
2020/12/11 Python
Simons官方网站:加拿大时尚零售商
2020/02/20 全球购物
2015年体育部工作总结
2015/04/02 职场文书
详解Redis主从复制实践
2021/05/19 Redis
MySQL完整性约束的定义与实例教程
2021/05/30 MySQL