keil debug如何在watch直接修改变量值_python日志记录系列教程,内置logging模块(一),直接使用logging模块的基础日志记录

前言:成熟的软件开发不可避免的要进行日志记录,python内置模块logging提供了强大的日志记录能力,本文将从多个角度,由浅入深的介绍logging的常见使用方法和一些基本概念,本此系列文章分为两篇,本文为系列文章第一篇,介绍实用logging模块进行基本的日志记录操作。本文主要都是直接使用 logging.xxxx() 的方式,这是最简单初步的日志记录,不涉及任何复杂的类和对象,这些将会在下一篇文章中来说明。

一、什么是日志记录

所谓的日志记录就是对软件执行时所发生事件的一种追踪方式。软件开发人员对他们的代码添加日志调用,借此来指示某事件的发生。一个事件通过一些包含变量数据的描述信息来描述(比如:每个事件发生时的数据都是不同的)。开发者还会区分事件的重要性,重要性也被称为 等级严重性

1.1 什么时候使用 Logging

对于简单的日志使用来说日志功能提供了一系列便利的函数。它们是 debug()info()warning()error()critical()。想要决定何时使用日志,请看下表,其中显示了对于每个通用任务集合来说最好的工具。

你想要执行的任务此任务最好的工具
对于命令行或程序的应用,结果显示在控制台。print(),这是我们自己常用的,显示某一些信息,直接打印结果,但是比较低级
在对程序的普通操作发生时提交事件报告(比如:状态监控和错误调查)http://logging.info() 函数(当有诊断目的需要详细输出信息时使用 logging.debug() 函数)
提出一个警告信息基于一个特殊的运行时事件warnings.warn() 位于代码库中,该事件是可以避免的,需要修改客户端应用以消除告警
logging.warning() 不需要修改客户端应用,但是该事件还是需要引起关注
对一个特殊的运行时事件报告错误引发异常
报告错误而不引发异常(如在长时间运行中的服务端进程的错误处理)logging.error(), logging.exception() 或 logging.critical() 分别适用于特定的错误及应用领域

1.2 日志记录的5个等级

日志功能应以所追踪事件级别或严重性而定。各级别适用性如下(以严重程度递增):

级别何时使用
DEBUG细节信息,仅当诊断问题时适用。
INFO确认程序按预期运行,但是要提示一些相关的信息,
WARNING表明有已经或即将发生的意外(例如:磁盘空间不足)。程序仍按预期进行,但是会有警告,可能出现什么错误。
ERROR由于严重的问题,程序的某些功能已经不能正常执行
CRITICAL严重的错误,表明程序已不能继续执行

以及严重程度排序为:

debug<info<warning<error<critical

默认的级别是``WARNING``,意味着只会追踪该级别以及该级别以上的事件,当然我们可以更改日志配置,重新设置默认值。

另外,我们需要查看所记录的日志,一般日志输出会有两种形式,

所追踪事件可以以不同形式处理。最简单的方式是输出到控制台另一种常用的方式是写入磁盘文件。默认情况下,日志输出信息会显示在控制台上。下面也会以这两种方式来加以说明。

1.3 logging模块初识

571c932a74828a329b8fe708e136a08b.png

二、logging模块的常规基础操作

2.1 logging日志记录的基本配置

函数原型如下:

ff4109fd717c2f57aefe9ea6c34ef516.png

该函数支持以下关键字参数。

格式描述
filename使用指定的文件名而不是 StreamHandler 创建 FileHandler。在需要将日志写入到日志文件的时候使用
filemode日志文件的写入模式.,默认的是"a",默认是追加的方式,若要每一次都重新写入,则使用"w"
format使用的指定格式字符串。
datefmt时间格式的字符串
styleIf format is specified, use this style for the format string. One of '%', '{' or '$' for printf-style, str.format() or string.Template respectively. Defaults to '%'.
字符串的格式化方式的选择,参考下面的style参数详解。
level设置根记录器级别去指定 level.默认的是warning,可以重新指定,比如http://logging.INFO logging.DEBUG 等等,
streamUse the specified stream to initialize the StreamHandler. Note that this argument is incompatible with filename - if both are present, a ValueError is raised.(后面用到了再说)
handlersIf specified, this should be an iterable of already created handlers to add to the root logger. Any handlers which don't already have a formatter set will be assigned the default formatter created in this function. Note that this argument is incompatible with filename or stream - if both are present, a ValueError is raised.(后面用到了再说)

