当前位置: 首页 > news >正文

Python程序设计 内置函数 日志模块

logging(日志)

日志记录是程序员工具箱中非常有用的工具。它可以帮助您更好地理解程序的流程,并发现您在开发过程中可能没有想到的场景。

日志为开发人员提供了额外的一组眼睛,这些眼睛不断关注应用程序正在经历的流程。它们可以存储信息,例如访问应用程序的用户或IP。如果发生错误,那么通过告诉您程序在到达发生错误的代码行之前的状态,它们可以提供比堆栈跟踪更多的见解。

通过从正确的位置记录有用的数据,您不仅可以轻松地调试错误,还可以使用数据分析应用程序的性能以规划扩展或查看使用模式以规划营销。

Python提供了一个日志系统作为其标准库的一部分,因此您可以快速将日志记录添加到您的应用程序中。在本文中,您将了解为什么使用此模块是向应用程序添加日志记录以及如何快速入门的最佳方式,您将了解一些可用的高级功能。

Logging模块

Python中的日志记录模块是一个随时可用且功能强大的模块,旨在满足初学者和企业团队的需求。它被大多数第三方Python库使用,因此您可以将日志消息与这些库中的日志消息集成,以为您的应用程序生成同类日志。

将记录添加到Python程序就像这样简单:

import logging

导入日志记录模块后,您可以使用称为“logger”的内容来记录您要查看的消息。默认情况下,有5个标准级别指示事件的严重性。每个都有一个相应的方法,可用于记录该严重级别的事件。按严重程度增加的顺序定义的级别如下:

  • DEBUG
  • 信息 info
  • 警告 warning
  • 错误 error
  • 危急 critical

日志记录模块为您提供了一个默认记录器,使您无需进行太多配置即可开始使用。可以调用每个级别的相应方法,如以下示例所示:

import logginglogging.debug('这里是调试信息')
logging.info('这里是详情信息')
logging.warning('这里是警告信息')
logging.error('这里是错误信息')
logging.critical('这里是危机信息')

上述程序的输出如下所示:

WARNING:root:这里是警告信息
ERROR:root:这里是错误信息
CRITICAL:root:这里是危机信息

输出显示每条消息之前的严重性级别root,即日志记录模块为其默认记录器提供的名称。(记录器将在后面的章节中详细讨论。)此格式显示由冒号(:)分隔的级别,名称和消息,是默认的输出格式,可以配置为包括时间戳,行号和其他内容细节。

请注意,并没有记录debug()info()消息。这是因为,默认情况下,日志记录模块会记录严重性级别为WARNING或更高的邮件。您可以通过将日志记录模块配置为根据需要记录所有级别的事件来更改它。您还可以通过更改配置来定义自己的严重性级别,但通常不建议这样做,因为它可能会导致您可能正在使用的某些第三方库的日志混淆。

基本配置

您可以使用该方法配置日志记录:basicConfig(**kwargs)

一些常用的参数basicConfig()如下:

  • level:根记录器将设置为指定的严重性级别。
  • filename:这指定文件。
  • filemode:如果filename给定,则以此模式打开文件。默认值为a,表示追加。
  • format:这是日志消息的格式。

通过使用该level参数,您可以设置要记录的日志消息级别。这可以通过传递类中可用的一个常量来完成,这将允许记录该级别或更高级别的所有日志记录调用。这是一个例子:

import logginglogging.basicConfig(level=logging.DEBUG)
logging.debug('This will get logged')

 DEBUG:root:This will get logged

DEBUG现在将记录DEBUG级别或更高级别的事件。

同样,对于记录到文件而不是控制台,filename并且filemode可以使用,您可以使用确定消息的格式format。以下示例显示了所有三个的用法:

import logginglogging.basicConfig(filename='app.log', filemode='w', format='%(name)s - %(levelname)s - %(message)s')
logging.warning('This will get logged to a file')

 root - ERROR - This will get logged to a file

