python中的logging记录日志_python上手 -- 使用logging日志模块

在程序开发过程中,通常会需要错误排查的语句,除了使用输出print或者echo之类的语句外,在python中logging日志模块也可以派上用场。logging模块可以用于记录程序执行的过程,这样非常有利于监测程序运行状态,不光可以在控制台看到运行过程,还可以将日志记录输出到文件里。下面将logging库常用方法及实践案例介绍如下。

(1)logging日志导入

logging是python自带的标准库,无需使用pip来安装。使用时如datetime、random等模块一样直接使用import logging方式即可。

import logging

(2)logging初次使用

使用的时候,先设置一下logging的basicConfig基本配置参数:

logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(levelname)s - %(lineno)d - %(message)s ')

然后定义一个logger对象,调用logging模块的getLogger方法。

logger = logging.getLogger()

然后就可以在程序代码中使用了:

import logging

logging.basicConfig(level=logging.INFO,format='%(asctime)s-%(levelname)s-%(lineno)d-%(message)s')

logger = logging.getLogger()

logger.info("程序开始执行...")

def cal_area(radius=None):

return 3.14*radius*radius

radius = eval(input("请输入半径的值:"))

if radius <=0:

logger.warning("半径不能小于0...")

logger.info("开始计算面积...")

area = cal_area(radius=radius)

logger.info("计算面积结果为:{area}".format(area=area))

运行后,终端显示出来结果为:

F:\learn-Python\tt\venv\Scripts\python.exe F:/learn-Python/tt/test/circle.py

2020-02-19 11:41:57,348 - INFO - 8 - 程序开始执行...

请输入半径的值: 15

2020-02-19 11:42:09,277 - INFO - 17 - 开始计算面积...

2020-02-19 11:42:09,277 - INFO - 19 - 计算面积结果为:706.5

Process finished with exit code 0

如上显示,我们将程序执行过程在终端就记录下来了。

如果想将这个记录存成文件输出,简单操作就是只需要增加一下filename指定就可以:

logging.basicConfig(level=logging.INFO,filename='1.log')

就是在basicConfig参数里将filename参数指定下来,如上面程序代码我们修改一下:

import logging

logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(levelname)s - %(lineno)d - %(message)s ',filename='1.log')

logger = logging.getLogger()

logger.info("程序开始执行...")

def cal_area(radius=None):

return 3.14*radius*radius

radius = eval(input("请输入半径的值:"))

if radius <=0:

logger.warning("半径不能小于0...")

logger.info("开始计算面积...")

area = cal_area(radius=radius)

logger.info("计算面积结果为:{area}".format(area=area))

执行程序时,有关日志就不再会在终端打印了,而是都写到了指定的1.log文件中。

(3)logging应用详解

上面我们通过程序的实践都实现了日志的终端输出和文件记录。这样实现后,以后再在代码中我们就可以不去使用print方式输出有些可能存在代码错误的地方,非常方便监测程序运行状态。下面就一些可以调整的参数做个实践和介绍。basicConfig里的level级别: 这是设置打印日志级别,低于该级别的就不打印输出,高于的才记录。所以有必要了解这个level级别设置。在logging模块里,一共分了5个级别:

1.DEBUG:详细信息,用于诊断问题。Value=10。

2.INFO:确认代码运行正常。Value=20。

3.WARNING:意想不到的事情发生了,或预示着某个问题。但软件仍按预期运行。value=30

4.ERROR:出现更严重的问题,软件无法执行某些功能。Value=40。

5.CRITICAL:严重错误,程序本身可能无法继续运行。Value=50

这5个级别从重要性来看,肯定4和5要严重一些。但从全面性来看,1和2记录信息更详细一些。所以在basicConfig(level=logging.LEVEL)这个LEVEL参数这可以用上述5个英文单词替换。使用LEVEL为DEBUG或者INFO时,就是较为详细的记录日志。

2. basicConfig里的format,这是日志输出时的格式定义。上述代码中format=‘%(asctime)s’这个asctime参数是当前时间,%s 是以字符串格式输出。'%(levelname)s' 这个levelname就是级别名称,包括INFO、WARNING、ERROR和CRITICAL等。’%(lineno)d‘这个是日志输出所在的行号,以%d整型方式输出。’%(message)s‘这里的message就是消息参数,后面在http://logger.info(message)这里给出具体的值。而logging模块里还有很多类似的格式控制符:

