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实现获取域名所用服务器的真实IP
Oct 25 Python
简单解决Python文件中文编码问题
Nov 22 Python
基于Django用户认证系统详解
Feb 21 Python
python如何通过twisted实现数据库异步插入
Mar 20 Python
Python3多线程基础知识点
Feb 19 Python
python实践项目之监控当前联网状态详情
May 23 Python
Python初学者常见错误详解
Jul 02 Python
Python字符串格式化常用手段及注意事项
Jun 17 Python
python3.7添加dlib模块的方法
Jul 01 Python
django表单中的按钮获取数据的实例分析
Jul 31 Python
关于python中模块和重载的问题
Nov 02 Python
Python使用Web框架Flask开发项目
Jun 01 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 上传文件类型判断函数(避免上传漏洞 )
2010/06/08 PHP
php多种形式发送邮件(mail qmail邮件系统 phpmailer类)
2014/01/22 PHP
PHP把空格、换行符、中文逗号等替换成英文逗号的正则表达式
2014/05/04 PHP
PHP微信开发之有道翻译
2016/06/23 PHP
thinkPHP简单调用函数与类库的方法
2017/03/15 PHP
php判断文件上传图片格式的实例详解
2017/09/30 PHP
PHP实现动态添加XML中数据的方法
2018/03/30 PHP
为你的 Laravel 验证器加上多验证场景的实现
2020/04/07 PHP
js 绑定带参数的事件以及手动触发事件
2010/04/27 Javascript
jQuery中has()方法用法实例
2015/01/06 Javascript
jquery获取checkbox的值并post提交
2015/01/14 Javascript
JavaScript精炼之构造函数 Constructor及Constructor属性详解
2015/11/05 Javascript
JavaScript下的时间格式处理函数Date.prototype.format
2016/01/27 Javascript
使用jQuery或者原生js实现鼠标滚动加载页面新数据
2016/03/06 Javascript
ES6 迭代器(Iterator)和 for.of循环使用方法学习(总结)
2018/02/08 Javascript
JavaScript设计模式之单例模式简单实例教程
2018/07/02 Javascript
elementUI Tree 树形控件的官方使用文档
2019/04/25 Javascript
javascript设计模式 ? 抽象工厂模式原理与应用实例分析
2020/04/09 Javascript
详解Vue2的diff算法
2021/01/06 Vue.js
[03:28]2014DOTA2国际邀请赛 走近EG战队天才中单Arteezy
2014/07/12 DOTA
python获取标准北京时间的方法
2015/03/24 Python
Python探索之Metaclass初步了解
2017/10/28 Python
Python实现的归并排序算法示例
2017/11/21 Python
Python2和Python3之间的str处理方式导致乱码的讲解
2019/01/03 Python
Python MongoDB 插入数据时已存在则不执行,不存在则插入的解决方法
2019/09/24 Python
命令行运行Python脚本时传入参数的三种方式详解
2019/10/11 Python
numpy中三维数组中加入元素后的位置详解
2019/11/28 Python
pandas抽取行列数据的几种方法
2020/12/13 Python
Python实现Kerberos用户的增删改查操作
2020/12/14 Python
HTML5 Canvas玩转酷炫大波浪进度图效果实例(附demo)
2016/12/14 HTML / CSS
荷兰家电购物网站:Expert.nl
2020/01/18 全球购物
C#中有没有静态构造函数,如果有是做什么用的?
2016/06/04 面试题
大一新生期末自我评价
2014/09/12 职场文书
简易版租房协议书范本
2014/10/13 职场文书
2015年劳动部工作总结
2015/05/23 职场文书
Python OpenCV超详细讲解调整大小与图像操作的实现
2022/04/02 Python