该消息将如下所示,但将写入名为app.log而不是控制台的文件。filemode设置为w,这意味着每次basicConfig()调用日志文件都以“写入模式”打开,程序的每次运行都将重写该文件。filemode的默认配置a是append。

您可以使用更多参数进一步自定义根记录器basicConfig(),可在此处找到。

应该注意,basicConfig()只有在之前没有配置根记录器的情况下,调用配置根记录器才有效。基本上,这个函数只能调用一次。

debug()info()warning()error(),和critical()也称basicConfig()自动无参数,如果它以前没有叫。这意味着在第一次调用上述函数之一后,您无法再配置根记录器,因为它们会在basicConfig()内部调用该函数。

默认设置basicConfig()是将记录器设置为以下列格式写入控制台:

ERROR:root:This is an error message

格式化输出

虽然您可以将任何可以表示为字符串的变量作为消息传递给您的日志,但是有一些基本元素已经成为其中的一部分,LogRecord并且可以轻松添加到输出格式中。如果要将进程ID与级别和消息一起记录,可以执行以下操作:

import logginglogging.basicConfig(format='%(process)d-%(levelname)s-%(message)s')
logging.warning('This is a Warning')

18472-WARNING-This is a Warning

format可以使用LogRecord您喜欢的任何排列中的属性字符串。可以在此处找到可用属性的完整列表。

这是另一个可以添加日期和时间信息的示例:

import logginglogging.basicConfig(format='%(asctime)s - %(message)s', level=logging.INFO)
logging.info('Admin logged in')

 2018-07-11 20:12:06,288 - Admin logged in

%(asctime)s增加了创造时间LogRecord。可以使用datefmt属性更改格式,该属性使用与datetime模块中的格式化函数相同的格式化语言,例如time.strftime()

import logginglogging.basicConfig(format='%(asctime)s - %(message)s', datefmt='%d-%b-%y %H:%M:%S')
logging.warning('Admin logged out')

 12-Jul-18 20:53:19 - Admin logged out

记录变量数据

在大多数情况下,您可能希望在日志中包含应用程序中的动态信息。您已经看到日志记录方法将字符串作为参数,并且在单独的行中使用可变数据格式化字符串并将其传递给log方法似乎很自然。但实际上,这可以通过使用消息的格式字符串并将变量数据作为参数附加来直接完成。这是一个例子:

import loggingname = 'John'logging.error('%s raised an error', name)

类和函数

到目前为止,我们已经看到了一个名为默认记录器root,用于通过日志模块,只要其功能被直接称为是这样的:logging.debug()。您可以(并且应该)通过创建Logger类的对象来定义自己的记录器,尤其是在应用程序具有多个模块的情况下。我们来看看模块中的一些类和函数。

日志记录模块中定义的最常用类如下:

  • **Logger:**这是一个类,其对象将直接在应用程序代码中用于调用函数。
  • **LogRecord:**记录器自动创建LogRecord具有与记录事件相关的所有信息的对象,例如记录器的名称,功能,行号,消息等。
  • **Handler:**处理程序将LogRecord控制器或文件发送到所需的输出目标。Handler对于像的子类的碱StreamHandlerFileHandlerSMTPHandlerHTTPHandler,等等。这些子类将日志记录输出发送到相应的目标,如sys.stdout磁盘文件。
  • **Formatter:**您可以通过指定列出输出应包含的属性的字符串格式来指定输出的格式。

其中,我们主要处理Logger类的对象,这些对象使用模块级函数进行实例化logging.getLogger(name)getLogger()使用相同的多次调用name将返回对同一Logger对象的引用,这使我们无法将记录器对象传递到需要它的每个部分。这是一个例子:

import logginglogger = logging.getLogger('example_logger')
logger.warning('This is a warning')

This is a warning

同样,与根记录器不同,无法使用自定义记录器进行配置basicConfig()。您必须使用处理程序和格式化程序对其进行配置:

使用Handler

当您想要配置自己的记录器并在生成日志时将日志发送到多个位置时,处理程序就会出现。处理程序将日志消息发送到已配置的目标(如标准输出流或文件或HTTP)或通过SMTP发送到您的电子邮件。

