摘要by crazyhacking:
与log4cxx一样,分为三个部分,logger, handler,formatter.

一   简单示例

import logging

    

    logger = logging.getLogger()  # 生成一个日志对象



    # logfile是一个全局变量,它就是一个文件名,如:'crawl.log'

    logfile = 'test.log'

# 生成一个Handler。logging支持许多Handler,

    # 象FileHandler, SocketHandler, SMTPHandler等,我由于要写

    # 文件就使用了FileHandler。    

    hdlr = logging.FileHandler('sendlog.txt')

# 成一个格式器,用于规范日志的输出格式。如果没有这行代码,那么缺省的

    # 格式就是:"%(message)s"。也就是写日志时,信息是什么日志中就是什么,

    # 没有日期,没有信息级别等信息。logging支持许多种替换值,详细请看

    # Formatter的文档说明。这里有三项:时间,信息级别,日志信息

    formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')

# 将格式器设置到处理器上

    hdlr.setFormatter(formatter)

# 将处理器加到日志对象上

    logger.addHandler(hdlr)

# 设置日志信息输出的级别。logging提供多种级别的日志信息,如:NOTSET, 

    # DEBUG, INFO, WARNING, ERROR, CRITICAL等。每个级别都对应一个数值。

    # 如果不执行此句,缺省为30(WARNING)。可以执行:logging.getLevelName

    # (logger.getEffectiveLevel())来查看缺省的日志级别。日志对象对于不同

    # 的级别信息提供不同的函数进行输出,如:info(), error(), debug()等。当

    # 写入日志时,小于指定级别的信息将被忽略。因此为了输出想要的日志级别一定

    # 要设置好此参数。这里我设为NOTSET(值为0),也就是想输出所有信息

    logger.setLevel(logging.NOTSET)

二  使用配置文件

实际运用中,我们可能需要将日志的配置信息独立出来,这时候我们就需要用到logging的另一个功能:

test.py

# test.py
import logging
import logging.config logging.config.fileConfig("logging.conf") #使用logger_example
logger = logging.getLogger("example") #"application" code
logger.debug("debug message")
logger.info("info message")
logger.warn("warn message")
logger.error("error message")
logger.critical("critical message")
#默认的调用[logger_root],也就是说如果logger名字不是conf文件中已有的,那么使用logger_root的相关配置信息
logHello = logging.getLogger("hello")
logHello.info("Hello world!")

logging.conf配置文件:

# logging.conf

#1.  建立logger
[loggers]
keys=root,example #2. 建立handler---输出位置
[handlers]
keys=consoleHandler,rotateFileHandler #终端输出
[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,) #文件输出
[handler_rotateFileHandler]
class=handlers.RotatingFileHandler
level=DEBUG
formatter=simpleFormatter
args=('ip_place.log', 'a', 200000, 9) #3. 建立formatters
[formatters]
keys=simpleFormatter [formatter_simpleFormatter]
format=[%(asctime)s](%(levelname)s)%(name)s : %(message)s #4. 建立logger与handler的联系
[logger_root]
level=DEBUG
handlers=consoleHandler [logger_example]
level=DEBUG
handlers=rotateFileHandler
qualname=example
propagate=0







一个例子:

使用python的logging模块

一、从一个使用场景开始







开发一个日志系统, 既要把日志输出到控制台, 还要写入日志文件







Python代码

  1. import logging
  2. # 创建一个logger
  3. logger = logging.getLogger('mylogger')
  4. logger.setLevel(logging.DEBUG)
  5. # 创建一个handler,用于写入日志文件
  6. fh = logging.FileHandler('test.log')
  7. fh.setLevel(logging.DEBUG)
  8. # 再创建一个handler,用于输出到控制台
  9. ch = logging.StreamHandler()
  10. ch.setLevel(logging.DEBUG)
  11. # 定义handler的输出格式
  12. formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
  13. fh.setFormatter(formatter)
  14. ch.setFormatter(formatter)
  15. # 给logger添加handler
  16. logger.addHandler(fh)
  17. logger.addHandler(ch)
  18. # 记录一条日志
  19. logger.info('foorbar')

复制代码

运行后, 在控制台和日志文件都有一条日志:







Java代码  

1.2011-08-31 19:18:29,816 - mylogger - INFO - foorbar  

