logging 日志模块

http://python.usyiyi.cn/python_278/library/logging.html 中文官方

http://blog.csdn.net/zyz511919766/article/details/25136485清晰明了,入门必备

http://my.oschina.net/leejun2005/blog/126713 继承讲的很棒

http://my.oschina.net/u/126495/blog/464892 实例分析

一:概述

在实际项目中,需要对一些数据进行日志记录,并将日志记录到不同的存储单元中,例如数据库,文本,或者推送到图形化界面中,当需要时发现自己实现一个日

志库其实是要很大的代价,因此,第三方的日志库上进行定制化处理 正文内容是对logging的理解和使用方式,非常方便

1:四个主要类,使用官方文档中的概括:

logger提供了应用程序可以直接使用的接口;

handler将(logger创建的)日志记录发送到合适的目的输出;

filter提供了细度设备来决定输出哪条日志记录;用处不太大

formatter决定日志记录的最终输出格式

2:模块级函数

logging.getLogger([name]):#返回一个logger对象,如果没有指定名字将返回root logger,最常用

logging.basicConfig(): #给logger对象的配置管理函数 ,不常用

logging.debug()、logging.info()、logging.warning()、logging.error()、logging.critical(): #logger的日志级别

二: logging工作流演示

cat demo.py

#coding:utf-8

import logging

# 创建一个logger命名为mylogger, %(name)s可调用这个名字

mylogger = logging.getLogger('mylogger')

mylogger.setLevel(logging.DEBUG)

# 定义日志输出格式formatter

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

# 创建一个handler,用于写入日志文件,只输出debug级别以上的日志,并调用定义的输出格式

fh = logging.FileHandler('test.log')

fh.setLevel(logging.DEBUG)

fh.setFormatter(formatter)

# 再创建一个handler,用于输出到控制台, 一般不用

ch = logging.StreamHandler()

ch.setLevel(logging.DEBUG)

ch.setFormatter(formatter)

# 给我们开始实例化的logger对象添加handler

mylogger.addHandler(fh)

mylogger.addHandler(ch)

# 直接在本模块中调用记录两条日志——生产环境会封装成函数调用

mylogger.info('foorbar')

mylogger.debug('just a test ')

$ python demo.py

2015-10-30 15:44:01,722 - mylogger - test1.py- INFO - foorbar

2015-10-30 15:44:01,723 - mylogger - test1.py- DEBUG - just a test

http://www.php101.cn/2015/03/05/Python%E4%B8%AD%E7%9A%84Logging%E7%AE%80%E4%BB%8B/ 精彩实例

三:logging模块的API

1:logging.getLogger([name])

返回一个logger实例,如果没有指定name,返回root logger。只要name相同,返回的logger实例都是同一个而且只有一个,即name和logger实例是一一对

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

2:logger.setLevel(lvl)——设置logger的level,

level有以下几个级别:

NOTSET < DEBUG < INFO < WARNING < ERROR < CRITICAL

不同日志级别对应的数字对照

级别 数值

CRITICAL 50

ERROR 40

WARNING 30

INFO 20

DEBUG 10

NOTSET 0

如果把logger的级别设置为INFO, 那么小于INFO级别的日志都不输出, 大于等于INFO级别的日志都输出。也就意味着同一个logger实例,如果多个地方调用,会

出现很多重复的日志

logger.debug("debug") # 不输出

logger.info("info") # 输出

logger.warning("warning") # 输出

logger.error("error") # 输出

logger.critical("critical") # 输出

3:logger.addHandler(hd)——logger雇佣handler来帮它处理日志

handler对象负责发送相关的信息到指定目的地。Python的日志系统有多种Handler可以使用。有些Handler可以把信息输出到控制台,有些Logger可以把信息输

出到文件,还有些 Handler可以把信息发送到网络上。如果觉得不够用,还可以编写自己的Handler。可以通过addHandler()方法添加多个多handler

handler主要有以下几种:

logging.StreamHandler:#日志输出到流即控制台,可以是sys.stderr、sys.stdout

logging.FileHandler:#日志输出到文件

logging.handlers.RotatingFileHandler#日志输出到文件,并按照设定的日志文件大小切割

logging.handlers.TimedRotatingFileHandler#日志输出到文件,并按设定的时间切割日志文件