您创建的记录器可以有多个处理程序,这意味着您可以将其设置为保存到日志文件并通过电子邮件发送。

与记录器一样,您也可以在处理程序中设置严重性级别。如果要为同一记录器设置多个处理程序但希望每个处理程序具有不同的严重性级别,这将非常有用。例如,您可能希望将具有级别WARNING及更高级别的日志记录到控制台,但是具有级别ERROR及更高级别的所有内容也应保存到文件中。这是一个执行该操作的程序:

# logging_example.pyimport logging# Create a custom logger
logger = logging.getLogger(__name__)# Create handlers
c_handler = logging.StreamHandler()
f_handler = logging.FileHandler('file.log')
c_handler.setLevel(logging.WARNING)
f_handler.setLevel(logging.ERROR)# Create formatters and add it to handlers
c_format = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
f_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
c_handler.setFormatter(c_format)
f_handler.setFormatter(f_format)# Add handlers to the logger
logger.addHandler(c_handler)
logger.addHandler(f_handler)logger.warning('This is a warning')
logger.error('This is an error')

 __main__ - WARNING - This is a warning
__main__ - ERROR - This is an error

在这里,logger.warning()创建一个LogRecord包含事件的所有信息并将其传递给它拥有的所有处理程序:c_handlerf_handler

c_handler是一个StreamHandler带有级别WARNING并从中获取信息LogRecord以生成指定格式的输出并将其打印到控制台。f_handler是一个FileHandler 有级别的 ERROR,它忽略LogRecord了它的级别WARNING

logger.error()调用时,c_handler 行为与以前完全相同,并f_handler获得a LogRecord级别ERROR,因此它继续生成输出c_handler,但不是将其打印到控制台,而是以这种格式将其写入指定的文件:

2018-08-03 16:12:21,723 - __main__ - ERROR - This is an error

将与__name__变量对应的记录器的名称记录为__main__,这是Python分配给执行开始的模块的名称。如果此文件由某个其他模块导入,则该__name__变量将对应于其名称*logging_example*。这是它的样子:

# run.pyimport logging_example
logging_example - WARNING - This is a warning
logging_example - ERROR - This is an error

保持冷静并阅读日志

记录模块被认为非常灵活。它的设计非常实用,应该适合您的开箱即用。您可以将基本日志记录添加到一个小项目中,或者如果您正在处理一个大项目,则可以创建自己的自定义日志级别,处理程序类等。

如果您还没有在应用程序中使用日志记录,那么现在是开始的好时机。完成后,日志记录肯定会消除开发过程中的大量摩擦,并帮助您找到将应用程序提升到新的水平的机会。

Python 日志模块详解及应用
日志概述

百度百科的日志概述

Windows网络操作系统都设计有各种各样的日志文件,如应用程序日志,安全日志、系统日志、Scheduler服务日志、FTP日志、WWW日志、DNS服务器日志等等,这些根据你的系统开启的服务的不同而有所不同。我们在系统上进行一些操作时,这些日志文件通常会记录下我们操作的一些相关内容,这些内容对系统安全工作人员相当有用。比如说有人对系统进行了IPC探测,系统就会在安全日志里迅速地记下探测者探测时所用的IP、时间、用户名等,用FTP探测后,就会在FTP日志中记下IP、时间、探测所用的用户名等。

我映像中的日志

查看日志是开发人员日常获取信息、排查异常、发现问题的最好途径,日志记录中通常会标记有异常产生的原因、发生时间、具体错误行数等信息,这极大的节省了我们的排查时间,无形中提高了编码效率。

日志分类

我们可以按照输出终端进行分类,也可以按照日志级别进行分类。输出终端指的是将日志在控制台输出显示和将日志存入文件;日志级别指的是 Debug、Info、WARNING、ERROR以及CRITICAL等严重等级进行划分。

Python 的 logging

logging提供了一组便利的日志函数,它们分别是:debug()、 info()、 warning()、 error() 和 critical()。logging函数根据它们用来跟踪的事件的级别或严重程度来命名。标准级别及其适用性描述如下(以严重程度递增排序):