对basicConfig的调用应该在 debug、info等函数的前面。因为它被设计为一次性的配置,只有第一次调用会进行操作,随后的调用不会产生有效操作。

2.2 将日志写入文件

d90dbc0a8994b1a1f9bad0f2cc9698fd.png

2.3 多个模块中使用日志记录

如果你的程序包含多个模块,这里有一个如何组织日志记录的示例:

c2defac6b3f0114e4a9aea447841880c.png

41246cd6527a742029550f0336e8a2d8.png

如果你运行 myapp.py ,你应该在 myapp.log 中看到:

b81a0e66e126dbb703f3cb1fcb7e65e3.png

我们发现,不同模块中所记录的日志信息都被保存到了同一个日志文件里面了。

2.4 格式化输出以及记录相关的变量值到日志文件

前面有文章专门介绍了python中的字符串格式化的几种方法,包括使用百分号%、str.format、string.Template模板等方法,可以参考前面的文章:

python字符串格式化深入详解(四种方法)

所以,要定义自己的字符串输出格式,要记录相关的变量到字符串中,我们可以这样做。

要记录变量数据,请使用格式字符串作为事件描述消息,并将变量数据作为参数附加。 例如:

91b27f477dbc83acfab07e64aa34ef16.png

如你所见,

logging日志记录的字符串格式化,将数据合并到字符串中所采用的方式是 百分号% 的形式,
但是如果我想要使用其他的字符串格式化的方法怎么办呢?就需要通过指定style参数来决定了,style的取值可以是三个,即
  • '%':这是默认的,即默认使用百分号%格式的字符串格式化方法;
  • '{':表示使用str.format()的字符串格式化方法;
  • '$':表示使用string.Template的格式化方法;

为什么是默认使用百分号 % 格式化工具呢?主要是因为logging的出现时间比这两种格式化方法要早一些,但是并不是说完全不支持,现在完全有其他的方法让logging支持str.format()和string.Template()这些格式,只需要设置不同的style参数值即可。


三、logging模块的格式化设置以及时间格式化

当我们看之前的记录日志的时候,我们发现,记录的日志总是下面的格式,如下:

c9465cf5854c65871e873b4af2693e5e.png

即所谓的:

日志类别严重程度:root:message

这样的格式,那么能不能进行更改呢?这个自然是可以的,怎么更改呢,如下:

3.1 消息显示的格式设置——basicConfig的 format 参数

要更改用于显示消息的格式,你需要指定要使用的格式:

3575ed3ff136c23ae4a093622085febc.png

这将输出:

79a98e4c0debf52f51e7a66998b95f4c.png

请注意,前面示例中出现的“root”已消失。

对于可以出现在格式字符串中的全部内容,你可以参考以下文档 LogRecord 属性 ,在后面的系列文章第二篇中,还会深入探讨日志记录的高级主题,来说明的。

下面是常见的格式设置的字段标识:

  • %(asctime)s:日志创建时的普通时间;
  • %(created)f:日志创建时的时间(由time.time()返回);
  • %(filename)s:文件名;
  • %(funcName)s:调用日志记录的函数;
  • %(levelname)s:日志消息的文本级别;
  • %(levelno)s:日志消息的数字级别;
  • %(lineno)d:调用日志消息的行号;
  • %(msecs)d:创建时间的毫秒部分;
  • %(message)s:日志消息;
  • %(name)s:日志器的名称;
  • %(pathname)s:记录日志的源文件的路径名;
  • %(process)d:进程ID;
  • %(processName)s:进程名;
  • %(thread)d:线程ID;
  • %(threadName)s:线程名;
  • %(relativeCreated)d:创建日志记录的时间(以毫秒为单位)

借助于这些格式,我们可以自定义日志记录,比如显示时间:

516a3103c5b746fd15090a4ae04b287e.png

这样,日志中除了记录消息等级、消息信息外,还会记录上消息创建的时间。

3.2 设置日志记录的时间显示的格式——basicConfig的datefmt参数

