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的发展史
Sep 26 Python
详解Django缓存处理中Vary头部的使用
Jul 24 Python
python中的错误处理
Apr 10 Python
python随机取list中的元素方法
Apr 08 Python
Python 删除整个文本中的空格,并实现按行显示
Jul 24 Python
Python读取实时数据流示例
Dec 02 Python
关于sys.stdout和print的区别详解
Dec 05 Python
opencv3/C++实现视频读取、视频写入
Dec 11 Python
python模拟点击网页按钮实现方法
Feb 25 Python
python中format函数如何使用
Jun 22 Python
教你怎么用Python处理excel实现自动化办公
Apr 30 Python
用Python爬虫破解滑动验证码的案例解析
May 06 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获取从百度搜索进入网站的关键词的详细代码
2014/01/08 PHP
实现PHP多线程异步请求的3种方法
2014/01/17 PHP
PHP经典算法集锦【经典收藏】
2016/09/14 PHP
php通过pecl方式安装扩展的实例讲解
2018/02/02 PHP
让ie运行js时提示允许阻止内容运行的解决方法
2010/10/24 Javascript
ASP.NET MVC中EasyUI的datagrid跨域调用实现代码
2012/03/14 Javascript
js的回调函数详解
2015/01/05 Javascript
原生JS实现LOADING效果
2015/03/16 Javascript
JavaScript实现简单图片翻转的方法
2015/04/17 Javascript
谈一谈javascript闭包
2016/01/28 Javascript
Javascript单例模式的介绍和实例
2016/10/08 Javascript
JavaScript、C# URL编码、解码总结
2017/01/21 Javascript
Angular2下使用pdf插件的方法详解
2017/04/29 Javascript
解决vue 打包发布去#和页面空白的问题
2018/09/04 Javascript
利用weixin-java-miniapp生成小程序码并直接返回图片文件流的方法
2019/03/29 Javascript
微信小程序用户授权弹窗 拒绝时引导用户重新授权实现
2019/07/29 Javascript
在vue中阻止浏览器后退的实例
2019/11/06 Javascript
微信小程序基于movable-view实现滑动删除效果
2020/01/08 Javascript
简单了解three.js 着色器材质
2020/08/03 Javascript
vue v-model的用法解析
2020/10/19 Javascript
python九九乘法表的实例
2017/09/26 Python
python3正则提取字符串里的中文实例
2019/01/31 Python
django2.0扩展用户字段示例
2019/02/13 Python
Pyqt5 实现跳转界面并关闭当前界面的方法
2019/06/19 Python
在IE6系列等老式浏览器中使用HTML5的新标签实现方案
2012/12/25 HTML / CSS
html svg生成环形进度条的实现方法
2019/09/23 HTML / CSS
美国著名的家居用品购物网站:Bed Bath & Beyond
2018/01/05 全球购物
Wiggle新西兰:自行车、跑步、游泳
2020/05/06 全球购物
Shell编程面试题
2012/05/30 面试题
销售员自我评价怎么写
2013/09/19 职场文书
大学生职业生涯规划书前言
2014/01/09 职场文书
运动会口号8字
2014/06/07 职场文书
看古人们是如何赞美老师的?
2019/07/08 职场文书
CocosCreator ScrollView优化系列之分帧加载
2021/04/14 Python
只用20行Python代码实现屏幕录制功能
2021/06/02 Python
sql时间段切分实现每隔x分钟出一份高速门架车流量
2022/02/28 SQL Server