2.7.配置logging的几种方式

目录:

1.1.logging日志用途(tcy)https://mp.csdn.net/postedit/95102043

1.2.logging日志流处理流程 https://blog.csdn.net/tcy23456/article/details/95102217

2.1.logging模块级函数        https: //mp.csdn.net/postedit/95102425

2.2.Logger类                       https://mp.csdn.net/postedit/95102590

2.3.Handler类                      https://mp.csdn.net/postedit/95102690

2.4.Formater类                    https://mp.csdn.net/postedit/95102834

2.5.Filter类                           https://mp.csdn.net/postedit/95103238

3.1.logging.basicConfig       https://mp.csdn.net/postedit/95103385

3.2.配置logging的几种方式 https://mp.csdn.net/postedit/95103602

4.1.日志切割                       https://mp.csdn.net/postedit/95103779

4.2.日志滚动和过期删除     https://mp.csdn.net/postedit/95103902

4.3.多模块调用logging        https://mp.csdn.net/postedit/95104089

4.4.日志类封装                    https://mp.csdn.net/postedit/95104392

4.5.用logging模块记录异常 https://mp.csdn.net/postedit/95104529

 

配置logging的几种方式


作为开发者,我们可以通过以下3中方式来配置logging:

  • 1)用Python代码显式创建loggers, handlers和formatters分别调用它们配置函数;
  • 2)创建日志配置文件,用fileConfig()函数来读取该文件的内容;
  • 3)创建配置信息dict,把它传递个dictConfig()函数;

logging.basicConfig()也属于第一种方式,只是对loggers, handlers和formatters函数进行封装。

配置二将配置信息和代码分离,降低日志维护成本,使得非开发人员也能够修改日志配置。

 

一、使用Python代码实现日志配置

# 创建一个日志器logger并设置其日志级别为DEBUG
logger = logging.getLogger('simple_logger')
logger.setLevel(logging.DEBUG)

# 创建一个流处理器handler并设置其日志级别为DEBUG
handler = logging.StreamHandler(sys.stdout)
handler.setLevel(logging.DEBUG)

# 创建一个格式器formatter并将其添加到处理器handler
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
handler.setFormatter(formatter)

# 为日志器logger添加上面创建的处理器handler
logger.addHandler(handler)

# 日志输出
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')

"""
2019-07-03 19:12:15,542 - simple_logger - DEBUG - debug message
2019-07-03 19:12:15,542 - simple_logger - INFO - info message
2019-07-03 19:12:15,542 - simple_logger - WARNING - warn message
2019-07-03 19:12:15,542 - simple_logger - ERROR - error message
2019-07-03 19:12:15,542 - simple_logger - CRITICAL - critical message
"""
 

二、用配置文件和fileConfig()函数实现日志配置

import logging.config

# 读取日志配置文件内容
logging.config.fileConfig('logging.conf')

# 创建一个日志器logger
logger = logging.getLogger('simpleExample')

# 日志输出
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')

配置文件logging.conf内容:(不能包含中文注释,可含英文注释)

[loggers]  #必须包含
keys=root,simpleExample #一定要包含root这个值

[handlers] #必须包含
keys=fileHandler,consoleHandler#handler名字列表,必须在配置文件中有对应的section定义

[formatters] #必须包含
keys=simpleFormatter

[logger_root] #指定日志器;必须指定level和handlers这两个option
level=DEBUG
handlers=fileHandler

[logger_simpleExample]#指定日志器
level=DEBUG #DEBUG、INFO、WARNING、ERROR、CRITICAL、NOTSET
(所有级别包括用户定义级别;系统会查找高层次logger来决定logger的有效level)
handlers=consoleHandler
qualname=simpleExample#非root logger来说qualname是必须;表示在logger层级中名字,在应用代码中通过这个名字得到logger
propagate=0 #可选项,其默认是为1,表示消息将会传递给高层次logger的handler

[handler_consoleHandler] #指定处理器
class=StreamHandler #必须指定;表示用于创建handler的类名
args=(sys.stdout,) #必须;表示传递给class所指定handler类初始化方法参数;必是元组
level=DEBUG #可选
formatter=simpleFormatter#可选;指定格式器名称必须出现在formatters这个section中,
配置文件必有这个formatter的section定义;如不指定formatter则该handler会以消息本身作为日志消息进行记录,
而不添加额外的时间、日志器名称等信息;

[handler_fileHandler] #指定处理器
class=FileHandler
args=('logging.log', 'a')
level=ERROR
formatter=simpleFormatter


[formatter_simpleFormatter] #指定格式器;都是可选
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s#指定格式字符串,默认为消息字符串本身      
datefmt=#用于指定asctime的时间格式,默认为'%Y-%m-%d %H:%M:%S'

说明:

