本文章转自kenby的博客,比较全面易懂,转来留作以后使用。

http://kenby.iteye.com/blog/1162698

一、从一个使用场景开始

import logging

# 创建一个logger
logger = logging.getLogger('mylogger')
logger.setLevel(logging.DEBUG) # 创建一个handler,用于写入日志文件
fh = logging.FileHandler('test.log')
fh.setLevel(logging.DEBUG) # 再创建一个handler,用于输出到控制台
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG) # 定义handler的输出格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
ch.setFormatter(formatter) # 给logger添加handler
logger.addHandler(fh)
logger.addHandler(ch) # 记录一条日志
logger.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有以下几个级别:

>>> import logging
>>> print(logging.NOTSET)
0
>>> print(logging.DEBUG)
10
>>> print(logging.INFO)
20
>>> print(logging.WARNING)
30
>>> print(logging.ERROR)
40
>>> print(logging.CRITICAL)
50

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

logger.debug("foobar")    # 不输出
logger.info("foobar") # 输出
logger.warning("foobar") # 输出
logger.error("foobar") # 输出
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:

import logging
logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG)
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处理,

来看一个例子

import logging

# 设置root logger
r = logging.getLogger()
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
r.addHandler(ch) # 创建一个logger作为父亲
p = logging.getLogger('foo')
p.setLevel(logging.DEBUG)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(message)s')
ch.setFormatter(formatter)
p.addHandler(ch) # 创建一个孩子logger
c = logging.getLogger('foo.bar')
c.debug('foo')

输出如下:

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

可见, 孩子logger没有任何handler,所以对消息不做处理。但是它把消息转发给了它的父亲以及root logger。最后输出两条日志。

【python,logging】python中的logging模块的更多相关文章

  1. python在数据处理中常用的模块之numpy

    一 numpy模块 NumPy系统是Python的一种开源的数值计算扩展.这种工具可用来存储和处理大型矩阵,比Python自身的嵌套列表(nested list structure)结构要高效的多(该 ...

  2. python在数据处理中常用的模块之matplotlib

    <利用python进行数据分析>读书笔记--第八章 绘图和可视化 python 画子图(add_subplot & subplot)

  3. Python连载11-Python中os.path模块简介

    一.os.path(和路径相关的木块) 1.函数:abspath() (1)含义:将路径转化为绝对路径的形式(absolute path) (2)格式:os.path.abspath(相对路径) (3 ...

  4. Python 3 中的json模块使用

    1. 概述 JSON (JavaScript Object Notation)是一种使用广泛的轻量数据格式. Python标准库中的json模块提供了JSON数据的处理功能. Python中一种非常常 ...

  5. Python中的base64模块

    本文介绍Python 2.7中的base64模块,该模块提供了基于rfc3548的Base16, 32, 64编解码的接口.官方文档,参考这里. 该模块提供两套接口,传统接口基于rfc1521的Bas ...

  6. Python中的Pexpect模块的简单使用

    Pexpect 是一个用来启动子程序并对其进行自动控制的 Python 模块. Pexpect 可以用来和像 ssh.ftp.passwd.telnet 等命令行程序进行自动交互.以下所有代码都是在K ...

  7. Python(2.7.6) 标准日志模块的简单示例

    Python 标准库中的 logging 模块提供了一套标准的 API 来处理日志信息的打印. import logging logging.basicConfig( level = logging. ...

  8. Python库的使用之-Sys模块

    Python标准库之sys模块使用详解,讲解了使用sys模块获得脚本的参数.处理模块. 使用sys模块操作 模块搜索路径.使用sys模块查找内建模块.使用sys模块查找已导入的模块,重定向输出以及重定 ...

  9. Python中的logging模块

    http://python.jobbole.com/86887/ 最近修改了项目里的logging相关功能,用到了python标准库里的logging模块,在此做一些记录.主要是从官方文档和stack ...

  10. Python中的logging模块【转】https://www.cnblogs.com/yelin/p/6600325.html

    [转]https://www.cnblogs.com/yelin/p/6600325.html 基本用法 下面的代码展示了logging最基本的用法. 1 # -*- coding: utf-8 -* ...

随机推荐

  1. GWT工程架构分析与理解

    上一篇文章中介绍了GWT技术的一些理论性的东西,涉及到GWT得一些技术原理及实现.接下来笔者将通过创建一个GWT工程去理解分析GWT工程架构.     GWT工程架构解析 笔者使用的是Eclipse插 ...

  2. WEB数据挖掘(十三)——关联规则与序列模式(1)

    一.Apriori算法简介:  Apriori算法是一种挖掘关联规则的频繁项集算法,其核心思想是通过候选集生成和情节的向下封闭检测两个阶段来挖掘频繁项集. Apriori(先验的,推测的)算法应用广泛 ...

  3. iOS维码的生成和扫描

    iOS生成二维码(彩色 + 阴影) http://www.jianshu.com/p/85e131155b79?plg_nld=1&plg_uin=1&plg_auth=1&p ...

  4. Castle IOC容器组件生命周期管理

    主要内容 1.生命处理方式 2.自定义生命处理方式 3.生命周期处理 一.生命处理方式 我们通常创建一个组件的实例使用new关键字,这样每次创建出来的都是一个新的实例,如果想要组件只有一个实例,我们会 ...

  5. (剑指Offer)面试题14:调整数组顺序使奇数位于偶数前面

    题目: 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变. 如果去掉约束条件: ...

  6. iepngfix.htc让PNG-24在IE6中透明的方法(转)

    add:360用的一个方法: <!--[if IE 6]> <script src="http://se.360.cn/js/DD_belatedPNG.js"& ...

  7. UIWebView 获取当前的javascript上下文,并js,oc互调

    OC调用UIWebView 中的js,网上例子很多,最常用的是UIWebView自带的一个方法: - (NSString *)stringByEvaluatingJavaScriptFromStrin ...

  8. NameThreadForDebugging -- Naming threads for debugging

    http://forums.devart.com/viewtopic.php?t=16907 type tagTHREADNAME_INFO = record dwType : LongWord; / ...

  9. PostgreSQL的AnynonArray的例子

    程序: CREATE OR REPLACE FUNCTION kappend(anynonarray, anyelement) RETURNS text AS $$ ; $$ LANGUAGE SQL ...

  10. js查看浏览器类型和版本

    var Sys = {}; var ua = navigator.userAgent.toLowerCase(); var s; var scan; (s = ua.match(/msie ([\d. ...