个性化阅读
专注于IT技术分析

Python日志用法介绍

如果你刚刚开始使用Python, 并且想了解更多信息, 请参加srcmini的Python数据科学入门课程。

Python日志用法介绍1

记录级别

通常, 日志记录是保留从计算机程序生成的日志的一种方式。日志文件通常包含一组在你的代码(例如python代码)或操作系统中发生的事件的记录。这些事件或消息将被写入日志文件, 消息, 或者事件也可以是不同用户之间的通信。

通常取决于开发人员如何生成日志。也许他们想记录他们开发的应用程序的每个操作, 仅在发生错误时记录日志, 或者监视用户执行的基本操作并记录它们。一个基本的操作可能是检查最终用户或IP地址访问的应用程序或服务器, 如果尝试失败, 则开发人员可以从日志中寻求帮助, 并提供比单纯的堆栈跟踪更好的见解。 。

一个很好的例子是当你不是sudo用户时尝试以sudo用户身份在Linux上进行安装。你会看到一条消息” Xyz不在sudoers文件中。将报告此事件”, 该消息写在日志文件中。

好消息是Python带有内置的日志记录模块, 你可以直接使用它, 而无需进行任何安装。

记录与打印功能有何不同?

日志记录在本质上类似于打印功能。但是, 打印功能缺少许多可能对开发人员有用的信息。另一方面, 日志记录可以记录发生错误的时间戳和行号。它可以将错误或任何信息记录到文件, 套接字等中, 并且为你提供五种严重性, 你可以根据它们来区分日志记录。

如下所示, 日志记录分为五个级别:

  • 调试(10):对于诊断代码中的问题很有用。
  • 信息(20):可以确认代码中没有错误。信息级别日志记录的一个很好的用例是训练机器学习模型的进度。
  • 警告(30):表示将来可能发生的问题。例如, 将来可能会中断的模块警告或低内存警告。
  • 错误(40):代码中的一个严重错误, 可能是语法错误, 内存不足错误, 异常。
  • 严重(50):由于错误而导致程序可能停止运行或突然退出。

理论够了吧?

现在, 让我们了解如何在Python代码中实现日志记录。

但是在此之前, 让我们看一下日志记录属性表, 你将在今天的教程中使用以下一些日志记录属性。

Python日志用法介绍2

记录属性

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 = 'srcmini.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")
Python日志用法介绍3

如你所见, 现在正在日志文件srcmini.log中生成日志。多次运行上述单元格后, 你会注意到日志将多次添加到日志文件中。默认情况下, 文件处于追加模式。

Python日志用法介绍4

你可以使用filemode关键字来防止将日志文件写入日志的多个副本, 即追加模式。可以将filemode更改为write模式, 它将覆盖以前的日志, 仅保存当前的日志。由于文件模式设置为w, 这意味着每次运行basicConfig()时, 日志文件都将以写入模式打开, 最终将覆盖该文件。

日志记录中的文件模式功能类似于Python提供的标准文件处理。

import logging
logging.basicConfig(level = logging.INFO, filename = 'srcmini.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")

让我们多次运行以上代码行。你会注意到, 这次只保存了当前日志条目, 而以前的日志条目将被覆盖, 如下所示。

Python日志用法介绍5

让我们看一下其他的日志记录属性, 例如日期, 时间, 行号, 在这些属性中会生成警告或错误。好了, 你可能已经同意, 所有这些都比简单的打印功能更具优势, 并且比单纯的打印功能要强大得多。

为了完成此任务, 你将传递日志记录属性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:这将输出在其中生成日志的模块或函数名称。当你的代码中有很多功能, 并且你想根据日志所属的功能或方法来分隔日志时, 此功能很有用。

让我们举一个简单的例子, 看看如何插入日志调试功能来代替打印功能。

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, 并且想了解更多信息, 请参加srcmini的Python数据科学入门课程。

赞(0)
未经允许不得转载:srcmini » Python日志用法介绍

评论 抢沙发

评论前必须登录!