aa4f996eec3f32a2e5d340c7fc44f020.png

那我们可不可以更改时间显示的格式呢?这个自然是能的,

日期/时间显示的默认格式(如上所示)类似于 ISO8601 或 RFC 3339 。 如果你需要更多地控制日期/时间的格式,请为 basicConfig 提供 datefmt 参数,

需要格外注意的是:datefmt 参数的格式与 time.strftime() 支持的格式相同。

如下例所示:

d8fdfe5ddbcbb33c71ead00727b2b430.png

那到底有哪一些格式呢?可以参考官网:https://docs.python.org/zh-cn/3.7/library/time.html#time.strftime

函数原型为:

e5479d70b146b5e84789ce8c8a28692c.png

转换一个元组或 struct_time 表示的由 gmtime()localtime() 返回的时间到由 format 参数指定的字符串。如果未提供 t ,则使用由 localtime() 返回的当前时间。 format 必须是一个字符串。如果 t 中的任何字段超出允许范围,则引发 ValueError

0是时间元组中任何位置的合法参数;如果它通常是非法的,则该值被强制改为正确的值。

以下指令可以嵌入 format 字符串中。它们显示时没有可选的字段宽度和精度规范,并被 strftime() 结果中的指示字符替换:

指令含义注释
%a本地化的缩写星期中每日的名称。
%A本地化的星期中每日的完整名称。
%b本地化的月缩写名称。
%B本地化的月完整名称。
%c本地化的适当日期和时间表示。
%d十进制数 [01,31] 表示的月中日。
%H十进制数 [00,23] 表示的小时(24小时制)。
%I十进制数 [01,12] 表示的小时(12小时制)。
%j十进制数 [001,366] 表示的年中日。
%m十进制数 [01,12] 表示的月。
%M十进制数 [00,59] 表示的分钟。
%p本地化的 AM 或 PM 。(1)
%S十进制数 [00,61] 表示的秒。(2)
%U十进制数 [00,53] 表示的一年中的周数(星期日作为一周的第一天)作为。在第一个星期日之前的新年中的所有日子都被认为是在第0周。(3)
%w十进制数 [0(星期日),6] 表示的周中日。
%W十进制数 [00,53] 表示的一年中的周数(星期一作为一周的第一天)作为。在第一个星期一之前的新年中的所有日子被认为是在第0周。(3)
%x本地化的适当日期表示。
%X本地化的适当时间表示。
%y十进制数 [00,99] 表示的没有世纪的年份。
%Y十进制数表示的带世纪的年份。
%z时区偏移以格式 +HHMM 或 -HHMM 形式的 UTC/GMT 的正或负时差指示,其中H表示十进制小时数字,M表示小数分钟数字 [-23:59, +23:59] 。
%Z时区名称(如果不存在时区,则不包含字符)。
%%字面的 '%' 字符。

注释:

  1. 当与 strptime() 函数一起使用时,如果使用 %I 指令来解析小时, %p 指令只影响输出小时字段。
  2. 范围真的是 061 ;值 60 在表示 leap seconds 的时间戳中有效,并且由于历史原因支持值 61
  3. 当与 strptime() 函数一起使用时, %U%W 仅用于指定星期几和年份的计算。

下面是一个示例,一个与 RFC 2822 Internet电子邮件标准以兼容的日期格式。

5031871670c8f7f3be6ff0c81cd57714.png

个人总结:

个人习惯使用的格式为,年月日,时分秒,星期数,如下:

a44eff0198f42f7ee593f2294e8d98f5.png

四、日志记录的堆栈追踪

前面都是一些最简单的日志记录操作与格式设置,但是我们在编写python代码的时候,往往涉及到多个函数之间的调用,我们需要跟踪函数调用的堆栈信息,这样才能定位到到底是哪一个函数的哪一个位置出现了错误,这才更加合理。

再次回顾日志记录实际上是做一件什么事?

  • 即当满足什么条件的时候、或者是当某一件事情发生的时候,开始记录日志,明白这思想很重要
  • 现在我们要做的就是,在程序执行出发了异常的时候,就开始记录日志,并且记录程序的堆栈信息,思想是相通的,只不过条件现在变成了,在异常发生的时候。