class指定类名默认为logging.Formatter,该类名可以是相对于logging模块的相对值,如:FileHandler、
handlers.TimeRotatingFileHandler;也可以是一个绝对路径值,
通过普通的import机制来解析,如自定义的handler类mypackage.mymodule.MyHandler
但是mypackage需要在Python可用的导入路径中--sys.path。


输出:propagate=1除了在控制台有输出信息时候,在logging.log文件中也有内容输出
2019-07-03 19:31:51,634 - simpleExample - DEBUG - debug message
2019-07-03 19:31:51,635 - simpleExample - INFO - info message
2019-07-03 19:31:51,635 - simpleExample - WARNING - warn message
2019-07-03 19:31:51,635 - simpleExample - ERROR - error message
2019-07-03 19:31:51,635 - simpleExample - CRITICAL - critical message

 

三、使用字典配置信息和dictConfig()函数实现日志配置

pip install PyYAML
Python代码:

import logging
import logging.config
import yaml

with open('logging.yml', 'r') as f_conf:
    dict_conf = yaml.load(f_conf)
logging.config.dictConfig(dict_conf)

logger = logging.getLogger('simpleExample')
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')

logging.yml配置文件的内容:

version: 1
formatters:
  simple:
    format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
handlers:
  console:
    class: logging.StreamHandler
    level: DEBUG
    formatter: simple
    stream: ext://sys.stdout
  console_err:
    class: logging.StreamHandler
    level: ERROR
    formatter: simple
    stream: ext://sys.stderr
loggers:
  simpleExample:
    level: DEBUG
    handlers: [console]
    propagate: yes
root:
  level: DEBUG
  handlers: [console_err]