logging.handlers.SocketHandler:#远程输出日志到TCP/IP sockets

logging.handlers.DatagramHandler:#远程输出日志到UDP sockets

logging.handlers.SMTPHandler:#远程输出日志到邮件地址

logging.handlers.SysLogHandler:#日志输出到syslog

logging.handlers.NTEventLogHandler:#远程输出日志到Windows NT/2000/XP的事件日志

logging.handlers.MemoryHandler:#日志输出到内存中的制定buffer

由于StreamHandler和FileHandler是常用的日志处理方式,所以直接包含在logging模块中,而其他方式则包含在logging.handlers模块中,

handle常见调用

Handler.setLevel(lel)#指定被处理的信息级别,低于lel级别的信息将被忽略

Handler.setFormatter() #给这个handler选择一个格式

Handler.addFilter(filt)、Handler.removeFilter(filt):#新增或删除一个filter对象

举两个栗子

1: logging内部调用——测试学习即可

cat demo.py

import logging

import logging.handlers

LOG_FILE = 'api.log'

#定义日志文件切割规则最多备份5个日志文件,每个日志文件最大10M

handler = logging.handlers.RotatingFileHandler(LOG_FILE, maxBytes = 10*1024*1024, backupCount = 5)

#handler=logging.handlers.TimedRotatingFileHandler(LOG_FILE, when='midnight') #每天零点切换

#定义日志输出格式

fmt = '%(asctime)s - %(filename)s:%(lineno)s - %(name)s - %(message)s'

formatter = logging.Formatter(fmt) # 实例化formatter

handler.setFormatter(formatter) # 为handler添加formatter

#实例化一个logger对象,并为其绑定handle

mylogger = logging.getLogger('test')

mylogger.addHandler(handler) # 为mylogger添加handler

mylogger.setLevel(logging.DEBUG) # 为mylogger设置输出级别

#调用mylogger

mylogger.info('first info message')

mylogger.debug('first debug message')

2: logging封装为函数——适用生产环境中

cat util.py

#/usr/bin/env python

#coding:utf-8

import logging,logging.handlers

def WriteLog(log_name):

log_filename = "/tmp/test.log"

log_level = logging.DEBUG

format =logging.Formatter('%(asctime)s %(filename)s [line:%(lineno)2d]-%(funcName)s %(levelname)s %(message)s')

handler =logging.handlers.RotatingFileHandler(log_filename, mode='a', maxBytes=10*1024*1024, backupCount=5)

handler.setFormatter(format)

logger = logging.getLogger(log_name)

logger.addHandler(handler)

logger.setLevel(log_level)

return logger#函数最终将实例化的logger对象返回,后面直接调用即可

if __name__ == "__main__":

WriteLog('api').info('123')#模块内部直接调用函数。等价下面两行,下面的方法不推荐

# writelog = WriteLog('api')

# writelog.info('123')

'''

外面程序调用函数

cat test.py

import util

def index()

util.WriteLog('api').info('123')

index()

'''

4:logging.basicConfig([**kwargs])——加载logger的各项配置参数,不好用

cat test.py

import logging

logging.basicConfig(level=logging.DEBUG,#输出debug及其级别更高级别的日志

format='%(asctime)s %(filename)s [line:%(lineno)d] %(levelname)s %(message)s',

datefmt='%d %b %Y %H:%M:%S',

filename='myapp.log',#日志文件输出的文件地址,不写默认打印到桌面

filemde='w')

logging.debug("this is debug message")

logging.info("this is info message")

logging.warning("this is warning message")

tail -f myapp.log

30 Oct 2015 14:18:51 test.py [line:8] DEBUG this is debug message

30 Oct 2015 14:18:51 test.py [line:9] INFO this is info message

30 Oct 2015 14:18:51 test.py [line:10] WARNING this is warning message

关于logging.basicConfig函数的常用配置:

filename:指定日志文件名

filemode:和file函数意义相同,指定日志文件的打开模式,'w'或'a'

datefmt:指定时间格式,同time.strftime()

level:设置日志级别,默认为logging.WARNING,即warning及级别更高的日志才输出

stream: 指定将日志的输出流,可以指定输出到sys.stderr,sys.stdout或者文件,默认输出到sys.stderr,当stream和filename同时指定时,stream被