每个级别对应的数字值为 CRITICAL:50,ERROR:40,WARNING:30,INFO:20,DEBUG:10,NOTSET:0。 Python 中日志的默认等级是 WARNING,DEBUG 和 INFO 级别的日志将不会得到显示,在 logging 中更改设置。

日志输出

输出到控制台

使用 logging 在控制台打印日志,这里我们用 Pycharm 编辑器来观察:

import logginglogging.debug('调试信息')
logging.warning('警告信息')
logging.info('详情信息')

从上图运行的结果来看,的确只显示了 WARNING 级别的信息,验证了上面的观点。同时也在控制台输出了日志内容,默认情况下 Python 中使用 logging 模块中的函数打印日志,日志只会在控制台输出,而不会保存到日文件。

有什么办法可以改变默认的日志级别呢?

当然是有的,logging 中提供了 basicConfig 让使用者可以适时调节默认日志级别,我们可以将上面的代码改为:

import logginglogging.basicConfig(level=logging.INFO)
logging.debug('调试信息')
logging.info('详情信息')
logging.warning('警告信息')

在 basicConfig 中设定 level 参数的级别即可。

保存到文件

刚才演示了如何在控制台输出日志内容,并且自由设定日志的级别,那现在就来看看如何将日志保存到文件。依旧是强大的 basicConfig,我们再将上面的代码改为:

import logginglogging.basicConfig(level=logging.DEBUG, filename='coder.log', filemode='a')
logging.debug('调试信息')
logging.info('详情信息')
logging.warning('警告信息')

在配置中填写 filename (指定文件名) 和 filemode (文件写入方式),控制台的日志输出就不见了,那么 coder.log 会生成么?

在 .py 文件的同级目录生成了名为 coder.log 的日志。        

通过简单的代码设置,我们就完成了日志文件在控制台和文件中的输出。

相关文章:

Python程序设计 内置函数 日志模块

logging(日志) 日志记录是程序员工具箱中非常有用的工具。它可以帮助您更好地理解程序的流程,并发现您在开发过程中可能没有想到的场景。 日志为开发人员提供了额外的一组眼睛,这些眼睛不断关注应用程序正在经历的流程。它们可以存储信息,例…...

中标麒麟v5安装qt512.12开发软件

注意 需要联网操作 遇到问题1:yum提示没有可用软件包问题 终端执行如下命令 CentOS7将yum源更换为国内源保姆级教程 中标麒麟V7-yum源的更换(阿里云源) wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Cento…...

每日算法一练:剑指offer——数组篇(3)

1.报数 实现一个十进制数字报数程序,请按照数字从小到大的顺序返回一个整数数列,该数列从数字 1 开始,到最大的正整数 cnt 位数字结束。 示例 1: 输入:cnt 2 输出:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,1…...

Java代码说明设计模式

以下是使用 Java 代码分别说明设计模式中的工厂模式、抽象工厂模式(这里推测你可能想说的是抽象工厂模式而非虚拟工厂模式)、建造者模式和观察者模式。 一、工厂模式 工厂模式是一种创建对象的设计模式,它提供了一种创建对象的方式&#xf…...

Golang笔记_day06

一、GMP 调度器 1、调度器理解思路 理解golang的调度器要从进程到协程演进来说明: 进程--->线程--->协程---> golang的协程(goroutine) 从上图可以看出,进程到多线程到协程,最终目的就是为了提高CPU的利用率…...

「从零开始的 Vue 3 系列」:第十一章——跨域问题解决方案全解析

前言 本系列将从零开始,系统性地介绍 Vue 3 的常用 API,逐步深入每个核心概念与功能模块。通过详尽的讲解与实战演示,帮助大家掌握 Vue 3 的基础与进阶知识,最终具备独立搭建完整 Vue 3 项目的能力。 第十一章:跨域问…...

C语言结构体数组 java静动数组及问题

