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利用OpenCV2实现人脸检测
Apr 16 Python
python3解析库pyquery的深入讲解
Jun 26 Python
在unittest中使用 logging 模块记录测试数据的方法
Nov 30 Python
Python 文本文件内容批量抽取实例
Dec 10 Python
不到40行代码用Python实现一个简单的推荐系统
May 10 Python
python and or用法详解
Jun 26 Python
Python多版本开发环境管理工具介绍
Jul 03 Python
jenkins配置python脚本定时任务过程图解
Oct 29 Python
Python统计时间内的并发数代码实例
Dec 28 Python
使用 Python 读取电子表格中的数据实例详解
Apr 17 Python
详解python中的异常捕获
Dec 15 Python
python通配符之glob模块的使用详解
Apr 24 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实现window平台的checkdnsrr函数
2015/05/27 PHP
php采集中国代理服务器网的方法
2015/06/16 PHP
php生成二维码图片方法汇总
2016/12/17 PHP
FCK调用方法..
2006/12/21 Javascript
基于jQuery的输入框无值自动显示指定数据的实现代码
2011/01/24 Javascript
js 字符串转化成数字的代码
2011/06/29 Javascript
jquery 设置元素相对于另一个元素的top值(实例代码)
2013/11/06 Javascript
node.js中的fs.rmdir方法使用说明
2014/12/16 Javascript
详解JavaScript ES6中的Generator
2015/07/28 Javascript
JS判断当前页面是否在微信浏览器打开的方法
2015/12/08 Javascript
对象题目的一个坑 理解Javascript对象
2015/12/22 Javascript
jquery实现可旋转可拖拽的文字效果代码
2016/01/27 Javascript
jQuery实现根据生日计算年龄 星座 生肖
2016/11/23 Javascript
微信小程序 数组中的push与concat的区别
2017/01/05 Javascript
基于Angularjs+mybatis实现二级评论系统(仿简书)
2017/02/13 Javascript
详解Angularjs 如何自定义Img的ng-load 事件
2017/02/15 Javascript
微信小程序异步API为Promise简化异步编程的操作方法
2018/08/14 Javascript
webpack中如何使用雪碧图的示例代码
2018/11/11 Javascript
Vue 通过公共字段,拼接两个对象数组的实例
2019/11/07 Javascript
如何利用JS将手机号中间四位变成*号
2020/09/29 Javascript
[01:20]PWL S2开团时刻第三期——团战可以输 蝙蝠必须死
2020/11/26 DOTA
[05:09]DOTA2-DPC中国联赛2月22日Recap集锦
2021/03/11 DOTA
Python下singleton模式的实现方法
2014/07/16 Python
在python中bool函数的取值方法
2018/11/01 Python
使用python实现mqtt的发布和订阅
2019/05/05 Python
python pycharm的安装及其使用
2019/10/11 Python
Python 代码调试技巧示例代码
2020/08/11 Python
Python filter()及reduce()函数使用方法解析
2020/09/05 Python
python 获取剪切板内容的两种方法
2020/11/28 Python
详解html5 shiv.js和respond.min.js
2018/01/24 HTML / CSS
医学检验专业大学生求职信
2013/11/18 职场文书
汽车检测与维修专业求职信
2014/07/04 职场文书
公司领导班子四风对照检查材料
2014/09/27 职场文书
2014收银员工作总结范文
2014/12/16 职场文书
培训简讯范文
2015/07/20 职场文书
jdbc使用PreparedStatement批量插入数据的方法
2021/04/27 MySQL