首先其实我们发现,http://logging.xxx()的几个函数(info、debug、warning、error、critical)他们的参数格式是一样的,以error为例:

07846aee917625bb0c7e4a875c383b17.png

有两个非常关键的参数,它们是

  • stack_info:
  • exc_info:

下面将分别来说明这两个参数各自的作用

(1)exc_info=True——出现异常时记录堆栈调用信息

先从一个简单的函数调用例子来看

有一个math_func.py模块,实现了两个函数,如下:

83a57cecf42537e5bf55b2927eca7cd5.png

然后有一个operation_func.py模块,再进一步对这两个函数进行包装,以便进行选择性的调用哪一个函数,如下:

6388edc95ee6fb33e128773cf9fc1534.png

最后再主模块main.py里面进行调用,如下:

476e5261b402a7987d995c6f723c3654.png

运行之后,打开日志文件,得到如下的结果

2b808ea80dce42d151b09e6f47e084ec.png

从上面我们发现,错误信息以及堆栈信息全部清楚地记录在了里面。这对于程序调试是至关重要的。

以上就是出现错误的时候logging堆栈追踪的全部实现,一般的调用模板如下:

8dc45fec1e7aa156d3e92a43d6a2b2f6.png

前面提到了由两个参数,那么这两个参数到底有什么区别呢?现总结如下:

  • exe_info参数:在搜索异常处理程序时,跟踪异常而打开的堆栈帧的信息,这个是专门针对异常发生的时候记录日志的;
  • stack_info参数:默认为 False。如果为 True,则将堆栈信息添加到日志消息中,包括实际的日志调用。请注意,这与通过指定 exc_info 显示的堆栈信息不同:他主要是从堆栈底部到当前线程中的日志记录调用的堆栈帧,什么意思呢?即使在未引发任何异常的情况下,也可以显示如何到达代码中的特定点。堆栈帧在标题行(即每一句日志记录行)之后打印:
  • stack_info:简单来说就是,根据每一个日志记录语句所在的位置,打印出这一句日志记录信息,并且在后面显示这句日志记录所在的函数堆栈的位置是在哪里。

(2)stack_info=True——记录每一句日志记录语句所在代码中的堆栈信息

参考下面的例子:

8b29dd3f3bf0040655433e41fd262e26.png

调用b函数,b中有调用a函数,得到下面的日志信息:

62c62188c5e593f6505079004d2929b6.png

从上面可以看出,stack_info它会详细记录每一条日志打印语句所在的位置,然后在日志信息后面加以显示,这跟exe_info是有显著区别的

(3)补充参数说明——extra参数的说明

前面的3.1中在说明日志记录的格式的时候,给出了很多预先定义好的格式,比如

  • %(asctime)s:日志创建时的普通时间;
  • %(created)f:日志创建时的时间(由time.time()返回);
  • %(filename)s:文件名;

等等,有时候我们想定义自己的信息怎么办呢?可以采用下面的方式,extra参数接受的参数是一个字典类型,如下例子所示:

278da428b8157f64190d532eacdef69f.png

我们发现,自己定义的clientip、user、work都显示了出来!

实际上,上面的这种操作称之为,向日志输出中添加上下文信息

除了传递给日志记录函数的参数外,有时候我们还想在日志输出中包含一些额外的上下文信息。比如,在一个网络应用中,可能希望在日志中记录客户端的特定信息,如:远程客户端的IP地址和用户名。这里我们来介绍以下几种实现方式:

  • 通过向日志记录函数传递一个extra参数引入上下文信息
  • 使用LoggerAdapters引入上下文信息
  • 使用Filters引入上下文信息

具体说明请参考博文 《Python之向日志输出中添加上下文信息》

关于Python logging的更多高级用法,请参考文档<< Logging CookBook >>。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/506018.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux进程管理子系统分析,linux进程管理子系统简要分析

Linux进程管理&#xff1a;进程与程序&#xff1a;程序&#xff1a;存放在磁盘上的一系列代码和数据的可执行映像&#xff0c;是一个静止的实体。进程&#xff1a;是一个执行中的程序&#xff0c;它是动态的实体进程四要素&#xff1a;1. 有一段程序供其执行&#xff0c;这段程…

