首页 > 编程语言 >python-日志详解

python-日志详解

时间:2022-11-18 11:02:53浏览次数:64  
标签:logging log python 打印 详解 日志 logger logs

一. logging模块_打印以及保存日志

1、Logging :用来做简单的日志。等级分为 debug()、 info()、 warning()、 error() 和 critical()

等级	    使用场景
DEBUG 	    调试 ,打印详细信息
INFO 	    一般信息,打印关键信息,证明程序按预定轨迹执行。
WARNING     警告信息,未预料到的 及可能出现问题和错误的提示信息,但是软件还是会照常运行    例如:磁盘空间不足。
ERROR 	    程序出现错误,可能会波及一些功能的使用
CRITICAL    严重错误,软件不能正常执行

2. logging组件

# 1. Logger 记录器: 记录运行日志,并按配置日志等级过滤日志信息。

      #常用的方法分为两类:配置和发送消息。
        Logger.setLevel()
            指定logger将会处理的日志等级信息。
        Logger.addHandler()和Logger.removeHandler()
            从记录器对象中添加和删除处理程序对象。
        Logger.addFilter()和Logger.removeFilter()
            从记录器对象添加和删除过滤器对象。

# 2. Handler 处理器: 将日志存放到控制台或写入文件。

            logging.StreamHandler    
                控制台输出
            logging.FileHandler        
                文件输出
            logging.handlers.RotatingFileHandler
                按照大小自动分割日志文件,一旦达到指定的大小重新生成文件 
            logging.handlers.TimedRotatingFileHandler
                按照时间自动分割日志文件 
                
           # 配置方法:

            setLevel()方法
                指明了将会分发日志的最低级别。为什么会有两个setLevel()方法?记录器的级别决定了消息是否要传递给处理器。
                每个处理器的级别决定了消息是否要分发。
            setFormatter()
                为该处理器选择一个格式化器。
            addFilter()和removeFilter()
                分别配置和取消配置处理程序上的过滤器对象。


# 3. Filter 过滤器:  过滤输出的日志信息。

                addFilter(filter),removeFilter(filter)和filter(record)方法
                # 常用的属性
                    name     就是初始化logger对象时传入的名字

                    level    是级别

                    pathname 是哪个文件输出的这行日志

                    lineno   是行号

                    msg      是日志本身


