python3 logging 学习笔记

文章来源:https://www.jianshu.com/p/4993b49b6888

logging简单使用

看下面的代码就可以对logging的使用有一个基本的认识

# 亭子
#!/usr/bin/env python3
# -*- coding:utf-8 -*-

'''
记录了logging的简单使用方式,主要怎么配置logging
'''
import logging

def simple_example():
    #默认过滤级别为warning,默认输出到控制台
    logging.warning("warning")
    logging.info("info")

#logging:配置日志级别,输出位置
def logging_to_file():
    '''
    #参数:filename:用指定的文件名创建filedhandler,这样日志会被存储到指定的文件中,如果不指定,则默认输出到控制台
    #参数:filemode默认filemode的默认值"a",表示append,当然你也可以指定为"w"
    #参数:level,一共5个级别,critical(50)>error(40)>warning(30)>info(20)>debug(10),默认级别为Warning,这里可以用对应的数值表示level
    '''

    #将日志信息只输入到指定的文件
    logging.basicConfig(filename="example.log", level=logging.DEBUG)
    # logging.basicConfig(filename="example.log", level=logging.DEBUG, filemode="w")
    # logging.basicConfig(filename="example.log", level=10, filemode="w")
    logging.debug("debu1g")
    logging.info("info")
    logging.warning("info")
    logging.error("error")
    logging.critical("critical")

    # logging variable data:打印变量
    logging.error("logging variable date: %s,%s,%s","var01","var02","var03")

#logging:配置日志格式
def displaying_format_massages():
    '''
    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用户输出的消息
    '''

    # format:指定handler使用的日志显示格式。
    logging.basicConfig(format="%(asctime)s %(filename)s[line:%(lineno)d]%(levelname)s - %(message)s")
    logging.warning("warning")

#logging:配置日志时间格式
def displaying_date_message():
    # datefmt:指定日期时间格式,也就是“%(asctime)s”的格式
    logging.basicConfig(format="%(asctime)s %(filename)s[line:%(lineno)d]%(levelname)s - %(message)s",datefmt="%m/%d/%Y %I:%M:%S %p")
    logging.warning("warning")

if __name__ == "__main__":
    #test
    displaying_date_message()

logging高级进阶

我们直接上代码了,先对logging的高级应用做一个简单的流程梳理,具体仔细的东西,后面慢慢看。代码中也有很多注释,所以看起来应该不是很费劲。

##亭子
#!/usr/bin/env python3
# -*- coding:utf-8 -*-

'''
对logging进行更加灵活的控制:需要了解Logger,Handler,Formatter,Filter

步骤
1. 创建logger实例并配置
2. 创建formatter对象
3. 创建你需要的handler对象并配置
4. 将handler加载到logger实例中
5. 写日志

这个模块主要包含了几个内容
1. 输出日志到控制台中
2. 输出日志到指定的日志文件中
3. 输出的日志按照指定的大小来自动管理,当文件达到指定的大小后,自动创建新文件
4. 输出的文件按照时间来自动管理,当文件达到指定的时候后,自动创建新文件
'''

import logging
from logging import handlers
import time

if __name__ =="__main__":
    #初始化logger
    logger = logging.getLogger()
    # 配置日志级别,如果不显示配置,默认为Warning,表示所有warning级别已下的其他level直接被省略,
    # 内部绑定的handler对象也只能接收到warning级别以上的level,你可以理解为总开关
    logger.setLevel(logging.INFO)

    formatter = logging.Formatter(fmt="%(asctime)s %(filename)s[line:%(lineno)d]%(levelname)s - %(message)s",
                                  datefmt="%m/%d/%Y %I:%M:%S %p")  # 创建一个格式化对象

    console = logging.StreamHandler() # 配置日志输出到控制台
    console.setLevel(logging.WARNING) # 设置输出到控制台的最低日志级别
    console.setFormatter(formatter)  # 设置格式
    logger.addHandler(console)

    # file_logging = logging.FileHandler("example.log") # 配置日志输出到文件
    # file_logging.setLevel(logging.WARNING)
    # file_logging.setFormatter(formatter)
    # logger.addHandler(file_logging)

    # 和上面的FIleHandler差不多,只是handler对象可以管理文件大小,当文件大于指定的大小后,会自动将当前文件改名,然后重新创建一个新的同名文件继续输出
    # file_rotating_file = handlers.RotatingFileHandler("cat.log",maxBytes=1024,backupCount=3)
    # file_rotating_file.setLevel(logging.INFO)
    # file_rotating_file.setFormatter(formatter)
    # logger.addHandler(file_rotating_file)

    # 和上面的handler有点类似,不过,它是通过判断文件大小来决定何时重新创建日志文件,而是间隔一定的时候自动创建日志文件。
    # 代表每7天备份文件
    file_time_rotating = handlers.TimedRotatingFileHandler("app.log",when="s",interval=10,backupCount=5)
    file_time_rotating.setLevel(logging.INFO)
    file_time_rotating.setFormatter(formatter)
    logger.addHandler(file_time_rotating)

    #use logger
    logger.debug("debug")
    logger.info("info")
    logger.warning("warning")
    logger.error("error")
    logger.critical("critical message")

    time.sleep(12)

    logger.debug("debug")
    logger.info("info")
    logger.warning("warning")
    logger.error("error")
    logger.critical("critical message")