1. (1)先声明,后定义:如上一天 //(2).声明时直接定义 #define N 5 typedef struct student { int num; int score; }STU; int main(void) { STU class3[N] { {10,90},{14,70},{8,95} }; …...

uniapp项目结构基本了解

基本结构的解释 App.vue:应用的根组件,定义全局布局和逻辑。pages/:存放各个页面的 .vue 文件,定义应用的具体页面和功能模块。main.js:应用入口文件,初始化应用,挂载 App.vue。manifest.json&…...

常见Web知识1

List item 常见Web知识1 JSON: JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人类阅读和编写,同时也易于机器解析和生成。它通常用于客户端和服务器之间的数据传输。 JSON 结构 JSON 主要由两…...

新版idea菜单栏展开与合并

新版idea把菜单栏合并了看着很是不习惯,找了半天原来在这里展开 ① 点击文件 -> 设置 ② 点击外观与行为 -> 外观 -> 合并主菜单和窗口标题 然后确定,重启即可...

聊聊Go语言的异常处理机制

背景 最近因为遇到了一个panic问题,加上之前零零散散看了些关于程序异常处理相关的东西,对这块有点兴趣,于是整理了一下golang对于异常处理的机制。 名词介绍 Painc golang的内置方法,能够改变程序的控制流。 当函数调用了pan…...

复习:如何理解 React 中的 fiber

React 中的 Fiber 可以理解为 React 16 引入的一种新的协调(reconciliation)引擎,旨在提高 React 应用的性能和响应性。以下是对 React Fiber 的详细解释: 一、Fiber 的定义与背景 Fiber 是对 React 核心算法的一次重新实现,它将渲染工作分解成一系列小的任务单元,这些任…...

10分钟了解腾讯云混元大模型AIGC系列产品

前言 其实说到AIGC,作为开发者,大家其实已经见怪不怪了,那么AIGC是什么,这里我再简单科普一下。 AIGC的全称是Artificial Intelligence Generated Content (人工智能生成内容)或者说叫生成式人工智能&…...

Unity发送Http