c语言变量命名规则_带你学习C语言—变量

在编写程序时&#xff0c;常常需要将数据存储在内存中&#xff0c;以便于使用这个数据或者修改这个数据的值。我们通常使用变量来存储数据&#xff0c;而且使用变量可以引用存储在内存中的数据&#xff0c;并随时根据需要对数据进行处理。变量的概念在程序设计中&#xff0c;允…

html缩进快捷键_Windows IDEA 快捷键终极大全,果断收藏!

作者&#xff1a;JaJian出处&#xff1a;https://www.cnblogs.com/jajian/p/8012603.html话说IDEA对新手来说难&#xff0c;可能其中一个原因就是快捷键组合多而且复杂但是它也很全&#xff0c;基本所有功能都可以通过快捷键来完成&#xff0c;可以这么说&#xff0c;如果你掌握…

安装quartus时弹出错误_Win10 安装arcgis10.2 for desktop需要.net framework 解决方案

有效解决“Win10 安装arcgis10.2 for desktop需要microsoft.net framework 3.5 sp1或等效环境”。台式电脑新装了系统&#xff0c;重新安装arcgis 10.2时弹出“安装arcgis10.2 for desktop需要microsoft.net framework 3.5 sp1或等效环境 ”。在网上百度了很多的相关知识&#…

下面哪个字段是http请求中必须具备的_HTTP 协议报文结构及示例

HTTP 基本架构下面我们用一张简单的流程图来展示 HTTP 协议基本架构&#xff0c;以便大家先有个基本的了解Web Client 可以是浏览器、搜索引擎、机器人等等一切基于HTTP 协议发起 http 请求的工具。Web Server 可以是任何的能解析 HTTP 请求&#xff0c;并返回给Web Client 可识…

文件名为空linux,文件系统:隐匿在Linux背后的机制

原标题&#xff1a;文件系统&#xff1a;隐匿在Linux背后的机制在 Linux 中&#xff0c;最直观、最可见的部分就是 文件系统(file system) 。下面我们就来一起探讨一下关于 Linux 中国的文件系统&#xff0c;系统调用以及文件系统实现背后的原理和思想。这些思想中有一些来源于…

docker安装elasticsearch_Elasticsearch amp; Kibana 部署安装 (Docker)

为什么要使用 Docker来部署 Elasticsearch 和 Kibana 呢&#xff0c;传统使用软件在操作系统上安装和配置的方法过于繁琐&#xff0c;并且受一些跨平台的约束&#xff0c;例如Mac、Windows、Linux等&#xff0c;所以无论安装什么软件&#xff0c;通过 Docker 进行部署是最为简单…

mfc 对话框透明 控件不透明_你不知道的丨透明胶用法

家家都有的透明胶带&#xff0c;而它的作用不仅仅是用来粘东西。别看它是这么小小一块&#xff0c;可是作用却很多。平时我们穿的衣服&#xff0c;裤子难免会粘上些毛。在我们紧急出门的时候&#xff0c;突然发现衣服粘有毛&#xff0c;这时候我们的透明胶就派上用场了。用透明…

python partial_Python--并行计算框架(pathos)

​应用python进行数据挖掘或计算时&#xff0c;往往需要遍历多种参数进行数据建模&#xff0c;而单次的建模或计算有时候非常耗时&#xff0c;这时候可以利用python的并行计算功能&#xff0c;加快计算速度。python能够应用并行计算的模块有多个multiprocessing、pathos等。其中…

endnote怎么改成中文版_毕业论文面对大量的参考文献标注,应该怎么办?(便捷整理的技巧和方法)...

毕业论文不同于一般的小论文&#xff0c;特别是硕士毕业论文或者博士毕业论文。一般的小论文就四五页&#xff0c;而硕士论文动辄五六十页&#xff0c;有的甚至七八十页&#xff0c;因此有些东西如果要人工的去修改&#xff0c;将是一件非常痛苦的事情&#xff0c;比如目录自动…

怎么创建数据表的实体类和业务类_微服务项目第13天:商品分类业务的实现