输出结果:
"""
2019-07-04 21:03:31,879 - simpleExample - CRITICAL - critical message 
2019-07-04 21:03:31,878 - simpleExample - DEBUG - debug message 
2019-07-04 21:03:31,879 - simpleExample - INFO - info message 
2019-07-04 21:03:31,879 - simpleExample - WARNING - warn message 
2019-07-04 21:03:31,879 - simpleExample - ERROR - error message 
2019-07-04 21:03:31,879 - simpleExample - CRITICAL - critical message
"""
logging.config.dictConfig(config)
该函数可以从一个字典对象中获取日志配置信息,config参数就是这个字典对象
key名称 描述
version 必选,整数,表示配置格式版本,当前唯一可用的值就是1
formatters 可选,字典,key为格式器名称,value为格式器的配置信息,如format和datefmt
filters 可选,字典,key为过滤器名称,value为过滤器的配置信息,如name
handlers 可选,字典,key为处理器名称,value为处理器的配置信息,如class、level、formatter和filters,其中class必选项,其它可选;其他配置信息将会传递给class所指定的处理器类的构造函数,如下面的handlers定义示例中的stream、filename、maxBytes和backupCount等
loggers 可选,字典,key为日志器名称,value为日志器的配置信息,如level、handlers、filters 和 propagate(yes
root 可选,这是root logger的配置信息,其值也是一个字典对象。除非在定义其它logger时明确指定propagate值为no,否则root logger定义的handlers都会被作用到其它logger上
incremental 可选,默认False。如定义对象已存在,对这些对象定义是否应用到已存在对象上。False表示已存在的对象将会被重新定义。
disable_existing_loggers 可选,默认True。指定是否禁用已存在的日志器loggers,如incremental值为True则该选项将会被忽略

 

使用json配置文件设置logger的配置

#!/usr/bin/env python
# coding:UTF-8 
 
"""
@version: python3.x
@author:dtcy
@contact: [email protected]
@software: PyCharm
@file: 使用配置文件设置logger的配置(logging.config).py
@time: 2018/11/16 13:26
"""
import os,logging,sys,time,json
import logging.config
 
def singleton(cls):
  instances = {}
  def _singleton(*args,**kwargs):
    if cls not in instances:
      instances[cls] = cls(*args,**kwargs)
    return instances[cls]
  return _singleton
 
@singleton
class Logger():
    def __init__(self,logfile=None):
        self.logger = logging.getLogger("simple_example")
        with open("logconf.json","r") as config:
            LOGGING_CONFIG = json.load(config)
            logging.config.dictConfig(LOGGING_CONFIG)
  
if __name__ == "__main__":
    lg = Logger()
    lg.logger.warning("aaa1")
    lg.logger.error("bbb2")
    lg.logger.debug("ccc3")

logconf.json文件内容:

 

{
  "version":1,
  "handlers":{
    "console_streamHandler":{
      "class":"logging.StreamHandler",
      "level":"DEBUG",
      "formatter":"myFormatter",
      "stream":"ext://sys.stdout"
    },
    "console1_fileHandler":{
      "class":"logging.handlers.RotatingFileHandler",
      "level":"DEBUG",
      "formatter":"myFormatter",
      "filename":"log.log",
      "mode": "w+",
      "maxBytes":  524288000,
      "backupCount": 20,
      "encoding":"utf8"
    }
  },
  "formatters":{
    "myFormatter":{
      "format":"%(asctime)s %(name)s  %(levelname)s %(filename)s %(lineno)d %(thread)d %(threadName)s %(process)d %(message)s"
    }
  },
  "loggers":{
    "simple_example":{
      "level":"DEBUG",
      "handlers":["console_streamHandler","console1_fileHandler"]
    }
  }
}

结果显示:

2019-07-04 21:05:34,858 simple_example  WARNING test_pprint.py 47 11144 MainThread 11252 aaa1

2019-07-04 21:05:34,867 simple_example  ERROR test_pprint.py 48 11144 MainThread 11252 bbb2

2019-07-04 21:05:34,868 simple_example  DEBUG test_pprint.py 49 11144 MainThread 11252 ccc3

 

 通过YAML文件配置
    通过YAML文件进行配置,比JSON看起来更加简介明了

version: 1
   disable_existing_loggers:False 
   formatters:
    simple:
    format:"%(asctime)s - %(name)s - %(levelname)s - %(message)s"
   handlers:
    console:

    class:
        logging.StreamHandler

    level: DEBUG
    formatter: simple
    stream: ext: // sys.stdout
    info_file_handler:

    class:
        logging.handlers.RotatingFileHandler

    level: INFO
    formatter: simple
    filename: info.log
    maxBytes: 10485760
   backupCount: 20
   encoding: utf8
    error_file_handler:

   class:
        logging.handlers.RotatingFileHandler

    level: ERROR
    formatter: simple
    filename: errors.log
    maxBytes:10485760
   backupCount: 20
   encoding: utf8
    loggers:
    my_module:
    level: ERROR
    handlers: [info_file_handler]
    propagate: no
    root:
    level: INFO
    handlers: [console, info_file_handler, error_file_handler]
   

  通过YAML加载配置文件,然后通过logging.dictConfig配置logging,

 importyaml
    importlogging.config
   importos

   defsetup_logging(default_path="logging.yaml", default_level=logging.INFO, env_key="LOG_CFG"):
        path = default_path
        value = os.getenv(env_key,None)
       ifvalue:
            path = value
       ifos.path.exists(path):
           withopen(path,"r")asf:
                config = yaml.load(f)
                logging.config.dictConfig(config)
       else:
            logging.basicConfig(level=default_level)

   deffunc():
        logging.info("startfunc" )
        logging.info("exec func")
        logging.info("end func")

   if__name__ =="__main__":
        setup_logging( default_path="logging.yaml" )
        func()

3.通过JSON或者YAML文件配置logging模块

    尽管可以在Python代码中配置logging,但是这样并不够灵活,最好的方法是使用一个配置文件来配置。

    可以从字典中加载logging配置,也就意味着可以通过JSON或者YAML文件加载日志的配置。

    

    3.1.通过JSON文件配置

 JSON配置文件,

    {

        "version": 1,
        "disable_existing_loggers": false,
        "formatters": {
            "simple": {
                "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
            }
        },
        "handlers": {
            "console": {
                "class": "logging.StreamHandler",
                "level": "DEBUG",
                "formatter": "simple",
                "stream": "ext://sys.stdout"
            },
            "info_file_handler": {
                "class": "logging.handlers.RotatingFileHandler",
                "level": "INFO",
                "formatter": "simple",
                "filename": "info.log",
                "maxBytes": "10485760",
                "backupCount": 20,
                "encoding": "utf8"
            },

            "error_file_handler": {
                "class": "logging.handlers.RotatingFileHandler",
                "level": "ERROR",
                "formatter": "simple",
                "filename": "errors.log",
                "maxBytes": 10485760,
                "backupCount": 20,
                "encoding": "utf8"
            }
        },

        "loggers": {
            "my_module": {
                "level": "ERROR",
                "handlers": ["info_file_handler"],
                "propagate": "no"
            }
        },
        "root": {

            "level": "INFO",
            "handlers": ["console", "info_file_handler", "error_file_handler"]
        }
    }

 

    通过JSON加载配置文件,然后通过logging.dictConfig配置logging,

 

 import json
 import logging.config
 import os

 def setup_logging(default_path="logging.json", default_level=logging.INFO, env_key="LOG_CFG"):
        path = default_path
        value = os.getenv(env_key, None)
        if value:
            path = value
        if os.path.exists(path):
            with open(path, "r") as f:
                config = json.load(f)
                logging.config.dictConfig(config)
        else:
            logging.basicConfig(level=default_level)

 def func():
        logging.info("start func")
        logging.info("exec func")
        logging.info("end func")

 if __name__ == "__main__":
        setup_logging(default_path="logging.json")
        func()

   

你可能感兴趣的:(python)