忽略

format:指定输出的格式和内容,format可以输出很多有用信息,如上例所示:

%(name)s打印logger名,默认为root

%(levelno)s:打印日志级别的数值

%(levelname)s: 打印日志级别名称

%(pathname)s:打印当前执行程序的路径,其实就是sys.argv[0]

%(filename)s:打印当前执行程序名

%(funcName)s:打印日志的当前函数

%(lineno)d:打印日志的当前行号

%(asctime)s:打印日志的时间

%(message)s: 打印日志信息

%(thread)d: 打印线程ID

%(threadName)s: 打印线程名称

%(process)d: 打印进程ID

5: logging.config模块通过配置文件的方式,加载logger的参数——最好用的方式

cat logger.conf

# 定义logger模块,root是父类,必需存在的,其它的是自定义。

# logging.getLogger(NAME)就相当于向logging模块注册了实例化了

# name 中用 . 表示 log 的继承关系

[loggers]

keys=root,example01,example02

# [logger_xxxx] logger_模块名称

# level 级别,级别有DEBUG、INFO、WARNING、ERROR、CRITICAL

# handlers 处理类,可以有多个,用逗号分开

# qualname logger名称,应用程序通过 logging.getLogger获取。对于不能获取的名称,则记录到root模块。

# propagate 是否继承父类的log信息,0:否 1:是

[logger_root]

level=DEBUG

handlers=hand01,hand02

[logger_example01]

handlers=hand01,hand02

qualname=example01

propagate=0

[logger_example02]

handlers=hand01,hand03

qualname=example02

propagate=0

# [handler_xxxx]

# class handler类名

# level 日志级别

# formatter,上面定义的formatter

# args handler初始化函数参数

[handlers]

keys=hand01,hand02,hand03

[handler_hand01]

class=StreamHandler

level=INFO

formatter=form02

args=(sys.stderr,)

[handler_hand02]

class=FileHandler

level=DEBUG

formatter=form01

args=('myapp.log', 'a')

[handler_hand03]

class=handlers.RotatingFileHandler

level=INFO

formatter=form02

args=('myapp.log', 'a', 10*1024*1024, 5)

# 日志格式

[formatters]

keys=form01,form02

[formatter_form01]

format=%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s

datefmt=%a, %d %b %Y %H:%M:%S

[formatter_form02]

format=%(asctime)s%(name)-12s: %(levelname)-8s %(message)s

datefmt=%a, %d %b %Y %H:%M:%S

调用

import logging

import logging.config

logging.config.fileConfig("logger.conf")

logger = logging.getLogger("example01")

logger.debug('This is debug message')

logger.info('This is info message')

logger.warning('This is warning message')

生产环境中使用案例——通过函数定义调用

A:定义到工具模块中

cat util.py

import logging,

import logging.config

def write_log(loggername):

work_dir = os.path.dirname(os.path.realpath(__file__))

log_conf= os.path.join(work_dir, 'conf/logger.conf')

logging.config.fileConfig(log_conf)

logger = logging.getLogger(loggername)

return logger

B: 外部模块调用

cat test.py

import util

util.write_log('api').info('just a test')

四:关于root logger以及logger的父子关系

logger实例之间还有父子关系, root logger就是处于最顶层的logger, 它是所有logger的祖先。如下图:

如何得到root logger

root logger是默认的logger如果不创建logger实例, 直接调用logging.debug()、logging.info()logging.warning(),logging.error()、logging.critical()这

些函数,

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

root logger的日志级别

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处理,

eg:

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。最后输出两条日志。

这也就出现了一个问题,同一条日志会重复输出

解决方案

1:每个logger实例都给一个独立的名字,输出之间互不影响,

2: logging.conf中定义不继承

