热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python3logging

python3logginghttps:docs.python.org3.5librarylogging.html,先3.5是因为我当前的python版本是3.5之所
python3 logging

https://docs.python.org/3.5/library/logging.html,先3.5是因为我当前的python 版本是3.5

之所以要来详细的写是因为之前学django时也有这个,不是很理解,所以这里就多了解下。

写到后面发现整个文章一点条理都没有,但由于内容比较多,就不重新整理了

logging框架中主要由四个部分组成:

Loggers expose the interface that application code directly uses.Handlers send the log records (created by loggers) to the appropriate destination.Filters provide a finer grained facility for determining which log records to output.Formatters specify the layout of log records in the final output.

 

  • Loggers: 提供应用直接调用的接口
  • Handlers: 决定将日志记录发送至正确的目的地
  • Filters: 提供更精细的决定哪些日志输出的能力,简单点说就是决定哪些输出哪些不输出
  • Formatters: 制定最终输出的格式。

logger对象

事实上logger是不直接实例化的,但是我们可以通过模块级别的函数logging.getLogger(name)来调用。如果多次通过同一个名字调用getLogger()将只能得到对同一个对象的引用。

注意: logging.getLogger(name) 中的name是一个支持通过“.”(点号)分层级的值。

例如: 你定义一个logger: foo,那么foo.bar, foo.baz,就都算作它的子代,就是继承,有父子关系。

logger名字的层级与python中包的层级是一致的。所以为了区分它,如果你基于模块来组织logger,

那么建议你使用:logging.getLogger(__name__)这种形式,因为对于模块而言,在python

包的命名空间中__name__的值就是模块的名字。

 

常用方法:

Logger.setLevel(lvl):

将logger的门限设置为lvl,低于此等级的信息将被忽略,当一个Logger被创造出来时,它的等级被设置为:

NOTSET(未设置) 这样的结果就是: 如果它是一个root logger,它将处理所有的信息,如果没有root logger

它将继承父级的logger等级。Note: root logger可通过level waring来创建,注意这里是个坑,

事实上默认root logger等级为warning,不要搞错了

 

 级别设定:前面是名字,后面是对应的数字值

 

Logger.exception(msg, *args, **kwargs)

以error级别来记录信息,异常信息也会被添加到信息(message),需要exception handler调用才行

Logger.addFilter(filt)

添加指定的过滤器

Logger.removeFilter(filt)

移除指定的过滤器

这里的方法多得让人想撞死在屏幕上,以后慢慢更新吧。

Handler

  • Handler.setLevel(lel):指定被处理的信息级别,低于lel级别的信息将被忽略
  • Handler.setFormatter():给这个handler选择一个格式
  • Handler.addFilter(filt)、Handler.removeFilter(filt):新增或删除一个filter对象

handler有多达15种,这里只说下常见的几种:

1.logging.StreamHandler 

发送信息到流,类文件对象即可,如终端,文件等

2.logging.FileHandler

发送信息到硬盘文件

3.logging.RotatingFileHandler
这个Handler类似于上面的FileHandler,但是它可以管理文件大小,轮询日志文件(不知道是不是检测日志文件大小)。

当文件达到一定大小之后,它会自动将当前日志文件改名,然后创建一个新的同名日志文件继续输出。

4.logging.handlers.TimedRotatingFileHandler

这个Handler和RotatingFileHandler类似,不过,它没有通过判断文件大小来决定何时重新创建日志文件,

而是间隔一定时间就 自动创建新的日志文件。

Formatter

Formatters 决定了记录格式。Formatter会将传递来的信息拼接成一条具体的字符串,

默认情况下Format只会将信息%(message)s直接打印出来。Format中有一些自带的LogRecord属性可以使用,如下表格:

其中lineno,pathname,经过实测了,并不是有些博客里说的什么当前日志记录的行号。后面会有实例。

这里有一个简单的应用 的例子,记录出错信息:

#!/usr/bin/env python
#coding:utf-8
# Created by Andy @ 2017/6/22import logginglogging.basicConfig(level=logging.DEBUG,format='%(asctime)s %(pathname)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s ',datefmt='%a, %d %b %Y %H:%M:%S',filename=r'D:\Coding\oldboy\day13 module\test.log',filemode='w')def login():while True:try:name = input('Input user name:')password = int(input('Input password:')) # 这里故意转成整型,触发异常if name == 'andy' and password == 'nopasswd':print('logging succeed!')except ValueError as e:logging.debug(e)breakif __name__ == '__main__':login()

 

 终端验证

Input user name:andy
Input password:nopasswdProcess finished with exit code 0

 打开test.log:

Fri, 23 Jun 2017 09:56:40 D:/Coding/oldboy/day13 module/log.py log.py[line:24] DEBUG invalid literal for int() with base 10: 'nopasswd'

 注意看,lineno 并不是在日志里面的行号,而是你代码的行号,在24行调用了logging.debug(e)

 这里现定义一个一simple_logger:

#!/usr/bin/env python
#coding:utf-8
# Created by Andy @ 2017/6/22import logging
import oslog_path = os.path.join(os.getcwd(),'test.log')logging.basicConfig(level=logging.DEBUG,format='%(asctime)s %(pathname)s line:%(lineno)d %(message)s ',datefmt='%Y-%m-%d %H:%M:%S', # 将日期格式化成正常模式filename=log_path,filemode='a') # 指定成追加模式,默认就是追加,所以这句非必须simple_logger = logging.getLogger('simple')
fh = logging.StreamHandler() #输出到终端
fh.setLevel(level = logging.WARNING) #等级比默认的高,但调用时必须一致
formatter = logging.Formatter("%(asctime)s %(message)s %(levelname)s")
fh.setFormatter(formatter)
simple_logger.addHandler(fh)def login():while True:try:name = input('Input user name:')password = int(input('Input password:')) # 这里故意转成整型,触发异常if name == 'andy' and password == 'nopasswd':print('logging succeed!')except ValueError as e:simple_logger.warning(e)breakif __name__ == '__main__':login()

 

 运行:

终端输出:

Input user name:andy
Input password:andy
2017-06-24 09:55:57,395 invalid literal for int() with base 10: 'andy' WARNING

 test.log文件:

2017-06-24 09:55:57 D:/Coding/oldboy/day13 module/log.py line:33 invalid literal for int() with base 10: 'andy'

 这晨需要 注意的是:因为默认的logger等级是debug,所以它什么消息都会输出,而simple_logger则只输出比自身高等级的信息,

并且:调用simple_logger时必须比定义的等级高于或者等于定义的等级,这句话什么意思呢?看上面的例子,simple_logger

定义时的等级为warning,那么你调用时最少得warning等级,或者比它高的critical才能正常打印消息(它规定就是这样),否则你是看不到任何效果的

(这里坑了好久,一直没消息打印而找不到原因,root logger默认等级是warning,而非Noset),但是如果你调用的等级比较低,

并不影响root 这个logger打印日志信息。

填坑来了:

如果没指定默认的logger的等级,那么默认的等级warning就会生效,所以才出现上面的情况,如果需要将debug等级的信息也输入,那么,这里需要加一条:

simple_logger.setLevel(logging.DEBUG)
# 如果不设置此logger的级别,那么handler的记录是从logger传过来的,也就是默认从logger的warning来的

 

 

 

 

下面是一个使用配置文件 的例子:

#!/usr/bin/env python
#coding:utf-8
# Created by Andy @ 2017/6/25import logging
import logging.configlogging.config.fileConfig('logging.conf')# create logger
logger = logging.getLogger('simpleExample')# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')

 

 

 配置文件:

[loggers]
keys=root,simpleExample[handlers]
keys=consoleHandler,simpleHandler[formatters]
keys=consoleFormatter,simpleFormatter[logger_root]
level=DEBUG
handlers=consoleHandler[logger_simpleExample]
level=INFO
handlers=simpleHandler
qualname=simpleExample
propagate=1[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=consoleFormatter
args=(sys.stdout,)[handler_simpleHandler]
class=FileHandler
level=INFO
formatter=simpleFormatter
args=('simple.log','w')[formatter_consoleFormatter]
format=%(levelname)s :%(message)s[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=

 之前的例子没已经删除了,找到原因:propagate=1 ,只有当propagate 为True时,logger的信息才能传到上一级logger,或者说父logger,如果你设置为0

那么,就只有文件中有写入,而终端不会有信息打印出来。

 

posted on 2017-06-24 11:08 Andy_963 阅读(...) 评论(...) 编辑 收藏

转:https://www.cnblogs.com/Andy963/p/7067460.html



推荐阅读
  • 本文档汇总了Python编程的基础与高级面试题目,涵盖语言特性、数据结构、算法以及Web开发等多个方面,旨在帮助开发者全面掌握Python核心知识。 ... [详细]
  • Django xAdmin 使用指南(第一部分)
    本文介绍如何在Django项目中集成和使用xAdmin,这是一个增强版的管理界面,提供了比Django默认admin更多的功能。文中详细描述了集成步骤及配置方法。 ... [详细]
  • 日志记录对于软件开发至关重要,特别是在调试和维护阶段。通过日志,开发者能够追踪错误源头并了解系统的运行状态。本文将探讨如何在Django框架中有效配置和使用日志记录功能。 ... [详细]
  • Python处理Word文档的高效技巧
    本文详细介绍了如何使用Python处理Word文档,涵盖从基础操作到高级功能的各种技巧。我们将探讨如何生成文档、定义样式、提取表格数据以及处理超链接和图片等内容。 ... [详细]
  • cJinja:C++编写的轻量级HTML模板引擎
    本文介绍了cJinja,这是一个用C++编写的轻量级HTML模板解析库。它利用ejson来处理模板中的数据替换(即上下文),其语法与Django Jinja非常相似,功能强大且易于学习。 ... [详细]
  • 磁盘健康检查与维护
    在计算机系统运行过程中,硬件或电源故障可能会导致文件系统出现异常。为确保数据完整性和系统稳定性,定期进行磁盘健康检查至关重要。本文将详细介绍如何使用fsck和badblocks工具来检测和修复文件系统及硬盘扇区的潜在问题。 ... [详细]
  • JavaScript 基础语法指南
    本文详细介绍了 JavaScript 的基础语法,包括变量、数据类型、运算符、语句和函数等内容,旨在为初学者提供全面的入门指导。 ... [详细]
  • 目录一、salt-job管理#job存放数据目录#缓存时间设置#Others二、returns模块配置job数据入库#配置returns返回值信息#mysql安全设置#创建模块相关 ... [详细]
  • Linux环境下C语言实现定时向文件写入当前时间
    本文介绍如何在Linux系统中使用C语言编程,实现在每秒钟向指定文件中写入当前时间戳。通过此示例,读者可以了解基本的文件操作、时间处理以及循环控制。 ... [详细]
  • 1.增加视图函数#Http:127.0.0.1booksdefshow_books(request):booksBookInfo.objects.all()returnrend ... [详细]
  • 本文详细介绍如何结合Django框架和DRF(Django REST Framework)来设计一套有效的全局异常处理系统。这套系统不仅能够妥善处理DRF引发的异常,还能兼容Django自带的admin界面异常处理逻辑。 ... [详细]
  • 本文详细介绍了Django框架内置的对象关系映射(ORM)机制,包括其工作原理、如何连接MySQL数据库以及ORM的主要优势和局限性。同时,提供了配置和使用Django ORM的具体步骤。 ... [详细]
  • 深入理解Django中的AJAX应用
    本文详细介绍了AJAX技术及其在Django框架中的应用。AJAX,即异步JavaScript和XML,允许网页在不重新加载整个页面的情况下与服务器交换数据并更新部分网页。 ... [详细]
  • 本文介绍了SVD(奇异值分解)和QR分解的基本原理及其在Python中的实现方法。通过具体代码示例,展示了如何使用这两种矩阵分解技术处理图像数据和计算特征值。 ... [详细]
  • 本文介绍了如何在Django项目中使用django-crontab库来设置和管理定时任务,包括安装、配置、编写定时任务以及常见问题的解决方案。通过具体实例,帮助开发者快速掌握在Django中实现自动化任务的方法。 ... [详细]
author-avatar
周扒pi
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有