2011-08-31 19:18:29,816 - mylogger - INFO - foorbar 







二、logging模块的API







结合上面的例子,我们说下几个最常使用的API



logging.getLogger([name])

返回一个logger实例,如果没有指定name,返回root logger。

只要name相同,返回的logger实例都是同一个而且只有一个,即name和logger实例是

一一对应的。这意味着,无需把logger实例在各个模块中传递。只要知道name,就能得到 

同一个logger实例

 



Logger.setLevel(lvl)

设置logger的level, level有以下几个级别:











NOTSET < DEBUG < INFO < WARNING < ERROR < CRITICAL





如果把looger的级别设置为INFO, 那么小于INFO级别的日志都不输出, 大于等于INFO级

别的日志都输出

Python代码

  1. logger.debug("foobar")    # 不输出
  2. logger.info("foobar")        # 输出
  3. logger.warning("foobar") # 输出
  4. logger.error("foobar")      # 输出
  5. logger.critical("foobar")    # 输出

复制代码

Logger.addHandler(hdlr)

logger可以雇佣handler来帮它处理日志, handler主要有以下几种:

StreamHandler: 输出到控制台

FileHandler:   输出到文件

handler还可以设置自己的level以及输出格式。





logging.basicConfig([**kwargs])

* 这个函数用来配置root logger, 为root logger创建一个StreamHandler, 

   设置默认的格式。

* 这些函数: logging.debug()、logging.info()、logging.warning()、

   logging.error()、logging.critical() 如果调用的时候发现root logger没有任何 

   handler, 会自动调用basicConfig添加一个handler

* 如果root logger已有handler, 这个函数不做任何事情





使用basicConfig来配置root logger的输出格式和level:

Python代码

  1. import logging
  2. logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG)
  3. logging.debug('This message should appear on the console')

复制代码

三、关于root logger以及logger的父子关系



 

前面多次提到root logger, 实际上logger实例之间还有父子关系, root logger就是处于

最顶层的logger, 它是所有logger的祖先。如下图: 



root logger是默认的logger

如果不创建logger实例, 直接调用logging.debug()、logging.info()logging.warning()、logging.error()、logging.critical()这些函数,

那么使用的logger就是 root logger, 它可以自动创建,也是单实例的。





如何得到root logger

通过logging.getLogger()或者logging.getLogger("")得到root logger实例。





默认的level

root logger默认的level是logging.WARNING





如何表示父子关系

logger的name的命名方式可以表示logger之间的父子关系. 比如:

parent_logger = logging.getLogger('foo')

child_logger = logging.getLogger('foo.bar')





什么是effective level

logger有一个概念,叫effective level。 如果一个logger没有显示地设置level,那么它就

用父亲的level。如果父亲也没有显示地设置level, 就用父亲的父亲的level,以此推....

最后到达root logger,一定设置过level。默认为logging.WARNING

child loggers得到消息后,既把消息分发给它的handler处理,也会传递给所有祖先logger处理, 





来看一个例子

Python代码

  1. import logging
  2. # 设置root logger
  3. r = logging.getLogger()
  4. ch = logging.StreamHandler()
  5. ch.setLevel(logging.DEBUG)
  6. formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
  7. ch.setFormatter(formatter)
  8. r.addHandler(ch)
  9. # 创建一个logger作为父亲
  10. p = logging.getLogger('foo')
  11. p.setLevel(logging.DEBUG)
  12. ch = logging.StreamHandler()
  13. ch.setLevel(logging.DEBUG)
  14. formatter = logging.Formatter('%(asctime)s - %(message)s')
  15. ch.setFormatter(formatter)
  16. p.addHandler(ch)
  17. # 创建一个孩子logger
  18. c = logging.getLogger('foo.bar')
  19. c.debug('foo')

复制代码

输出如下:





Python代码

  1. 2011-08-31 21:04:29,893 - foo
  2. 2011-08-31 21:04:29,893 - DEBUG - foo

复制代码

可见, 孩子logger没有任何handler,所以对消息不做处理。但是它把消息转发给了它的父

亲以及root logger。最后输出两条日志。

转自:http://bbs.chinaunix.net/thread-3590256-1-1.html