今天是刘小爱自学Java的第143天。感谢你的观看&#xff0c;谢谢你。学习计划安排如下&#xff1a;商品分类业务的初步实现。数据模型的分析&#xff1a;数据表字段的设计&#xff0c;Java中对应的实体类&#xff0c;前端页面vue组件。业务模型的分析&#xff1a;请求路径是什么…

power iso linux启动盘,Power ISO Maker/ISO燃烧到磁盘工具 V3.0版

电源国际标准化组织是一个专业的工具&#xff0c;使国际标准化组织文件&#xff0c;并将其燃烧到磁盘。它可以快速地创建一个ISO文件从您的计算机&#xff0c;和ISO文件刻录到CD / DVD光盘。该软件还可以将你的光盘/光盘刻录到一个标准的文件&#xff0c;并烧毁它。你可以使用的…

scripts文件夹_常用Scripts整理

常用scripts整理--2020.05.13平时在进行数据处理时&#xff0c;经常会用到一些脚本文件&#xff0c;可以提高效率&#xff0c;我把自己常用到的进行整理总结&#xff0c;希望可以有所帮助1.批量修改图片名字#codingutf-8code by zzg 2020-04-07import os import re import sy…

python下载文件加上日期_Python实现给下载文件显示进度条和下载时间代码

本篇文章小编给大家分享一下Python实现给下载文件显示进度条和下载时间代码&#xff0c;文章代码介绍的很详细&#xff0c;小编觉得挺不错的&#xff0c;现在分享给大家供大家参考&#xff0c;有需要的小伙伴们可以来看看。 该模块调用了三个库&#xff1a; 1.os 2.requests 3.…

c# 计算空格宽度像素_用pythonnet为计算机视觉做图像整理

中国的.NETer是国内技术的另类&#xff0c;当他们强调.NET也可以做啥啥时都会给别的技术藐视&#xff0c;毕竟主流都不用.NET。本人这几年其实花在.NET时间也少&#xff0c;都投入在Python/Go社区。可我还是有点工作外的寄托&#xff0c;就是让.NET也有一个很好的推广&#xff…

C语言笔试不好应该转专业吗,你认为大学里什么学科“难学”?过来人说出几门,考试难补考更难...

原标题&#xff1a;你认为大学里什么学科“难学”&#xff1f;过来人说出几门&#xff0c;考试难补考更难文/晓宁说教育2020届的大一新生们的第一个学期已经结束了&#xff0c;经过了一个学期的学习和生活&#xff0c;相信很多学生都对自己的大学有了一定的规划。尽管进入大学之…

python画饼图存在的问题_Matplotlib 绘制饼图解决文字重叠的方法

在使用Matplotlib 绘制饼图的时候有些时候一些数据的比列太小在饼图呈现的效果不明显 很容易被覆盖&#xff0c;为了解决这个问题以下就是我个人的心得。 【未解决之前呈现的效果】可以看到这个饼状图其他和硕士这2个部分占比很小而且比例相互覆盖&#xff0c;这让人看起来不舒…

python变量类型是动态的_【Python】python动态类型

在python中&#xff0c;省去了变量声明的过程&#xff0c;在引用变量时&#xff0c;往往一个简单的赋值语句就同时完成了&#xff0c;声明变量类型&#xff0c;变量定义和关联的过程&#xff0c;那么python的变量到底是怎样完成定义的呢&#xff1f; 动态类型 python使用动态类…

c语言excel转pdf,基于C语言和Excel软件下光速测量仪测量玻璃折射率.pdf

基于C语言和Excel软件下光速测量仪测量玻璃折射率.pdf基于语言和 软件下光速测量仪测量玻璃折射率 朱承君 王奇峰 芦立娟 张艳春 ( 浙江海洋学院机电学院 浙江 舟山 ) ( 收稿日期 ) 摘要 介绍了用等相位法测玻璃折射率的原理和方法&#xff0c; 并利用了 语言和 在科学计算中的…

python3.7界面_Python3.7+tkinter实现查询界面功能

Tkinter 是 Python 的标准 GUI 库。Python 使用 Tkinter 可以快速的创建 GUI 应用程序。 这篇文章使用tkinter实现一个简单的查询界面 #!/usr/bin/python # -*- coding: UTF-8 -*- from tkinter import * import sqlite3 # 导入消息对话框子模块 import tkinter.messagebox #im…