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中字符串和数字拼接报错的方法
Oct 23 Python
Python排序搜索基本算法之冒泡排序实例分析
Dec 09 Python
Python爬虫包BeautifulSoup实例(三)
Jun 17 Python
python3实现磁盘空间监控
Jun 21 Python
使用pip发布Python程序的方法步骤
Oct 11 Python
python爬取淘宝商品销量信息
Nov 16 Python
用Python识别人脸,人种等各种信息
Jul 15 Python
Pycharm 2020年最新激活码(亲测有效)
Sep 18 Python
Python模块/包/库安装的六种方法及区别
Feb 24 Python
PyQt5 QDockWidget控件应用详解
Aug 12 Python
python 自定义异常和主动抛出异常(raise)的操作
Dec 11 Python
python源文件的字符编码知识点详解
Mar 04 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调用VC编写的COM组件实例
2014/03/29 PHP
php去除头尾空格的2种方法
2015/03/16 PHP
在vs2010中调试javascript代码方法
2011/02/11 Javascript
jquery 插件学习(六)
2012/08/06 Javascript
JavaScript mapreduce工作原理简析
2012/11/25 Javascript
js调用后台servlet方法实例
2013/06/09 Javascript
多个$(document).ready()的执行顺序实例分析
2014/07/26 Javascript
jQuery实现在最后一个元素之前插入新元素的方法
2015/07/18 Javascript
详解React-Todos入门例子
2016/11/08 Javascript
jQuery插件echarts实现的多柱子柱状图效果示例【附demo源码下载】
2017/03/04 Javascript
微信小程序框架wepy之动态控制类名
2018/09/14 Javascript
浅析JavaScript异步代码优化
2019/03/18 Javascript
浅谈layui使用模板引擎动态渲染元素要注意的问题
2019/09/14 Javascript
JS数组的常用10种方法详解
2020/05/08 Javascript
解决vue项目router切换太慢问题
2020/07/19 Javascript
javascript实现雪花飘落效果
2020/08/19 Javascript
[03:49]显微镜下的DOTA2第十五期—VG登基之路完美团
2014/06/24 DOTA
[01:48:04]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Elephant BO3 第一场 2月7日
2021/03/11 DOTA
[59:00]DOTA2-DPC中国联赛 正赛 Ehome vs PSG.LGD BO3 第一场 3月7日
2021/03/11 DOTA
Python的Django框架使用入门指引
2015/04/15 Python
Python中扩展包的安装方法详解
2017/06/14 Python
tornado 多进程模式解析
2018/01/15 Python
Python 实现在文件中的每一行添加一个逗号
2018/04/29 Python
Python中asyncio模块的深入讲解
2019/06/10 Python
在pycharm中为项目导入anacodna环境的操作方法
2020/02/12 Python
python 中关于pycharm选择运行环境的问题
2020/10/31 Python
AmazeUI的下载配置与Helloworld的实现
2020/08/19 HTML / CSS
Ajax的工作原理
2015/12/04 面试题
学校岗位设置方案
2014/01/16 职场文书
《自选商场》教学反思
2014/02/14 职场文书
2014年“世界无车日”活动方案
2014/09/21 职场文书
个人借款协议书范本
2014/11/17 职场文书
法制工作总结2015
2015/07/23 职场文书
幼儿园体操比赛口号
2015/12/25 职场文书
2016年敬老月活动总结
2016/04/05 职场文书
Java面试题冲刺第十七天--基础篇3
2021/08/07 面试题