首先,这里说几个概念,是我们代码里面涉及到的,也是我们这个章节里面比较重要的。那就是“Logger”,“Handler”,“Formatter”,“Filter”,下面做简单的解释

  1. logger提供了应用程序可以直接使用的接口;
  2. handler将(logger创建的)日志记录发送到合适的目的输出;
  3. filter提供了细度设备来决定输出哪条日志记录;(这里我就先不涉及了,为什么,因为我也不懂,后面如果涉及到,再慢慢补充)
  4. formatter决定日志记录的最终输出格式。

Logger

每个程序在输出信息之前都要获得一个Logger。Logger通常对应了程序的模块名,比如聊天工具的图形界面模块可以这样获得它的Logger:
LOG=logging.getLogger(”chat.gui”)
而核心模块可以这样:
LOG=logging.getLogger(”chat.kernel”)

Logger.setLevel(lel):指定最低的日志级别,低于lel的级别将被忽略。debug是最低的内置级别,critical为最高
Logger.addFilter(filt)、Logger.removeFilter(filt):添加或删除指定的filter
Logger.addHandler(hdlr)、Logger.removeHandler(hdlr):增加或删除指定的handler
Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical():可以设置的日志级别

Handler

handler对象负责发送相关的信息到指定目的地。Python的日志系统有多种Handler可以使用。有些Handler可以把信息输出到控制台,有些Logger可以把信息输出到文件,还有些Handler可以把信息发送到网络上。如果觉得不够用,还可以编写自己的Handler。可以通过addHandler()方法添加多个多handler
Handler.setLevel(lel):指定被处理的信息级别,低于lel级别的信息将被忽略
Handler.setFormatter():给这个handler选择一个格式
Handler.addFilter(filt)、Handler.removeFilter(filt):新增或删除一个filter对象

每个Logger可以附加多个Handler。接下来我们就来介绍一些常用的Handler:

1) logging.StreamHandler

使用这个Handler可以向类似与sys.stdout或者sys.stderr的任何文件对象(file object)输出信息。它的构造函数是:StreamHandler([strm])
其中strm参数是一个文件对象。默认是sys.stderr

2) logging.FileHandler

和StreamHandler类似,用于向一个文件输出日志信息。不过FileHandler会帮你打开这个文件。它的构造函数是:FileHandler(filename[,mode])
filename是文件名,必须指定一个文件名。
mode是文件的打开方式。参见Python内置函数open()的用法。默认是’a',即添加到文件末尾。

3) logging.handlers.RotatingFileHandler

这个Handler类似于上面的FileHandler,但是它可以管理文件大小。当文件达到一定大小之后,它会自动将当前日志文件改名,然后创建 一个新的同名日志文件继续输出。比如日志文件是chat.log。当chat.log达到指定的大小之后,RotatingFileHandler自动把文件改名为chat.log.1。不过,如果chat.log.1已经存在,会先把chat.log.1重命名为chat.log.2。。。最后重新创建 chat.log,继续输出日志信息。它的构造函数是:
RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]])
其中filename和mode两个参数和FileHandler一样。
maxBytes用于指定日志文件的最大文件大小。如果maxBytes为0,意味着日志文件可以无限大,这时上面描述的重命名过程就不会发生。
backupCount用于指定保留的备份文件的个数。比如,如果指定为2,当上面描述的重命名过程发生时,原有的chat.log.2并不会被更名,而是被删除。

4) logging.handlers.TimedRotatingFileHandler

这个Handler和RotatingFileHandler类似,不过,它没有通过判断文件大小来决定何时重新创建日志文件,而是间隔一定时间就 自动创建新的日志文件。重命名的过程与RotatingFileHandler类似,不过新的文件不是附加数字,而是当前时间。它的构造函数是:
TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]])
其中filename参数和backupCount参数和RotatingFileHandler具有相同的意义。
interval是时间间隔。
when参数是一个字符串。表示时间间隔的单位,不区分大小写。它有以下取值:
S 秒
M 分
H 小时
D 天
W 每星期(interval==0时代表星期一)
midnight 每天凌晨

说明

文章部分文字内容摘取自:http://www.cnblogs.com/wenwei-blog/p/7196658.html,感谢伟大的互联网。

文章来源:https://blog.csdn.net/a953713428/article/details/78648298

1.logging模块的使用非常简单,引入模块就可以使用。

import logging

logging.debug('This is debug message')
logging.info('This is info message')
logging.warning('This is warning message')

屏幕上打印:
WARNING:root:This is warning message

默认情况下,logging将日志打印到屏幕,日志级别为WARNING; 
日志级别大小关系为:CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET,当然也可以自己定义日志级别。

2.通过logging.basicConfig函数对日志的输出格式及方式做相关配置
 

import logging

logging.basicConfig(filename='log.log',
                    format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S %p',
                    level=10)