python模块 ---logging模块的更多相关文章

  1. Python之logging模块

    一.引言 之前在写一些小程序的时候想把日志内容打到文件中,所以就自己写了一个logger.py的程序,如下: #!/usr/bin/python # -*- coding=utf-8 -*- impo ...

  2. python的logging模块

    python提供了一个日志处理的模块,那就是logging 导入logging模块使用以下命令: import logging logging模块的用法: 1.简单的将日志打印到屏幕上 import ...

  3. python的logging模块之读取yaml配置文件。

    python的logging模块是用来记录应用程序的日志的.关于logging模块的介绍,我这里不赘述,请参见其他资料.这里主要讲讲如何来读取yaml配置文件进行定制化的日志输出. python要读取 ...

  4. Python全栈之路----常用模块----logging模块

    很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误.警告等信息输出,python的logging模块提供了标准的日志接口,你可以通过它存储各种格式的日志,loggin ...

  5. python中logging模块的用法

    很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误.警告等信息输出,python的logging模块提供了标准的日志接口,你可以通过它存储各种格式的日志,loggin ...

  6. Python模块——logging模块

    logging模块简介 logging模块定义的函数和类为应用程序和库的开发实现了一个灵活的事件日志系统.logging模块是Python的一个标准库模块, 由标准库模块提供日志记录API的关键好处是 ...

  7. python基础--logging模块

    很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误.警告等信息输出,python的logging模块提供了标准的日志接口,你可以通过它存储各种格式的日志,loggin ...

  8. Python中logging模块的基本用法

    在 PyCon 2018 上,Mario Corchero 介绍了在开发过程中如何更方便轻松地记录日志的流程. 整个演讲的内容包括: 为什么日志记录非常重要 日志记录的流程是怎样的 怎样来进行日志记录 ...

  9. Python日志(logging)模块,shelve,sys模块

    菜鸟学python第十七天 1.logging 模块 logging模块即日志记录模块 用途:用来记录日志 为什么要记录日志: 为了日后复查,提取有用信息 如何记录文件 直接打开文件,往里写东西 直接 ...

随机推荐

  1. js中子页面父页面方法和变量相互调用

    (1)子页面调用父页面的方法或者变量: window.parent.方法()或者变量名window.parent相当于定位到父页面 之后的操作和在父页面中写代码一样写 window.parent.aa ...

  2. HDU 5455 Fang Fang 水题,但题意描述有问题

    题目大意:f[1]=f,f[2]=ff,f[3]=ffc,以后f[n]每增加1,字符串增加一个c.给出一个字符串,求最少有多少个f[]组成.(字符串首尾相连,比如:ffcf可看做cfff) 题目思路: ...

  3. Rar related CMD

    recursively add folder Document to archive: (with all the files) rar a *.rar Document recursively ad ...

  4. 【语法】修饰符 static extern const

    转载自:http://my.oschina.net/u/2560887/blog/552683 一.C语言中的static的作用 在C语言中,static的字面意思很容易把我们导入歧途,其实它的作用有 ...

  5. Android自定义XML属性

    <?xml version="1.0" encoding="utf-8"?> <resources> <declare-style ...

  6. lucene的多种搜索2-SpanQuery

    SpanQuery按照词在文章中的距离或者查询几个相邻词的查询 SpanQuery包括以下几种: SpanTermQuery:词距查询的基础,结果和TermQuery相似,只不过是增加了查询结果中单词 ...

  7. CodeForces 701C They Are Everywhere(map的应用)

    这个题比较好的解决办法,我觉得还是map,map的size可以很快的知道我们选了几个字母,而且可以作为计数器,知道每一个字母出现了多少次, erase函数可以清除掉一个元素. 所以,定义两个指针L和R ...

  8. 转:Web安全与Rational AppScan入门

    Web 应用的基础概念 在讨论 Web 应用安全之前,先简单介绍一下 Web 应用基础概念,这样便于理解为什么 Web 应用是脆弱的,容易受到攻击. 1. 什么是 Web 应用 Web 应用是由动态脚 ...

  9. Android Studio ADB响应失败解决方法(2CTo.com)

    当启动Android Studio时,如果弹出 adb not responding. you can wait more,or kill "adb.exe" process ma ...

  10. Centos下安装jdk详解

    环境: 系统: [root@Wulaoer ~]# cat /proc/version Linux version 2.6.32-431.el6.x86_64 (mockbuild@c6b8.bsys ...