如果您刚开始学习 Python,想要了解更多内容,欢迎参加 DataCamp 的Python 数据科学入门 课程。
日志级别
一般来说,日志记录(logging)是一种保存由计算机程序生成的日志的方式。日志文件通常包含一系列在您的代码(例如 Python 代码)或操作系统中发生的事件记录。这些事件或消息会写入日志文件,消息或事件也可能是不同用户之间的通信。
通常由开发者决定如何生成日志。也许他们希望记录所开发应用的每一次操作,只在发生错误时记录,或监控并记录用户执行的重要操作。一个重要操作可能是检查哪个终端用户或 IP 地址访问了应用或服务器,如果是一次未成功的尝试,开发者就可以借助日志提供比简单堆栈跟踪更有价值的洞见。
一个不错的例子是:当您在 Linux 上尝试以 sudo 用户身份安装软件,而您并不是 sudo 用户时,您会看到一条消息 "Xyz is not in the sudoers file. This incident will be reported",这条信息会被写入日志文件。
好消息是,Python 自带 logging 模块,开箱即用,无需安装。
Logging 与 Print 函数有何不同?
Logging 与Print 函数 在精神上相似。然而,Print 函数缺少许多对开发者有用的信息。相比之下,Logging 可以记录错误发生的时间戳与行号;它还能将错误或任意信息写入文件、套接字等,并提供五种严重性级别,便于区分日志。
如此处 所示,日志有五个级别:
Debug (10) :用于诊断代码中的问题。
Info (20) :可作为代码无错误的确认。一个常见用例是记录机器学习模型训练的进度。
Warning (30) :指示未来可能出现的问题。例如,某模块将来可能停用的警告,或内存不足警告。
Error (40) :代码中的严重错误,可能是语法错误、内存不足错误或异常。
Critical (50) :导致程序可能停止运行或异常退出的错误。
理论够多了,对吧?
现在我们来理解如何在 Python 代码中实现日志。
在此之前,先看看日志属性表,今天的教程中您会用到下面的一些日志属性。
Logging Attributes</a
import logging
技术支持
现在您将调用 basicConfig() 方法,它可帮助您创建一个基础配置,使日志系统顺畅运行。 它允许您设置以下参数:
日志记录的严重性:五个日志级别。
将事件记录到文件中。
通过 filemode 覆盖旧日志,仅记录当前日志。
日志的存储格式。
请记住,basicConfig() 方法是可选的,您也可以跳过。
logging. basicConfig( )
技术支持
现在我们来构建五个严重性级别。
logging. debug( "A Debug Logging Message" )
技术支持
logging. info( "A Info Logging Message" )
技术支持
logging. warning( "A Warning Logging Message" )
技术支持
WARNING : root: A Warning Logging Message
技术支持
logging. error( "An Error Logging Message" )
技术支持
ERROR : root: An Error Logging Message
技术支持
logging. critical( "A Critical Logging Message" )
技术支持
CRITICAL : root: A Critical Logging Message
技术支持
从上面的输出可以看到,只有严重性级别高于 20 的日志被成功记录,因为这是 Python 日志记录的默认配置。
不过,如上所述,您可以使用 basicConfig() 方法修改严重性级别。这里将严重性级别改为 20,意味着记录严重性大于 10 的日志。
注意 :请在运行下面的单元格前重启内核,以看到正确输出。
import logging
技术支持
logging. basicConfig( level= logging. INFO)
技术支持
logging. debug( "A Debug Logging Message" )
技术支持
logging. info( "A Info Logging Message" )
技术支持
INFO : root: A Info Logging Message
技术支持
logging. warning( "A Warning Logging Message" )
技术支持
WARNING : root: A Warning Logging Message
技术支持
logging. error( "An Error Logging Message" )
技术支持
ERROR : root: An Error Logging Message
技术支持
logging. critical( "A Critical Logging Message" )
技术支持
CRITICAL : root: A Critical Logging Message
技术支持
现在我们把上述输出记录到一个日志文件中。为此,您将使用 basicConfig() 方法。
import logging
技术支持
logging. basicConfig( level = logging. INFO, filename = 'datacamp.log' )
技术支持
logging. debug( "A Debug Logging Message" )
技术支持
logging. info( "A Info Logging Message" )
技术支持
logging. warning( "A Warning Logging Message" )
技术支持
logging. error( "An Error Logging Message" )
技术支持
logging. critical( "A Critical Logging Message" ) 技术支持
如您所见,现在日志会生成在日志文件 datacamp.log 中。多次运行上述单元后,您会注意到日志会多次追加到该文件中。默认情况下,文件为 append 模式。
您可以使用 filemode 关键字来避免日志文件中出现多份重复日志(即追加模式)。可以将 filemode 改为 write 模式,这会覆盖之前的日志,只保存当前日志。由于 filemode 设为 w,这意味着每次运行 basicConfig() 时,日志文件都会以写入模式打开,并最终被覆盖。
logging 中的文件模式功能与 Python 提供的标准文件处理类似。
import logging
技术支持
logging. basicConfig( level = logging. INFO, filename = 'datacamp.log' , filemode = 'w' )
技术支持
logging. debug( "A Debug Logging Message" )
logging. info( "A Info Logging Message" )
logging. warning( "A Warning Logging Message" )
logging. error( "An Error Logging Message" )
logging. critical( "A Critical Logging Message" )
技术支持
我们多次运行上述代码行。您会注意到,这次只会保存当前的日志条目,之前的会被覆盖,如下所示。
我们再来看一些日志属性,比如生成警告或错误的日期、时间、行号。您可能已经同意,这些都是优于简单 Print 函数的优势,Logging 的能力远不止于此。
为此,您将传入日志属性 asctime 和 lineno。同时还要传入 message 属性,它是您希望在日志中显示的信息的占位符。所有这些属性将传给 format 方法。
import logging
技术支持
logging. basicConfig( format = 'Date-Time : %(asctime)s : Line No. : %(lineno)d - %(message)s' , \
level = logging. DEBUG)
技术支持
logging. debug( "A Debug Logging Message" )
logging. info( "A Info Logging Message" )
logging. warning( "A Warning Logging Message" )
logging. error( "An Error Logging Message" )
logging. critical( "A Critical Logging Message" )
技术支持
Date- Time : 2020 - 03 - 18 23 : 58 : 12 , 429 : Line No. : 1 - A Debug Logging Message
Date- Time : 2020 - 03 - 18 23 : 58 : 12 , 436 : Line No. : 2 - A Info Logging Message
Date- Time : 2020 - 03 - 18 23 : 58 : 12 , 437 : Line No. : 3 - A Warning Logging Message
Date- Time : 2020 - 03 - 18 23 : 58 : 12 , 440 : Line No. : 4 - An Error Logging Message
Date- Time : 2020 - 03 - 18 23 : 58 : 12 , 441 : Line No. : 5 - A Critical Logging Message
技术支持
让我们直接从这张表 看看各属性的定义。
asctime:生成 LogRecord 时的人类可读时间。默认形式为 2020-03-18 22:24:42,670(逗号后的数字为毫秒)。由于该属性是字符串,因此后面使用 s 关键字。
lineno:调用日志记录的源代码行号。该属性是整数,因此后面使用 d 关键字。
message:已记录的消息,计算方式为 msg % args。该值在调用 Formatter.format() 时设置。如果在使用 format() 参数时不指定此属性,您希望记录的消息将不会生成。类似地,对于 message 属性,由于其为字符串,因此使用 s。
funcName:输出生成日志的模块或函数名。当您的代码中有很多函数,并希望根据所属函数或方法对日志进行区分时非常有用。
我们用一个简单例子看看如何用 logging 的 debug 功能替代 print 函数。
import logging
logging. basicConfig( format = '% ( asctime) s : : % ( levelname) s : : % ( funcName) s : : % ( lineno) d \
: : % ( message) s', level = logging. INFO)
def addition ( x, y) :
add = x + y
return add
def subtract ( x, y) :
sub = x - y
return sub
def multiply ( x, y) :
mul = x * y
return mul
def divide ( x, y) :
div = x / y
return div
def exponent ( x, y) :
exp = x ** y
return exp
num1 = 20
num2 = 2
def main ( ) :
add_result = addition( num1, num2)
logging. info( 'Add: {} + {} = {}' . format ( num1, num2, add_result) )
sub_result = subtract( num1, num2)
logging. info( 'Sub: {} - {} = {}' . format ( num1, num2, sub_result) )
mul_result = multiply( num1, num2)
logging. info( 'Mul: {} * {} = {}' . format ( num1, num2, mul_result) )
div_result = divide( num1, num2)
logging. info( 'Div: {} / {} = {}' . format ( num1, num2, div_result) )
exp_result = exponent( num1, num2)
logging. info( 'Exp: {} ** {} = {}' . format ( num1, num2, exp_result) )
main( )
技术支持
2020 - 03 - 19 00 : 01 : 27 , 372 : : INFO : : main : : 35 : : Add: 20 + 2 = 22
2020 - 03 - 19 00 : 01 : 27 , 376 : : INFO : : main : : 38 : : Sub: 20 - 2 = 18
2020 - 03 - 19 00 : 01 : 27 , 377 : : INFO : : main : : 41 : : Mul: 20 * 2 = 40
2020 - 03 - 19 00 : 01 : 27 , 378 : : INFO : : main : : 44 : : Div: 20 / 2 = 10.0
2020 - 03 - 19 00 : 01 : 27 , 379 : : INFO : : main : : 47 : : Exp: 20 ** 2 = 400
技术支持
结语
恭喜您完成本教程。
您不妨尝试更多日志属性,了解如何在代码中加以利用。
如有与本教程相关的问题,欢迎在下方评论区留言。
如果您刚开始学习 Python,想要了解更多内容,欢迎参加 DataCamp 的Python 数据科学入门 课程。
如果您刚开始学习 Python,想要了解更多内容,欢迎参加 DataCamp 的Python 数据科学入门课程。
一般来说,日志记录(logging)是一种保存由计算机程序生成的日志的方式。日志文件通常包含一系列在您的代码(例如 Python 代码)或操作系统中发生的事件记录。这些事件或消息会写入日志文件,消息或事件也可能是不同用户之间的通信。
通常由开发者决定如何生成日志。也许他们希望记录所开发应用的每一次操作,只在发生错误时记录,或监控并记录用户执行的重要操作。一个重要操作可能是检查哪个终端用户或 IP 地址访问了应用或服务器,如果是一次未成功的尝试,开发者就可以借助日志提供比简单堆栈跟踪更有价值的洞见。
一个不错的例子是:当您在 Linux 上尝试以 sudo 用户身份安装软件,而您并不是 sudo 用户时,您会看到一条消息 "Xyz is not in the sudoers file. This incident will be reported",这条信息会被写入日志文件。
好消息是,Python 自带 logging 模块,开箱即用,无需安装。
Logging 与 Print 函数有何不同?
Logging 与
Print 函数在精神上相似。然而,Print 函数缺少许多对开发者有用的信息。相比之下,Logging 可以记录错误发生的时间戳与行号;它还能将错误或任意信息写入文件、套接字等,并提供五种严重性级别,便于区分日志。如此处所示,日志有五个级别:
Debug (10):用于诊断代码中的问题。
Info (20):可作为代码无错误的确认。一个常见用例是记录机器学习模型训练的进度。
Warning (30):指示未来可能出现的问题。例如,某模块将来可能停用的警告,或内存不足警告。
Error (40):代码中的严重错误,可能是语法错误、内存不足错误或异常。
Critical (50):导致程序可能停止运行或异常退出的错误。
理论够多了,对吧?
现在我们来理解如何在 Python 代码中实现日志。
在此之前,先看看日志属性表,今天的教程中您会用到下面的一些日志属性。
现在您将调用
basicConfig()方法,它可帮助您创建一个基础配置,使日志系统顺畅运行。它允许您设置以下参数:
请记住,
basicConfig()方法是可选的,您也可以跳过。现在我们来构建五个严重性级别。
从上面的输出可以看到,只有严重性级别高于 20 的日志被成功记录,因为这是 Python 日志记录的默认配置。
不过,如上所述,您可以使用
basicConfig()方法修改严重性级别。这里将严重性级别改为 20,意味着记录严重性大于 10 的日志。注意:请在运行下面的单元格前重启内核,以看到正确输出。
现在我们把上述输出记录到一个日志文件中。为此,您将使用
basicConfig()方法。如您所见,现在日志会生成在日志文件
datacamp.log中。多次运行上述单元后,您会注意到日志会多次追加到该文件中。默认情况下,文件为append模式。您可以使用
filemode关键字来避免日志文件中出现多份重复日志(即追加模式)。可以将 filemode 改为write模式,这会覆盖之前的日志,只保存当前日志。由于 filemode 设为w,这意味着每次运行basicConfig()时,日志文件都会以写入模式打开,并最终被覆盖。logging 中的文件模式功能与 Python 提供的标准文件处理类似。
我们多次运行上述代码行。您会注意到,这次只会保存当前的日志条目,之前的会被覆盖,如下所示。
我们再来看一些日志属性,比如生成警告或错误的日期、时间、行号。您可能已经同意,这些都是优于简单 Print 函数的优势,Logging 的能力远不止于此。
为此,您将传入日志属性
asctime和lineno。同时还要传入message属性,它是您希望在日志中显示的信息的占位符。所有这些属性将传给format方法。让我们直接从这张表看看各属性的定义。
asctime:生成 LogRecord 时的人类可读时间。默认形式为2020-03-18 22:24:42,670(逗号后的数字为毫秒)。由于该属性是字符串,因此后面使用s关键字。lineno:调用日志记录的源代码行号。该属性是整数,因此后面使用d关键字。message:已记录的消息,计算方式为 msg % args。该值在调用 Formatter.format() 时设置。如果在使用 format() 参数时不指定此属性,您希望记录的消息将不会生成。类似地,对于 message 属性,由于其为字符串,因此使用s。funcName:输出生成日志的模块或函数名。当您的代码中有很多函数,并希望根据所属函数或方法对日志进行区分时非常有用。我们用一个简单例子看看如何用 logging 的 debug 功能替代 print 函数。
结语
恭喜您完成本教程。
您不妨尝试更多日志属性,了解如何在代码中加以利用。
如有与本教程相关的问题,欢迎在下方评论区留言。
如果您刚开始学习 Python,想要了解更多内容,欢迎参加 DataCamp 的Python 数据科学入门课程。