zoukankan      html  css  js  c++  java
  • Python日志

    日志整合

    1.logging模块

    logging模块,这个模块的功能是记录我们软件的各种状态,你们现在和我一起找到红蜘蛛的那个图标,然后右键找一找是不是有个错误日志.其实每个软件都是有错误日志的,开发人员可以通过错误日志中的内容对他的程序进行修改, 我们也需要写日志

    1.1函数式简单配置

    我们先来看一下函数式简单配置

    import logging#导入默哀快
    logging.debug('debug message')  
    logging.info('info message')  
    logging.warning('warning message')  
    logging.error('error message')  
    logging.critical('critical message')
    

    默认情况下Python的logging模块将日志打印到了标准输出中,且只显示了大于等于WARNING级别的日志,这说明默认的日志级别设置为WARNING(日志级别等级CRITICAL > ERROR > WARNING > INFO > DEBUG),默认的日志格式为日志级别:Logger名称:用户输出消息。

    image-20211215092806832

    我们自己用函数写的这个可以正常使用但是不够灵活,我们看看这个灵活的

    1.2 灵活配置

    灵活配置日志级别,日志格式,输出位置

    import logging
    logging.basicConfig(level=logging.DEBUG,#设置等级debug
                        format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',#设置记录格式
                        datefmt='%a, %d %b %Y %H:%M:%S',#设置格式,星期 日月年时分秒
                        filename='./test.log',#设置输出位置
                        filemode='w')#写入,W清空上一次,追加可以写a
    logging.debug('debug message')
    logging.info('info message')
    logging.warning('warning message')
    logging.error('error message')
    logging.critical('critical message')
    

    image-20211215093620674

    1.3参数配置

    logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有:
    filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。
    filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
    format:指定handler使用的日志显示格式。
    datefmt:指定日期时间格式。
    level:设置rootlogger(后边会讲解具体概念)的日志级别
    stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件(f=open(‘test.log’,’w’)),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。
    format参数中可能用到的格式化串:
    %(name)s Logger的名字
    %(levelno)s 数字形式的日志级别
    %(levelname)s 文本形式的日志级别
    %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
    %(filename)s 调用日志输出函数的模块的文件名
    %(module)s 调用日志输出函数的模块名
    %(funcName)s 调用日志输出函数的函数名
    %(lineno)d 调用日志输出函数的语句所在的代码行
    %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
    %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
    %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
    %(thread)d 线程ID。可能没有
    %(threadName)s 线程名。可能没有
    %(process)d 进程ID。可能没有
    %(message)s用户输出的消息
    

    1.4 logger对象配置

    # -*- coding: utf-8 -*-
    '''
    @Time    : 2021/12/15 9:42
    @Author  : ziqingbaojian
    @File    : 2.logger对象配置.py
    '''
    import logging
    logger = logging.getLogger()
    # 创建一个handler,用于写入日志文件
    fh = logging.FileHandler('test1.log',encoding='utf-8')
    # 再创建一个handler,用于输出到控制台
    ch = logging.StreamHandler()
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    logger.setLevel(logging.DEBUG)# 设置日志的级别
    fh.setFormatter(formatter)#设置的日志的输出
    ch.setFormatter(formatter)
    logger.addHandler(fh) #logger对象可以添加多个fh和ch对象
    logger.addHandler(ch)
    logger.debug('logger debug message')#写入日志的信息
    logger.info('logger info message')
    logger.warning('logger warning message')
    logger.error('logger error message')
    logger.critical('logger critical message')
    

    image-20211215095349702

    logging库提供了多个组件:Logger、Handler、Filter、FormatterLogger对象提供应用程序可直接使用的接口

    Handler发送日志到适当的目的地,

    Filter提供了过滤日志信息的方法,

    Formatter指定日志显示格式。另外,可以通过:logger.setLevel(logging.Debug)设置级别

    日志我们一般写代码的时候会添加,部分公司和部分项目要求不一样,

    info一般都是记录一些消费信息,操作信息,转账信息

    info以上的级别就是在程序出现错误的时候会记录

    1.5字典配置

    1.案例一参考博客
    # -*- coding: utf-8 -*-
    '''
    @Time    : 2021/12/15 11:39
    @Author  : ziqingbaojian
    @File    : 6.新配置字典.py
    '''
    # 核心就在于CV
    import logging
    import logging.config
    
    standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
                      '[%(levelname)s][%(message)s]'  # 其中name为getlogger指定的名字
    
    simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
    
    logfile_path = 'a3.log'
    # log配置字典
    LOGGING_DIC = {
        'version': 1,
        'disable_existing_loggers': False,
        'formatters': {
            'standard': {
                'format': standard_format
            },
            'simple': {
                'format': simple_format
            },
        },
        'filters': {},  # 过滤日志
        'handlers': {
            # 打印到终端的日志
            'console': {
                'level': 'DEBUG',
                'class': 'logging.StreamHandler',  # 打印到屏幕
                'formatter': 'simple'
            },
            # 打印到文件的日志,收集info及以上的日志
            'default': {
                'level': 'DEBUG',
                'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
                'formatter': 'standard',
                'filename': logfile_path,  # 日志文件
                'maxBytes': 1024 * 1024 * 5,  # 日志大小 5M
                'backupCount': 5,
                'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
            },
        },
        'loggers': {
            #logging.getLogger(__name__)#拿到的logger配置  空字符串作为键 能够兼容所有的日志
            '': {
                'handlers': ['default', 'console'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
                'level': 'DEBUG',
                'propagate': True,  # 向上(更高level的logger)传递
            },  # 当键不存在的情况下 (key设为空字符串)默认都会使用该k:v配置
        },
    }
    
    # 使用配置字典
    logging.config.dictConfig(LOGGING_DIC)  # 自动加载字典中的配置
    logger1 = logging.getLogger('xxx')
    logger1.debug('好好的 不要浮躁 努力就有收获')
    
    
    2.案例二参考视频
    # -*- coding: utf-8 -*-
    '''
    @Time    : 2021/12/15 10:12
    @Author  : ziqingbaojian
    @File    : 3.记录日志.py
    '''
    import os
    import logging.config
    
    
    LOGGING_CONFIG={
        'version':1,
        'disable_existing_loggers':True,
        'formatters':{
            'standard':{
                'format':'{levelname} {asctime} {module} {process:d} {thread:d} {message}',
                'style':'{',
            },
            'simple':{
                'format':'[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s',
            },
        },
        'handlers':{
            'console': {
                'level': 'DEBUG',
                'class': 'logging.StreamHandler',  # 打印到屏幕
                'formatter': 'simple'
            },
            'sms_file':{
                'class': 'logging.handlers.RotatingFileHandler',
                'formatter':'standard',
                'filename':os.path.join('logs','sms.log'),
                'maxBytes':10240,#根据文件大小分割日志
                'backupCount':30,#备份个数
                'encoding':'utf-8'
            },
            'error_file':{
                'class':'logging.handlers.TimedRotatingFileHandler',
                'formatter':'standard',
                'filename':os.path.join('logs','error.log'),
                'when':'D',#根据每天拆分日志
                'backupCount':3,#保留备份
                'encoding':'utf8'
            }
        },
        'loggers':{
            'sms':{
                'level':'INFO',
                'handlers':['sms_file'],#意味着通过SMS的loggers,写日志的时 级别>info,且会写入到sms_file的文件中
                'propagate':False#通过sms写日志时,同时也会找到他的父亲,向上传播
            },
            'error':{
                'handlers':['error_file','console'],
                'level':'ERROR',
                'propagate':True
            }
        },
        'root':{
            'level':'ERROR',
            'handlers':['console',],
            'propagate':True
        }
    }
    
    # 根据自定义对logging进行配置
    logging.config.dictConfig(LOGGING_CONFIG)
    
    # 写日志
    logger_object=logging.getLogger('error')
    logger_object.error('日志好复杂')
    
    # logger_object=logging.getLogger("sms")
    # logger_object.error('666666')
    
    

    2.日志异步处理

    参考视频点击观看主要解决异步过程中按天分割日志文件;方便查看;

    需求:基于logging实现日志,每天的日志都记录在一个文件中;

    image-20211215135041609

    2.1注意事项

    日志文件不能碰,删除 or 修改 ,日志不再记录;

    • 对于文件操作而言:
    f1=open('a1.log','a',encoding='utf8')
    
    while True:
        f1.write("开始写入了")
        f1.flush()#将内容刷新到硬盘上
    
    • 此时如果删除掉文件不会报错但也不会继续写入;logging模块内部使用异常处理将该异常进行了处理;

    此过程需要重写源码中的类,建议观看视频;

    3.django日志

    官网示例,点击这里

    参考文章:点击这里,yongxinz

    3.1 配置文件中配置

    # 设置日志
    LOGGING={
        'version': 1,
        'disable_existing_loggers': False,
        'formatters': {
            'standard': {
                'format': '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
                      '[%(levelname)s][%(message)s]'
            },
            'simple': {
                'format': '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
            },
        },
        'handlers': {
            'console': {
                'level': 'DEBUG',
                'class': 'logging.StreamHandler',
                'formatter': 'simple'
            },
            'default': {
                'level': 'DEBUG',
                'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
                'formatter': 'standard',
                'filename': 'logs/debug.log',  # 日志文件
                'maxBytes': 1024 * 1024 *5,  # 日志大小 5M
                'backupCount': 5,# 表示日志文件的保留个数
                'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
            },
        },
        'loggers': {
            'django': {
                'handlers': ['console','default'],
                'level': 'INFO',
                'propagate': False,
            },
            'web':{
                'handlers': ['default'],
                'level': 'DEBUG',
                # 此记录器处理过的消息就不再让 django 记录器再次处理了
                'propagate': False
            },
        }
    }
    
    • # 在视图函数中可以增加对应的自定义日志
      import logging
      log_obj=logging.getLogger('web')
      
      # 在对应的逻辑处写上log_obj.debug("XXXXX"),也可以写上用户名之类的信息
      
    • image-20211215171438635

    • image-20211215171021367

    3.2 中间件配置

    # -*- coding: utf-8 -*-
    '''
    @Time    : 2021/12/15 15:36
    @Author  : ziqingbaojian
    @File    : log_middlware.py
    '''
    import logging
    import json
    import socket
    import threading
    
    from django.utils.deprecation import MiddlewareMixin
    
    local=threading.local()
    
    class RequestLogFilter(logging.Filter):
        '''
        日志过滤器
        '''
        def filter(self,record):
            record.sip = getattr(local, 'sip', 'none')
            record.dip = getattr(local, 'dip', 'none')
            record.body = getattr(local, 'body', 'none')
            record.path = getattr(local, 'path', 'none')
            record.method = getattr(local, 'method', 'none')
            record.username = getattr(local, 'username', 'none')
            record.status_code = getattr(local, 'status_code', 'none')
            record.reason_phrase = getattr(local, 'reason_phrase', 'none')
            return True
    
    class RequestLogMiddleware(MiddlewareMixin):
        '''
        将request的信息记录在当前请求的线程上
        '''
        def __init__(self,get_reponse=None):
            self.get_response=get_reponse
            self.apiLogger=logging.getLogger('web.log')
    
        def __call__(self,request):
            try:
                body=json.loads(request.body)
            except Exception:
                body=dict()
    
            # if request.method == 'GET':
            #     body.update(dict(request.GET))
            # else:
            #     body.update(dict(request.POST))
    
            local.body = body
            local.path = request.path
            local.method = request.method
            local.username = request.user
            local.sip = request.META.get('REMOTE_ADDR', '')
            local.dip = socket.gethostbyname(socket.gethostname())
    P
            response = self.get_response(request)
            local.status_code = response.status_code
            local.reason_phrase = response.reason_phrase
            self.apiLogger.info('system-auto')
    
            return response
    

    本方法建议去看参考文献的具体做法;

    加油!!!
  • 相关阅读:
    CS224n, lec 10, NMT & Seq2Seq Attn
    CS231n笔记 Lecture 11, Detection and Segmentation
    CS231n笔记 Lecture 10, Recurrent Neural Networks
    CS231n笔记 Lecture 9, CNN Architectures
    CS231n笔记 Lecture 8, Deep Learning Software
    CS231n笔记 Lecture 7, Training Neural Networks, Part 2
    pytorch坑点排雷
    Sorry, Ubuntu 17.10 has experienced an internal error
    VSCode配置python插件
    tmux配置与使用
  • 原文地址:https://www.cnblogs.com/Blogwj123/p/15693797.html
Copyright © 2011-2022 走看看