郎林 發表於 2021-11-11 19:00:00

python基础_标准库-logging

<h3>一、简介&nbsp;</h3>
<p>1、概要:logging 是python&nbsp; 用于记录日志的标准模块</p>
<p>2、logging 日志库定义的日志级别:</p>
<table style="height: 236px; float: left; border: 0 solid rgba(0, 0, 0, 1); background-color: rgba(240, 248, 255, 1); width: 736px" border="0" align="center">
<tbody>
<tr>
<td>级别</td>
<td>级别数值(int)</td>
<td>使用时机</td>
</tr>
<tr>
<td>DEBUG</td>
<td>10</td>
<td>详细信息</td>
</tr>
<tr>
<td>INFO</td>
<td>20</td>
<td>正常运行过程中产生的一些信息</td>
</tr>
<tr>
<td>WARNING</td>
<td>30</td>
<td>警告信息,虽然程序正常运行,但有可能发生错误</td>
</tr>
<tr>
<td>ERROR</td>
<td>40</td>
<td>运行出错,程序已经不能执行一些功能了</td>
</tr>
<tr>
<td>CRITICAL</td>
<td>50</td>
<td>严重错误,程序已经不能正常运行</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>3、logging 日志库的四类组件(四个类)</p>
<p>Logger :记录器&nbsp; &nbsp;提供了应用程序代码直接使用的接口 (是用记录器去记录日志,简单理解就是 记录日志的工具,类似 笔)(备注:一个记录器可以对接多个处理器)</p>
<p>Handlers : 处理器 将记录器产生的日志发送至指定的目的地 (就是日志输出的位置,比如输出到本地文件,控制台,或者发送至Email 等网络上的任意位置,)</p>
<p>Filters: 过滤器 提供了更细粒度的功能,用于确定要输出的日志记录 (过滤日志用的)</p>
<p>Fomatters: 格式器:指定最终输出中日志记录的样式。 (日志信息格式化用的)</p>
<h3>二、logging 模块的工作流程</h3>
<p><img src="https://img2020.cnblogs.com/blog/2560969/202111/2560969-20211111154425398-2101835.png"></p>
<h4>&nbsp;Logger 记录器:</h4>
<p>1、创建记录器对象:</p>
<p>logger=logging.getLogger(name=None)&nbsp; &nbsp; &nbsp; name&nbsp; 如果不传 则返回 一个 root&nbsp; logger,&nbsp;</p>
<p>2、设置日志记录器的级别</p>
<p>loger.setLevel()</p>
<p>3、讲日志内容传递到关联的handler&nbsp;</p>
<p>loger.addHandler()&nbsp; 关联一个处理器</p>
<p>loger.removeHandler()&nbsp; 取消关联</p>
<p>&nbsp;</p>
<h4>Handler 处理器</h4>
<p>StreamHandler类型 :标准的输出stdout (比如显示器输出,控制台输出) 分发器</p>
<p>创建方法:logging.StreamHandler(stream=None)</p>
<p>&nbsp;</p>
<p>FileHandler类型:将日志保存到磁盘文件的处理器</p>
<p>创建方法:file_handler =&nbsp;logging.FileHandler(filename='xx.log',mode='a',encoding='utf-8')</p>
<p>&nbsp;</p>
<p>设置当前处理器对象使用的日志格式:</p>
<p>file_handler.setFormatter(ojb)&nbsp; &nbsp;#ojb 为 一个格式器对象</p>
<p>&nbsp;</p>
<p>其他常用的 处理器类型:</p>
<p>BaseRotatingHandler</p>
<p>Rotating Filehandler&nbsp; &nbsp; &nbsp;滚动的多日志输出,按照时间or其他方式去生成多个日志</p>
<p>TimedRotatingfilehandler</p>
<p>&nbsp;</p>
<h4>Formatter 格式器</h4>
<p>Formatter 格式器用来最终设置日志信息的顺序,结构和内容</p>
<p>创建方法&nbsp;</p>
<p>formatter = logging.Formatter(<span class="hljs-string">"%(asctime)s|%(levelname)8s|%(filename)10s%lineno)s|%(message)s")</span></p>
<p id="formatters格式">    &nbsp;Formatter对象的格式:</p>
<div class="table-wrapper" style="text-align: left; margin-left: 30px">
<table style="height: 582px; margin-left: 30px; width: 654px">
<thead>
<tr><th>属性</th><th>格式</th><th>描述</th></tr>
</thead>
<tbody>
<tr>
<td><span style="color: rgba(255, 0, 0, 1)">asctime</span></td>
<td><span style="color: rgba(255, 0, 0, 1)">%(asctime)s</span></td>
<td><span style="color: rgba(255, 0, 0, 1)">日志产生的时间,默认格式为msecs2003-07-0816:49:45,896</span></td>
</tr>
<tr>
<td>msecs</td>
<td>%(msecs)d</td>
<td>日志生成时间的亳秒部分</td>
</tr>
<tr>
<td>created</td>
<td>%(created)f</td>
<td>time.tme)生成的日志创建时间戳</td>
</tr>
<tr>
<td><span style="color: rgba(255, 0, 0, 1)">message</span></td>
<td><span style="color: rgba(255, 0, 0, 1)">%(message)s</span></td>
<td><span style="color: rgba(255, 0, 0, 1)">具体的日志信息</span></td>
</tr>
<tr>
<td>filename</td>
<td>%(filename)s</td>
<td>生成日志的程序名</td>
</tr>
<tr>
<td>name</td>
<td>%(name)s</td>
<td>日志调用者 (日志记录器的名称)</td>
</tr>
<tr>
<td>funcname</td>
<td>%(<span style="color: rgba(255, 0, 0, 1)">funcName</span>)s</td>
<td>调用日志的函数名</td>
</tr>
<tr>
<td>levelname</td>
<td>%(levelname)s</td>
<td>日志级別( DEBUG,INFO, WARNING, 'ERRORCRITICAL)</td>
</tr>
<tr>
<td><span style="color: rgba(255, 0, 0, 1)">levene</span></td>
<td><span style="color: rgba(255, 0, 0, 1)">%( leveling)s</span></td>
<td><span style="color: rgba(255, 0, 0, 1)">日志级别对应的数值</span></td>
</tr>
<tr>
<td>lineno</td>
<td>%(lineno)d</td>
<td>日志所针对的代码行号(如果可用的话)</td>
</tr>
<tr>
<td>module</td>
<td>%( module)s</td>
<td>生成日志的模块名</td>
</tr>
<tr>
<td>pathname</td>
<td>%( pathname)s</td>
<td>生成日志的文件的完整路径</td>
</tr>
<tr>
<td>process</td>
<td>%( (process)d</td>
<td>生成日志的进程D(如果可用)</td>
</tr>
<tr>
<td>processname</td>
<td>(processname)s</td>
<td>进程名(如果可用)</td>
</tr>
<tr>
<td>thread</td>
<td>%(thread)d</td>
<td>生成日志的线程D(如果可用)</td>
</tr>
<tr>
<td>threadname</td>
<td>%( threadname)s</td>
<td>线程名(如果可用)</td>
</tr>
</tbody>
</table>
</div>
<p>&nbsp;</p>
<h3>Filter 过滤器</h3>
<p>可以被 Handler 和 Logger 调用&nbsp;&nbsp;用来实现比按层级提供更复杂的过滤操作。</p>
<p>创建过滤器:</p>
<p>flt = logging.Filter("cn.cccb")</p>
<p>在处理器和记录器中进行过滤</p>
<p><span class="hljs-comment">logger.addFilter(flt)&nbsp; &nbsp;&nbsp;</span></p>
<p><span class="hljs-comment">file_handler.addFilter(flt)</span></p>
<p>&nbsp;</p>
<h3>三、一个简单的例子</h3>
<p>以下例子实现了一个日志记录器同时往控制台和本地文件输入不同级别的日志</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> logging


</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 创建一个日志记录器</span>
loger = logging.getLogger(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">applog</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)

</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 设置日志记录器的等级 INFO</span>
<span style="color: rgba(0, 0, 0, 1)">loger.setLevel(logging.INFO)

</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 创建一个将流式的日志处理器</span>
steram_handler =<span style="color: rgba(0, 0, 0, 1)"> logging.StreamHandler()


</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> loger.removeHandler()#接触绑定</span>

<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">创建一个 输出到磁盘文件的日志处理器</span>
file_handler=logging.FileHandler(filename=<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">file.log</span><span style="color: rgba(128, 0, 0, 1)">'</span>,mode=<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">w</span><span style="color: rgba(128, 0, 0, 1)">'</span>,encoding=<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">utf-8</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)

</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> file_handler 设置日志等级为 ERROR ,没有给handler 设置日志级别,该handler 将使用logger设置或者默认的级别</span>
<span style="color: rgba(0, 0, 0, 1)">file_handler.setLevel(logging.ERROR)

</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 创建一个日志格式器</span>
formatter = logging.Formatter(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">%(asctime)s - %(name)s - %(levelname)s -%(module)s:%(message)s</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)

</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 设置处理器输出的日志格式</span>
<span style="color: rgba(0, 0, 0, 1)">file_handler.setFormatter(formatter)
steram_handler.setFormatter(formatter)


</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 设置一个过滤器</span>
fl1 = logging.Filter(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">app2log</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)

</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 给日志记录器设置一个过滤器 ,(从根部开始过滤)</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)"> loger.addFilter(fl1)</span>


<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">还可以给 handler 设置过滤器 (在输出的时候过滤)</span>
<span style="color: rgba(0, 0, 0, 1)">steram_handler.addFilter(fl1)


</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 记录器设置一个处理器</span>
<span style="color: rgba(0, 0, 0, 1)">loger.addHandler(steram_handler)
loger.addHandler(file_handler)

</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 写入日志</span>
loger.debug(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">debug log</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
loger.info(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">info log</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
loger.warning(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">warning log</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
loger.error(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">error log</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
loger.critical(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">critical log</span><span style="color: rgba(128, 0, 0, 1)">'</span>)</pre>
</div>
<p>&nbsp;</p>
<p>&nbsp;注意:<span style="color: rgba(255, 0, 0, 1)">Handler 可设置的日志级别是Logger 的设置的日志级别的子集(如果Logger没设置,默认是WARNING)</span></p>
<p>&nbsp;假设Logger 设置INFO 级别的日志,Handler 设置的DEBUG级别的日志,那Handler 还是只能输出INFO 及以上级别的日志</p>
<p>&nbsp;</p>
<h3>四、写在最后:</h3>
<p>logging本质是实现了一个日志记录器按指定的等级获取日志,在处理器上设置日志格式以及等级后,通过处理器输出日志到指定位置</p>
<p>同时还可以通过filter 过滤器从logger 或者handler 处过滤不同记录器产生的日志</p>
<p>&nbsp;</p>
<p><span style="font-family: &quot;Courier New&quot;, sans-serif; font-size: 13px; white-space: pre; background-color: rgba(245, 245, 245, 1)">&nbsp;</span></p><br><br>
来源:https://www.cnblogs.com/byhh/p/15539676.html
頁: [1]
查看完整版本: python基础_标准库-logging