# 4. Formatter 格式化器: 格式化日志输出格式。    

            # 默认的时间格式为%Y-%m-%d %H:%M:%S

            # 常用信息
                %(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. 引入方法

import logging
from logging import handles

2. 配置日志输出格式

logging.basicConfig函数各参数

filename: 指定日志文件名,将文件写入 
filemode: 和file函数意义相同,指定日志文件的打开模式,'w' 覆盖写入 或'a' 追加写入 ,默认写入模式为a
format: 指定输出的格式和内容,format可以输出很多有用信息,如上例所示:
    %(levelno)s:    打印日志级别的数值
    %(levelname)s:  打印日志级别
    %(pathname)s:   打印当前执行程序名(包含详细路径),其实就是sys.argv[0]
    %(filename)s:   打印当前执行程序名
    %(funcName)s:   打印日志的当前函数
    %(lineno)d:     打印日志的当前行号
    %(asctime)s:    打印日志的时间
    %(thread)d:     打印线程ID
    %(threadName)s: 打印线程名称
    %(process)d:    打印进程ID
    %(message)s:    打印日志信息
datefmt: 指定时间格式,同time.strftime()
   英文:    %A 周, %B 月
   英文缩写:  %a 周, %b 月, %c 日期+时间缩写 (输出格式:Wed Jan 12 10:00:06 2022)
   时间:    %d 日, %w 周, %m 月, %Y 年, %H:%M:%S 时分秒, %T 时间 (10:09:32), %D 日期 (12/01/22), %F 日期(2022-01-12)

level: 设置日志级别,默认为logging.WARNING 
stream: 指定将日志的输出流,可以指定输出到sys.stderr,sys.stdout或者文件,默认输出到sys.stderr,当stream和filename同时指定时,stream被忽略

3. 设置日志格式

# 设置日志格式
# 设置打印格式
logging.basicConfig(format='%(asctime)s - %(name)s[line:%(lineno)d] - %(levelname)s: %(message)s', # 日志格式
                    datefmt='%F %T ', # 日期格式
                    level=logging.INFO) # 日志等级info

三.打印方法

# 1、仅打印到控制台,logging 默认设置的等级为warning,只打印warning和以上等级
      # coding:utf-8
      import logging

      # 打印到控制台

      logging.debug("打印到控制台")
      logging.info("打印到控制台")
      logging.warning("打印到控制台")
      logging.error("打印到控制台")
      logging.critical("打印到控制台")

# 2. 仅将日志写入文件
# 设置打印格式
logging.basicConfig(format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s', # 日志格式
                    datefmt='%F %T ', # 日期格式
                    level=logging.INFO,# 日志等级
                    filename="info.log",    # 日志写入文件info.log
                    filemode="a")      #a 追加写入, w 覆盖写入

四. 输出控制台并写入日志文件

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import os, datetime, logging
from logging import handlers

# >>> 定义Logger类
class Logger(object):
    # 定义类属性
    level_relations = {'debug': logging.DEBUG, 'info': logging.INFO, 'warning': logging.WARNING, 'error': logging.ERROR, 'crit': logging.CRITICAL}#日志级别关系映射

    # 使用函数exists()对文件存在与否进行判断,存在为True,不存在为False.
    if os.path.exists('logs') == True:  # 文件存在
        filepath = os.getcwd() + '\logs\log_' + datetime.datetime.now().strftime('%Y%m%d') + '.log'
    else:
        os.makedirs(".\logs")  # 创建文件夹
        filepath = os.getcwd() + '\logs\log_' + datetime.datetime.now().strftime('%Y%m%d') + '.log'

    # 定义构造函数  when=D 天数,新生成的文件名上会带上时间 backCount 保留文件生成个数
    def __init__(self, filename=filepath, level='info', when='D', backCount=3, fmt='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s'):
     #when:描述滚动周期的基本单位;“S”: Seconds ,“M”: Minutes ,“H”: Hours ,“D”: Days ,“W”: Week day (0=Monday) ,“midnight”: Roll over at midnight
        self.logger = logging.getLogger(filename)   # 指定日志文件名
        format_str = logging.Formatter(fmt) # 设置日志格式
        self.logger.setLevel(self.level_relations.get(level))   # 设置日志级别
        sh = logging.StreamHandler()    # 往屏幕上输出
        sh.setFormatter(format_str)     # 设置屏幕上显示的格式
        th = handlers.TimedRotatingFileHandler(filename=filename, when=when, backupCount=backCount, encoding='utf-8')  # 写入文件
        th.setFormatter(format_str) # 设置文件里写入的格式
        self.logger.addHandler(sh)  # 把对象加到logger里 屏幕输出
        self.logger.addHandler(th)  # 把对象加到logger里 文件写入

    def getLog(self):
        return self.logger

#创建log对象,隐式调用了我们手动创建的 __init__() 构造方法,并设置日志等级
# logs = Logger().logger  # 方法一
# logs = Logger().getLog()  # 方法二
# 方法三:重置日志等级
logs = Logger(level="debug").getLog()


# 该部分只有文件作为脚本时才会被执行,而 import 到其他脚本中是不会被执行的
if __name__ == '__main__':
    logs.debug('debug 信息')
    logs.info('info 信息')
    logs.warning('警告 信息')
    logs.error('报错 信息')
    logs.critical('严重 信息')

自动分割日志:将不同级别的日志分别保存在不同的文件中

import logging
from logging import handlers

class Logger(object):
    level_relations = {'debug': logging.DEBUG,  'info': logging.INFO, 'warning': logging.WARNING,  'error': logging.ERROR, 'crit': logging.CRITICAL}#日志级别关系映射

    def __init__(self, filename, level='info', when='D', backCount=3, fmt='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s'):
        self.logger = logging.getLogger(filename) # 创建一个logger
        format_str = logging.Formatter(fmt)#设置日志格式
        self.logger.setLevel(self.level_relations.get(level))#设置日志级别
        sh = logging.StreamHandler()#往屏幕上输出
        sh.setFormatter(format_str) #设置屏幕上显示的格式
        th = handlers.TimedRotatingFileHandler(filename=filename, when=when, backupCount=backCount, encoding='utf-8') #往文件里写入#指定间隔时间自动生成文件的处理器
        th.setFormatter(format_str)#设置文件里写入的格式
        self.logger.addHandler(sh) #把对象加到logger里
        self.logger.addHandler(th)#

if __name__ == '__main__':
    log = Logger('./logs/debug.log', level='debug')
    log.logger.debug('debug')
    log.logger.info('info')
    log.logger.warning('警告')
    log.logger.error('报错')
    log.logger.critical('严重')
    Logger('./logs/error.log', level='error').logger.error('error')

五. loguru



# 安装
pip install loguru

# 引用
from loguru import logger as logg

# 打印日志
logg.info("debug")

# 写入文件
# logg.add("logs_20220414.log")
# 将日志保存在当前路径上一级目录的logs目录下,命名为 log_name 
log_name = "log_{}.log".format(datetime.datetime.now().strftime('%Y%m%d'))
logs.add(sink=os.path.abspath("..") + "\\logs\\{}".format(log_name), level=log_level.upper()) 

# 设置生成日志文件,utf-8编码,每天0点切割,zip压缩,保留3天,异步写入 
# logs.add(sink='test.log', level="INFO", rotation="00:00", retention="3 days", compression="zip", encoding="utf-8", enqueue=True)





from loguru import logger as logg
logg.add("logs.log")

def case():
    logg.debug("debug")
    logg.warning("warning")


case()








# 仅输出到文件 不打印到控制台
# 删除以前添加的处理程序并停止向其接收器发送日志。
logs.remove(handler_id=None)     # 移除控制台输出

 

 

# 集成loguru到控制台(即html报告)
class PropogateHandler(logging.Handler):
    def emit(self, record):
        logging.getLogger(record.name).handle(record)
logs.add(PropogateHandler(), format="{time:YYYY-MM-DD at HH:mm:ss} | {message}")

原文链接:https://www.cnblogs.com/phoenixy/p/15791454.html

标签:logging,log,python,打印,详解,日志,logger,logs
From: https://www.cnblogs.com/kh-1314/p/16902510.html

相关文章

  • Python print() 实时打印
    在程序中发现print内容输出和实际输出时间不一致,所以怀疑输出时间有问题,实践发现print没有进行实时刷新。#正常使用print("something。。。")#实时刷新print("someth......
  • Python | Python中 from __future__ import * 的作用
    我们在读代码的时候,总是会看到代码开头会加上from__future__import*这样的语句。这样的做法的作用就是将新版本的特性引进当前版本中,也就是说我们可以在当前版本使用新......
  • vue前端开发仿钉图系列(1)高德地图的使用详解
    最近公司让参考钉图做图层模块相关的功能,很庆幸有机会细细研究地图相关的东西。因为手机端用的是高德地图,web端也使用高德地图。还是和往常一样,先贴上效果图。 ......
  • 日志系统
    日志1、Log简介logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级、日志保存路径、日志文件回滚等;相比print,具备如下优点:通过log的分析,可......
  • python单线程爬虫安装与调试
    信息时代的到来,带给我们海量信息的同时也给我们带来很多有用的价值。如何在这些海量信息池里面找到自己需要的有价值的信息就离不开爬虫技术了,那么在python下如果去部署安装......
  • Python基础之运算符
    一、算数运算符混合运算优先级顺序:()⾼于**⾼于*///%⾼于+-二、赋值运算符单个变量赋值num=1print(num)多个变量赋值num1,float1,str1=10,0.5,'hellowo......
  • No Python interpreter configured for the project
    ......
  • 力扣704(java&python)-二分查找(简单)
    题目:给定一个 n 个元素有序的(升序)整型数组 nums和一个目标值 target ,写一个函数搜索 nums 中的target,如果目标值存在返回下标,否则返回-1。示例1:输入:nums......
  • docker-compose文件详解
    Compose和Docker兼容性:Compose文件格式有3个版本,分别为1,2.x和3.x目前主流的为3.x其支持docker1.13.0及其以上的版本常用参数:version#指定comp......
  • python笔记75-compile() 函数将字符串转字节代码
    前言compile()函数将一个字符串编译为字节代码。compile()使用以下是compile()方法的语法:compile(source,filename,mode[,flags[,dont_inherit]])参数so......