python log文件如何不写入syslog_python 自动化之路 logging日志模块相关推荐

  1. python log文件如何不写入syslog_Centos下python 对syslog重写进行日志记录

    在Linux 环境下,python自带一个syslog的模块可以进行日志记录.python可以利用logging模块来重写syslog,这样就可以自定义写入文件的文件名.如果不做配置则直接写入到/va ...

  2. python写日志文件_Python logging日志模块 配置文件方式

    在一些微服务或web服务中我们难免需要日志功能,用来记录一些用户的登录记录,操作记录,以及一些程序的崩溃定位,执行访问定位等等; Python内置 非常强大的日志模块 ==> logging 今 ...

  3. python logging日志分割_python logging日志模块以及多进程日志

    本篇文章主要对 python logging 的介绍加深理解.更主要是 讨论在多进程环境下如何使用logging 来输出日志, 如何安全地切分日志文件. 1. logging日志模块介绍 python ...

  4. python中logging模块详解_python logging日志模块详解

    logging 日志模块详解 用Python写代码的时候,在想看的地方写个print xx 就能在控制台上显示打印信息,这样子就能知道它是什么了,但是当我需要看大量的地方或者在一个文件中查看的时候,这 ...

  5. python logging日志模块以及多进程日志

    本篇文章主要对 python logging 的介绍加深理解.更主要是 讨论在多进程环境下如何使用logging 来输出日志, 如何安全地切分日志文件. 原出处博客 1. logging日志模块介绍 ...

  6. python log文件_Python logging基本使用

    1.打印到控制台 #-*- coding: UTF-8 -*- importloggingdeflogFileTest(): logging.debug('This is debug') loggin ...

  7. Python文件操作-文本文件、二进制文件、csv文件的读取写入、OS、shutil、CSV模块、常用字符编码

    Python文件操作 文本文件和二进制文件 文件操作相关模块 open()创建文件对象 文件对象的常用属性和方法 pickle 序列化 文本文件读取和写入 文本文件写入步骤 write()/write ...

  8. python入门文件读取与写入_使用Python对Dicom文件进行读取与写入的实现

    Pydicom 单张影像的读取 使用 pydicom.dcmread() 函数进行单张影像的读取,返回一个pydicom.dataset.FileDataset对象. import os import ...

  9. python 日志输出为json格式文件_Py修行路 python基础 (二十一)logging日志模块 json序列化 正则表达式(re)...

    一.日志模块 两种配置方式:1.config函数 2.logger #1.config函数 不能输出到屏幕 #2.logger对象 (获取别人的信息,需要两个数据流:文件流和屏幕流需要将数据从两个数据 ...

最新文章

  1. 实用Jquery开发自己的插件
  2. 鲁亿通欲收购昇辉控股 跨界布局照明、智慧城市领域
  3. 【Spring】Spring学习笔记-01-入门级实例
  4. 北京环球度假区:尚未发布票务信息,未面向公众销售任何门票
  5. 全网首发:linux任务栏分组的研究
  6. 人大经济论坛SAS入门到高级教程
  7. html5网页制作的基本步骤,网页制作流程介绍
  8. oracle 查询入职年限,计算入职年限员工人数占总人数的百分比
  9. 【托业】【新托业TOEIC新题型真题】学习笔记2-题库一--P5-6
  10. 类似组卷网实现快速组卷功能,实现试题,试卷,课件快速录入、搜索、分类查询,支持mathtype和latex2word。
  11. 解线性方程组c语言实验报告,实验五线性方程组的迭代法实验
  12. 深度学习理论——ssd从之前的网络断点接着训练
  13. Information Communication Technology,简称ICT
  14. 用canvas画了个多啦A梦
  15. MATLAB去读网页源码时中文乱码
  16. python 音频数据归一化
  17. MySql_ZIP安装 教导指南
  18. iOS Objective-C(2014-1-6 20:30、20140114,20140824,20150926、20160106、20160110、20160123)
  19. UPnP 体系架构和基本原理 —— Linux SDK for UPnP Devices
  20. 告别极寒,科学家突破将量子计算机运行最低温提了15倍

热门文章

  1. kubernetes CSI(中)
  2. android tabhost黑色背景,关于Android TabHost切换Tab字体的颜色背景颜色改变
  3. ElasticSearch 性能优化总结 04
  4. Chemkin模拟煤粉氨气混合燃料燃烧特性
  5. 悄悄告诉你免拔卡TikTok不要再用,一图吓死你
  6. CG动画制作——实训项目前期工作(二)
  7. 四信5G工业路由器全面支持中国移动研究院5G专网质量探针,满足5G专网高质保障需求
  8. 寄存器模型 — UVM
  9. 毕业设计_基于Android的陌生人交友软件的开发与实现
  10. 老机器升级Bigsur以后没有管理员账户的解决记录