Python basics _ detailed explanation of the code logic and configuration files in the log module

First look at the code logic diagram of the log module:
Insert picture description here

With the code, help me deepen my understanding:

# coding=utf-8
import logging
import time
from Common.function import project_path

# 单词:formatter格式器、handler处理程序、FileHandler文件内容处理程序
class FrameLog:
    """
    这里定义了日志输出的基本格式
    """
    def __init__(self, name=None):
        # 调用Framelog,user默认root、日志级别默认debug
        self.logger = logging.getLogger(name)
        self.logger.setLevel(logging.DEBUG)

        # handler定义了将日志发送到哪里,如:pycharm控制器、日志文件、邮件、短信等,
        # 创建一个handler,定义了将日志发送到文件,并设置了日志内容的格式、级别、
        self.log_name = f"{project_path()}/logs/" + time.strftime("%Y_%m_%d") + "_log.log"
        file = logging.FileHandler(self.log_name, "a", "utf-8")
        formatter = logging.Formatter('[%(asctime)s] %(filename)s-> %(funcName)s line:%(lineno)d [%(levelname)s]%(''message)s')
        file.setFormatter(formatter)
        file.setLevel(logging.DEBUG)

        # 再次创建一个handler,将日志发送到控制器(我用的是上面的格式器,你可以再这个handler里再自定义一个。)
        console = logging.StreamHandler(stream=None)
        console.setFormatter(formatter)  
        console.setLevel(logging.INFO)
        
        # 将2个处理器加入到logger中,不但向控制器输出、还想文件输出。
        self.logger.addHandler(file)
        self.logger.addHandler(console)
        
    def log(self):
        return self.logger


if __name__ == '__main__':
    # cgis模块,打印cgis-server模块的日志
    log = FrameLog('cgis-server').log()
    try:
        print(2/0)
    except ZeroDivisionError:
        print('这里打印在控制台')
        # 下面的message输入到日志
        log.error('这是一个框架性的错误11111111')
        log.debug('这是业务代码里的错误1111111111')
        log.info('这是业务代码里info级别的错误11111111111')
        log.critical('这是系统性的错误1111111')

    # fgis模块,打印fgis - server模块的日志
    log = FrameLog('fgis-server').log()
    try:
        print(2/0)
    except ZeroDivisionError:
        print('这里打印在控制台')
        # 下面的message输入到日志
        log.error('这是一个框架性的错误22222')
        log.debug('这是业务代码里的错误22')
        log.info('这是业务代码里info级别的错误2222')
        log.critical('这是系统性的错误222')

In the actual project, the definition of the log is realized through the configuration file. Please refer to the summary of the boss :

[loggers]               #固定写法
keys=root,error,info    #创建三个app名,root是父类,必需存在的

[logger_root]           #创建完的app名我们要定义一些规则,严格要求格式为"logger_appname"
level=DEBUG             #设置日志级别
qualname=root           #这里在"root"appname下可以不填,所有没获取get的情况下默认app名都是root
handlers=debugs         #设置指定过滤器,多个以逗号分隔,这个名字待会儿 我们会以固定格式"handler_(value)"创建

[logger_error]
level=ERROR
qualname=error          #除了root appname以外,定义的app名必须要设置这个属性,用于定义打印输出时候的app名
handlers=errors

[logger_info]
level=INFO
qualname=INFO
handlers=infos

[handlers]                  #固定格式
keys=infos,errors,debugs    #定义过滤器名称,下面定义以handler_keysname格式定义,上面引用名称必须和keys一致

[handler_infos]
class=FileHandler           #指定过滤器组件,详情请看官网,这个是以文件方式创建
level=INFO                  #设置级别
formatter=form01            #定义日志打印格式,下面会创建formatters,格式也是严格要求formatter_keysname 创建
args=('info.log','a')       #创建文件名字,以什么方式打开

[handler_errors]
class=FileHandler
level=DEBUG
formatter=form02
args=('info1.log','a')

[handler_debugs]
class=FileHandler
level=DEBUG
formatter=form02
args=('info1.log','a')

[formatters]            #固定格式
keys=form01,form02      #定义名称,下面会引用格式同上

[formatter_form01]
format=%(asctime)s %(filename)s %(levelname)s  %(message)s  #年-月-日 时-分-秒,毫秒,文件名,级别名,消息信息
datefmt=%Y-%m-%d %H:%M:%S   #日期输出格式

[formatter_form02]
format=%(asctime)s %(filename)s %(levelname)s  %(message)s
datefmt=%Y-%m-%d %H:%M:%S

This is how it is called in the log module:

# coding=utf-8
import logging
import logging.config
logging.config.fileConfig('log.conf')

logs = logging.getLogger('error')
logs.error('errorsssss')

Guess you like

Origin blog.csdn.net/weixin_45451320/article/details/113027426