logging.critical('c')
logging.fatal('f')
logging.debug('This is debug message')
logging.info('This is info message')
logging.warning('This is warning message')

logging.info('我是一条日志信息')


log.log文件中内容为:
2017-06-21 15:53:51 PM - root - CRITICAL -demo4:  c
2017-06-21 15:53:51 PM - root - CRITICAL -demo4:  f
2017-06-21 15:53:51 PM - root - DEBUG -demo4:  This is debug message
2017-06-21 15:53:51 PM - root - INFO -demo4:  This is info message
2017-06-21 15:53:51 PM - root - WARNING -demo4:  This is warning message
2017-06-21 15:53:51 PM - root - INFO -demo4:  我是一条日志信息

logging.basicConfig函数各参数:

filename: 指定日志文件名
filemode: 和file函数意义相同,指定日志文件的打开模式,’w’或’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()

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

import logging

logging.basicConfig(filename='log.log',
                    format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S %p',
                    level=10)


#定义一个StreamHandler,将INFO级别或更高的日志信息打印到标准错误,并将其添加到当前的日志处理对象#
console = logging.StreamHandler()
console.setLevel(logging.INFO)
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
console.setFormatter(formatter)
logging.getLogger('').addHandler(console)

logging.critical('c')
logging.fatal('f')
logging.debug('This is debug message')
logging.info('This is info message')
logging.warning('This is warning message')

logging.info('我是一条日志信息')

日志文件中同时也输出:

2017-06-21 15:59:13 PM - root - CRITICAL -demo4:  c
2017-06-21 15:59:13 PM - root - CRITICAL -demo4:  f
2017-06-21 15:59:13 PM - root - DEBUG -demo4:  This is debug message
2017-06-21 15:59:13 PM - root - INFO -demo4:  This is info message
2017-06-21 15:59:13 PM - root - WARNING -demo4:  This is warning message
2017-06-21 15:59:13 PM - root - INFO -demo4:  我是一条日志信息

由上我们能看到日志的一般操作循序为:

  1. 创建一个流类型handler用于输出日志到控制台
  2. 定义handler的输出格式formatter
  3. 将handler添加到logging对象
import logging
from logging.handlers import RotatingFileHandler

#定义一个RotatingFileHandler,最多备份5个日志文件,每个日志文件最大10M
Rthandler = RotatingFileHandler('log.log', maxBytes=10*1024*1024,backupCount=5)
Rthandler.setLevel(logging.INFO)
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
Rthandler.setFormatter(formatter)
logging.getLogger('').addHandler(Rthandler)

从上面两个例子来看logging有一个日志处理的主对象basicConfig,其他的都是通过addHandler的方式添加进去的。logging的集中handler方法如下:

- logging.StreamHandler: 日志输出到流,可以是sys.stderr、sys.stdout或者文件
- logging.FileHandler: 日志输出到文件
- 日志回滚方式,实际使用时用RotatingFileHandler和TimedRotatingFileHandler
- logging.handlers.BaseRotatingHandler
- logging.handlers.RotatingFileHandler
- logging.handlers.TimedRotatingFileHandler
- logging.handlers.SocketHandler: 远程输出日志到TCP/IP sockets
- logging.handlers.DatagramHandler:  远程输出日志到UDP sockets
- logging.handlers.SMTPHandler:  远程输出日志到邮件地址
- logging.handlers.SysLogHandler: 日志输出到syslog
- logging.handlers.NTEventLogHandler: 远程输出日志到Windows NT/2000/XP的事件日志
- logging.handlers.MemoryHandler: 日志输出到内存中的制定buffer
- logging.handlers.HTTPHandler: 通过"GET"或"POST"远程输出到HTTP服务器

由于StreamHandler和FileHandler是常用的日志处理方式,所以直接包含在logging模块中,而其他方式则包含在logging.handlers模块中。

5.在配置文件中配置日志信息,类似于我们在java中配置log4j的logging.config:

#logger.conf
###############################################
[loggers]
keys=root,example01,example02
[logger_root]
level=DEBUG
handlers=hand01,hand02
[logger_example01]
handlers=hand01,hand02
qualname=example01
propagate=0
[logger_example02]
handlers=hand01,hand03
qualname=example02
propagate=0
###############################################
[handlers]
keys=hand01,hand02,hand03
[handler_hand01]
class=StreamHandler
level=INFO
formatter=form02
args=(sys.stderr,)
[handler_hand02]
class=FileHandler
level=DEBUG
formatter=form01
args=('myapp.log', 'a')
[handler_hand03]
class=handlers.RotatingFileHandler
level=INFO
formatter=form02
args=('log.log', 'a', 10*1024*1024, 5)
###############################################
[formatters]
keys=form01,form02
[formatter_form01]
format=%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s
datefmt=%a, %d %b %Y %H:%M:%S
[formatter_form02]
format=%(name)-12s: %(levelname)-8s %(message)

定义完logging.config,我们在同一个工程下的所有模块都可以使用它:

import logging
import logging.config

logging.config.fileConfig("logger.conf")
logger = logging.getLogger("example01")

logger.debug('This is debug message')
logger.info('This is info message')
logger.warning('This is warning message')

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值