本篇实现在Unity中发送Http请求。 讲解Get,Post,用于在Unity中进行数据对接。 一、Get IEnumerator Get() {string url "";//链接UnityWebRequest request UnityWebRequest.Get(url);//创建UnityWebRequest实例并设置请求方式为Getyield …...

微服务开发-Nacos服务治理

注册中心原理 流程如下: 服务启动时就会注册自己的服务信息(服务名、IP、端口)到注册中心;调用者可以从注册中心订阅想要的服务,获取服务对应的实例列表(1个服务可能多实例部署);调…...

鸿蒙开发:两个重磅更新,鸿蒙版微信要来了!

从媒体消息中,其实我们已经知道,华为纯血鸿蒙系统(HarmonyOS NEXT)于10月8日正式开启了公测,对应的官方文档,大家可以看到已由原来的Beta版本更新到了Release,NEXT终于迎来了正式版本。 文档更新…...

es kibana .logstash离线集群安装

es离线集群安装 下载对应的版本一般看你客户端引用的是什么版本我这里下载的是7.6.2 官方下载地址:https://www.elastic.co/cn/downloads/elasticsearch 源码安装-环境准备:在etc/hosts文件添加3台主机 node-001 192.168.1.81 node-002 19…...

Java项目-基于springboot框架的基于协同过滤算法商品推荐系统项目实战(附源码+文档)

作者:计算机学长阿伟 开发技术:SpringBoot、SSM、Vue、MySQL、ElementUI等,“文末源码”。 开发运行环境 开发语言:Java数据库:MySQL技术:SpringBoot、Vue、Mybaits Plus、ELementUI工具:IDEA/…...

JAVA使用easyExcel导出数据到EXCEl,导出数据不全问题解决

JAVA使用easyExcel导出数据到EXCEl,导出数据不全问题解决 问题描述解决思路一解决思路二温馨提示 问题描述 JAVA使用easyExcel导出数据到EXCEl,导出数据不全问题。 导出的excel部分列有数据,好几列没有数据 解决思路一 从网上百度查询,大多数的解决思路…...

2-130 基于经验模态分解(EMD)的信号分解

基于经验模态分解(EMD)的信号分解。通过仿真信号构造待分解信号,经过分解后得到信号希尔伯特时频图,可视化展示不同分解信号频率段。程序已调通,可直接运行。 下载源程序请点链接:2-130 基于经验模态分解&…...

openlayers 测量功能实现(测距测面)- vue3

一、配置openlayer环境 借鉴:Vue 3 OpenLayers 的简单使用_vue3 openlayers-CSDN博客 二、代码如下(测距、测面和清除) measurs.js: import {ref} from vue; import Draw from ol/interaction/Draw import VectorSource from ol/source/…...

各种语言的序列化与反序列化(C/C++ c# Python Javascript Java)

序列化是指将程序中的对象转换为字节序列的过程,使得对象的状态可以在网络上传输或存储到文件中。反序列化则是将字节序列恢复为程序中的对象的过程。这两个过程是数据持久化和远程通信中的关键步骤。 1. C 序列化与反序列化 在 C 中,标准库没有提供内…...

RHCE笔记

第二章:时间服务器 东八区:UTC8CST(北京时间) 应用层的时间协议:NTP(网络时间协议):udp/端口:123 Chrony软件:由chronyd(客户端)和chronyc(服务…...

Android 设置控件为圆形

Android的圆形控件 对于所有的View有效 在开发的过程中,肯定需要实现一个圆形的控件,而且不是绘制一个圆形,那么怎么弄呢,在Android5.0后,有一个类ViewOutlineProvider,可以实现这个功能,应该是…...

qt/c++中成员函数返回成员变量并且可以赋值

#创作灵感 最近在做仪表项目,由于客户提供的仪表故障指示灯只有10个固定位置,而故障指示灯却有80多个。为了解决这个问题,进过我的设计,项目中需要返回类的成员变量。并且还可以赋值给它。于是就产生了下面的代码。 class Foo { …...

【网络安全】IDOR与JWT令牌破解相结合,实现编辑、查看和删除数万帐户

未经许可,不得转载。 文章目录 前言漏洞1漏洞2修复建议在今年4月17日,笔者发过一篇关于 JWT 的文章,未学习过或稍有遗忘的朋友可以点击跳转:【网络安全 | 密码学】JWT基础知识及攻击方式详析 现分享一篇与 JWT 有关的漏洞挖掘案例。 前言 我在某公共漏洞奖励计划的应用程…...

docker安装与镜像打包

文章目录 前言一、docker安装1.1、下载docker安装包1.2、解压1.3、移动1.4、docker注册成系统服务1.5、添加文件权限1.6、设置开机启动1.7、启动docker1.8、测试是否启动 二、镜像加载2.1、镜像准备2.2、加载镜像2.3、查看已加载镜像2.4、进入镜像 三、打包镜像3.1、创建 Docke…...

“新物种”即将上线,极氪MIX是近几年最“好玩”的新车?

像极氪MIX这样有创意的新能源车 除了概念车外,市面上真的很少能看到类似的量产车 别致可爱的造型、新颖的对开门设计、百变的空间布局 同时兼顾了MPV大空间以及SUV的操控乐趣和通过性 妥妥的“新物种” A级车车长D级车轴距,配合隐藏式双B柱电动对开…...

【Flutter】路由与导航:复杂导航与深度链接

在开发大型 Flutter 应用时,复杂的导航管理是不可避免的。除了基本的页面跳转与返回操作外,很多应用会用到 嵌套路由、页面分组、TabBar 和 Drawer 的结合使用等复杂导航场景,甚至支持 深度链接 和 动态路由。本文将深入探讨这些高级导航技巧…...

07 实战:视频捕获

代码如下: import tkinter as tk # 导入tkinter库,用于创建图形用户界面 from tkinter import ttk, filedialog, messagebox # 导入tkinter的额外部件、文件对话框和消息框 import cv2 # 导入OpenCV库,用于图像处理 import numpy as np # 导入NumPy库,用于数值计算 from P…...