%(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: 打印日志信息

我们可以测试一下,打印一下filename信息:

import logging

logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s ',filename='2.log')

logger = logging.getLogger()

logger.info("程序开始执行...")

def cal_area(radius=None):

return 3.14*radius*radius

radius = eval(input("请输入半径的值:"))

if radius <=0:

logger.warning("半径不能小于0...")

logger.info("开始计算面积...")

area = cal_area(radius=radius)

logger.info("计算面积结果为:{area}".format(area=area))

输出的日志文件中内容为:

2020-02-19 13:09:18,021 - circle.py[line:5] - INFO: 程序开始执行...

2020-02-19 13:09:20,885 - circle.py[line:14] - INFO: 开始计算面积...

2020-02-19 13:09:20,885 - circle.py[line:16] - INFO: 计算面积结果为:78.5

3. 如果将basicConfig配置拆分,变为直接对象属性设置,如果想直接在控制台输出,可以设置输出流StreamHandler:

import logging

log_level =logging.INFO

logger = logging.getLogger("for this file")

logger.setLevel(log_level)

#控制台输出流,设置输出级别

ch = logging.StreamHandler()

ch.setLevel(logging.DEBUG)

#创建formatter格式化器

formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

#将formatter 添加到ch处理器

ch.setFormatter(formatter)

#将ch添加到logger

logger.addHandler(ch)

logger.info("the program starting ... ")

def test():

print("welcome to my apps!")

test()

logger.info('程序执行完成...')

如果想输出为日志文件,则可以这样:

import logging

log_file = '4.log'

log_level =logging.INFO

logger = logging.getLogger("for this file")

logger.setLevel(log_level)

#文件流输出,设置输出级别

fh = logging.FileHandler(log_file)

fh.setLevel(logging.DEBUG)

#创建formatter格式化器

formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

#将formatter 添加到ch处理器

fh.setFormatter(formatter)

#将ch添加到logger

logger.addHandler(fh)

logger.info("the program starting ... ")

def test():

print("welcome to my apps!")

test()

logger.info('程序执行完成...')

输出在4.log文件里,打开为:

2020-02-19 13:32:21,407 - for this file - INFO - the program starting ...

2020-02-19 13:32:21,407 - for this file - INFO - 程序执行完成...

(4)logging模块应用实践

从上面我们实践的简单例子来看,都是将logging日志配置相关代码与实际程序运行代码混杂在一起的,这样显得程序比较重,当然我们都还是用的简单程序,如果是复杂的工程类项目,每个业务代码里都嵌入这样的logging配置肯定是不科学的,因此一般在实际应用中通常会单独来个python包或者模块用于配置logging,然后其他的业务代码文件中直接import来使用。

我们来实践一下,首先我们建立一个py文件,命名为logBase.py,专门用于设置logging相关配置:

import logging

class logBase(): #建立日志类

def __init__(self,appName=None):

self.log_level = logging.INFO #设置日志级别

self.appName = appName #设置当前程序名

def logCreator(self): #创建日志

logging.basicConfig(level=self.log_level,format='%(asctime)s - %(name)s - %(lineno)d - %(message)s')

logger = logging.getLogger(self.appName)

return logger

然后我们可以在同一级别目录下新建另外一个py文件,命名为main.py,输入如下代码:

from .logBase import logBase #导入日志配置文件

logger = logBase(appName='main').logCreator() #建立一个日志对象

class Weather():

def __init__(self):

pass

def RecordInfo(self):

print("接最新天气预报.....")

print("今天,天津天气,雨雾,湿气大,不适宜出门")

def Action(self,choice=None):

if not choice:

logger.warning("还没给出选择方案...")

return False

elif choice == '1':

msg = "我们在家做好吃的东西,然后开个PARTY"

elif choice == '2':

msg = '我们还是想出去转转,试试看是否有新的发现'

logger.info("执行方案: {choice}".format(choice=choice))

return msg

if __name__=='__main__':

logger.info('start to connect with weather database ...') #加入日志记录

t = Weather()

t.RecordInfo()

print(t.Action())

也就是当创建好日志logging配置文件后,在其他模块或者业务代码中只需要导入这个模块,然后开始使用logger对象就可以进行日志记录了。这样就方便了很多。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值