设为首页 收藏本站
查看: 1186|回复: 0

[经验分享] Python 模块学习 logging(1)

[复制链接]

尚未签到

发表于 2015-4-25 11:13:52 | 显示全部楼层 |阅读模式
一、快速入门
1、基础知识
  日志的作用是跟踪,django项目中不可缺少。
  派出:

  控制台输出:print()
  报告事件,发生在一个程序的正常运行:logging.info()或logging.debug()
  发出警告关于一个特定的运行时事件:warnings.warn()或logging.warning()
  报告一个错误对于一个特定的运行时事件:异常处理
  报告一个错误当没有引发一个异常:logging.error()、logging.exception()或logging.critical()

  级别:

  DEBUG:详细的信息,通常只出现在诊断问题上
  INFO:确认一切按预期运行
  WARNING:一个迹象表明,一些意想不到的事情发生了,或表明一些问题在不久的将来(例如。磁盘空间低”)。这个软件还能按预期工作。
  ERROR:个更严重的问题,软件没能执行一些功能
  CRITICAL:一个严重的错误,这表明程序本身可能无法继续运行

  日志一共分成5个等级,从低到高分别是:DEBUG INFO WARNING ERROR CRITICAL。这5个等级,也分别对应5种打日志的方法: debug 、info 、warning 、error 、critical。默认的是WARNING,当在WARNING或之上时才被跟踪。有两种方式记录跟踪,一种输出控制台,另一种是记录到文件中,如日志文件。
2、简单日志操作



import logging
logging.warning('error')    #在控制台输出WARNING:root:error
logging.info('msg')         #没有输出,因为默认级别是 WARNING,INFO小于此级别
  写入一个文件里面:



#Logging to a file
import os
import logging
FILE = os.getcwd()
logging.basicConfig(filename=os.path.join(FILE,'log.txt'),level=logging.DEBUG)
logging.debug('写进去')
logging.info('滚进去')
logging.warning('也滚进去')
  
运行之后,打开该文件,效果如下:


DSC0000.png
3、多个模块中操作日志


#log1.py
import logging
def lo():
logging.info('log1--')

#log2.py
import logging
import os
FILE = os.getcwd()
import log1
def main():
logging.basicConfig(filename=os.path.join(FILE,'log.txt'),level=logging.INFO)
logging.info('start--')
log1.lo()
logging.info('end--')
if __name__ == '__main__':
main()
  运行后打开log.txt,结果如下:
  INFO:root:start--
INFO:root:log1--
INFO:root:end--

4、日志的格式化字符串




logging.warning('name:%s msg:%s','BeginMan','Hi')               #方式一
logging.warning('name:%s msg:%s' %('BeginMan','Hi'))            #方式二
logging.warning('name:{0} msg:{1}'.format('BeginMan','Hi'))     #方式三
from string import Template                                     #方式四
msg = Template('name:$who msg:$what')
logging.warning(msg.substitute(who='BeginMan',what='Hi'))
5、改变显示消息格式
  指定自己所需的格式,如下:



logging.basicConfig(format='%(levelname)s:%(message)s')
logging.warning('msg')      #WARNING:msg
logging.basicConfig(format='Hi,试试这个:%(asctime)s:%(message)s')
logging.warning('msg')      #Hi,试试这个:2013-09-22 14:25:21,936:msg
logging.basicConfig(format='%(asctime)s:%(message)s',datefmt='%m/%d/%Y %I:%M:%S %p')
logging.warning('msg')      #09/22/2013 02:28:14 PM:msg
  format: 指定输出的格式和内容,format可以输出很多有用信息,如上例所示:

  %(levelno)s: 打印日志级别的数值
%(levelname)s: 打印日志级别名称
%(pathname)s: 打印当前执行程序的路径,其实就是sys.argv[0]
%(filename)s: 打印当前执行程序名
%(funcName)s: 打印日志的当前函数
%(lineno)d: 打印日志的当前行号
%(asctime)s: 打印日志的时间
%(thread)d: 打印线程ID
%(threadName)s: 打印线程名称
%(process)d: 打印进程ID
%(message)s: 打印日志信息




logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s:%(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%a, %d %b %Y %H:%M:%S',
filename = os.path.join(FILE,'log.txt'),
filemode='w')
logging.info('msg')
logging.debug('msg2')
  打开文件显示如下:
  Sun, 22 Sep 2013 15:23:13:log1.py[line:41] INFO msg
Sun, 22 Sep 2013 15:23:13:log1.py[line:42] DEBUG msg2

  这种格式字符串参见:http://docs.python.org/2.7/library/logging.html#logrecord-attributes
二、高级进阶
  接下来学习一些日志组件以及一些高级部分。日志组件包括:loggers、handlers,filters,formatters.
  Logger 对象扮演了三重角色.首先,它暴露给应用几个方法以便应用可以在运行时写log.其次,Logger对象按照log信息的严重程度或者根据filter对 象来决定如何处理log信息(默认的过滤功能).最后,logger还负责把log信息传送给相关的loghandlers.
  Handler对象负责分配合适的log信息(基于log信息的严重 程度)到handler指定的目的地.Logger对象可以用addHandler()方法添加零个或多个handler对象到它自身.一个常见的场景 是,一个应用可能希望把所有的log信息都发送到一个log文件中去,所有的error级别以上的log信息都发送到stdout,所有critical 的log信息通过email发送.这个场景里要求三个不同handler处理,每个handler负责把特定的log信息发送到特定的地方.
  filter:细致化,选择哪些日志输出
  format:设置显示格式
1、logging.basicConfig([**kwargs]):

  Does basic configuration for the logging system by creating a StreamHandler with a default Formatter and adding it to the root logger. The functions debug(), info(), warning(), error() and critical() will call basicConfig() automatically if no handlers are defined for the root logger.
  This function does nothing if the root logger already has handlers configured for it.

  为日志模块配置基本信息。kwargs 支持如下几个关键字参数:
filename :日志文件的保存路径。如果配置了些参数,将自动创建一个FileHandler作为Handler;
filemode :日志文件的打开模式。 默认值为'a',表示日志消息以追加的形式添加到日志文件中。如果设为'w', 那么每次程序启动的时候都会创建一个新的日志文件;
format :设置日志输出格式;
datefmt :定义日期格式;
level :设置日志的级别.对低于该级别的日志消息将被忽略;
stream :设置特定的流用于初始化StreamHandler;
  演示如下:



import logging
import os
FILE=os.getcwd()
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s:%(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%a, %d %b %Y %H:%M:%S',
filename = os.path.join(FILE,'log.txt'),
filemode='w')
logging.info('msg')
logging.debug('msg2')
2、logging.getLogger([name])
  创建Logger对象。日志记录的工作主要由Logger对象来完成。在调用getLogger时要提供Logger的名称(注:多次使用相同名称 来调用getLogger,返回的是同一个对象的引用。),Logger实例之间有层次关系,这些关系通过Logger名称来体现,如:
  p = logging.getLogger("root")
  c1 = logging.getLogger("root.c1")
  c2 = logging.getLogger("root.c2")
  例子中,p是父logger, c1,c2分别是p的子logger。c1, c2将继承p的设置。如果省略了name参数, getLogger将返回日志对象层次关系中的根Logger。



import logging
'''命名'''
log2=logging.getLogger('BeginMan')  #生成一个日志对象
print log2  #
'''无名'''
log3 = logging.getLogger()
print log3  # 如果没有指定name,则返回RootLogger
'''最好的方式'''
log = logging.getLogger(__name__)#__name__ is the module’s name in the Python package namespace.
print log   #  Logger对象
print __name__  #__main__
三、Logger对象
  通过logging.getLogger(nam)来获取Logger对象,
  Class logging.Logger
  有如下属性和方法:
1、Logger.propagate



print log.propagate         #1
  具体参考:http://docs.python.org/2.7/library/logging.html
2、Logger.setLevel(lvl)
  设置日志的级别。对于低于该级别的日志消息将被忽略.



import logging
import os
logging.basicConfig(format="%(levelname)s,%(message)s",filename=os.path.join(os.getcwd(),'log.txt'),level=logging.DEBUG)
log = logging.getLogger('root.set')   #Logger对象
print log.propagate         #1
log.setLevel(logging.WARN)  #日志记录级别为WARNNING  
log.info('msg')             #不会被记录
log.debug('msg')            #不会被记录
log.warning('msg')
log.error('msg')
3、Logger.debug(msg [ ,*args [, **kwargs]])
  记录DEBUG级别的日志信息。参数msg是信息的格式,args与kwargs分别是格式参数。



import logging
logging.basicConfig(filename = os.path.join(os.getcwd(), 'log.txt'), level = logging.DEBUG)
log = logging.getLogger('root')
log.debug('%s, %s, %s', *('error', 'debug', 'info'))
log.debug('%(module)s, %(info)s', {'module': 'log', 'info': 'error'})
4、同上

Logger.info(msg[ , *args[ , **kwargs] ] )

Logger.warnning(msg[ , *args[ , **kwargs] ] )

Logger.error(msg[ , *args[ , **kwargs] ] )

Logger.critical(msg[ , *args[ , **kwargs] ] )

5、Logger.log(lvl, msg[ , *args[ , **kwargs] ] )
  记录日志,参数lvl用户设置日志信息的级别。参数msg, *args, **kwargs的含义与Logger.debug一样。



log.log(logging.ERROR,'%(module)s %(info)s',{'module':'log日志','info':'error'}) #ERROR,log日志 error
log.log(logging.ERROR,'再来一遍:%s,%s',*('log日志','error'))  #ERROR,再来一遍:log日志,error
6、Logger.exception(msg[, *args])
  以ERROR级别记录日志消息,异常跟踪信息将被自动添加到日志消息里。Logger.exception通过用在异常处理块中,如:



import logging
import os
logging.basicConfig(format="%(levelname)s,%(message)s",filename=os.path.join(os.getcwd(),'log.txt'),level=logging.DEBUG)
log = logging.getLogger('root')   #Logger对象
try:
raise Exception,u'错误异常'
except:
log.exception('exception')  #异常信息被自动添加到日志消息中  
打开文件,显示如下:

'''ERROR,exception
Traceback (most recent call last):
File "E:\project\py\src\log3.py", line 12, in
raise Exception,u'错误异常'
Exception: 错误异常
'''
7、Logger.addFilter(filt)
  指定过滤器
8、Logger.removeFilter(filt)
  移除指定的过滤器
9、Logger.filter(record)
  ....其他的后面介绍
四、 Handler对象、Formatter对象、Filter对象、Filter对象
这里简要介绍



#coding=utf8
'''
Created on 2013年9月23日
Function : Handler对象、Formatter对象、Filter对象、Filter对象
@author : BeginMan
'''
import logging
import os
'''Logger'''
l = logging.Logger('root')          #创建Logger对象
log = logging.getLogger('root')     #通过logging.getLogger创建Logger对象
print l                             #
print log                           #
'''Handler'''
handler = logging.Handler()         #创建Handler对象
handler.__init__(logging.DEBUG)     #通过设置level来初始化Handler实例
handler.createLock()                #初始化一个线程锁可以用来序列化访问底层I / O功能,这可能不是线程安全的。
handler.acquire()                   #获取线程锁通过handler.createLock()
handler.release()                   #释放线程锁通过获取handler.acquire()
handler.setLevel(logging.DEBUG)     #设置临界值,如果Logging信息级别小于它则被忽视,当一个handler对象被创建,级别没有被设置,导致所有的信息会被处理。
handler.setFormatter("%(levelname)s,%(message)s")              #设置格式
# handler.addFilter(filter)         #添加指定的过滤器
# handler.removeFilter(filter)      #移除指定的过滤器
# handler.filter(record)            #通过设置过滤器适用于记录并返回真值如果要处理的记录
handler.flush()                     #确保所有的日志输出已经被刷新
handler.close()                     #收拾任何所使用资源处理程序,
# handler.handle(record)            #有条件地发出指定的日志记录,这取决于过滤器可能被添加到处理程序。
# handler.handlerError(record)      #处理错误
# handler.format(record)            #格式输出
# handler.emit(record)
#Formatter:http://docs.python.org/2.7/library/logging.html#logging.Formatter
'''Formatter:
the base Formatter allows a formatter string to be specified,is none ,used default value '%(message)s'
class logging.Formatter(fmt=None,datefmt=None)
If no fmt is specified, '%(message)s' is used. If no datefmt is specified, the ISO8601 date format is used.
'''
fm = logging.Formatter('%(levelname)s:%(message)s','%m/%d/%Y %I:%M:%S %p')
print fm        #
#有如下方法:format()、formatTime()、formatException()
#http://docs.python.org/2.7/library/logging.html#formatter-objects
'''Filter'''
'''
class logging.Filter(name=''):
返回Filter实例,If name is specified, it names a logger which, together with its children,
will have its events allowed through the filter. If name is the empty string, allows every event.
用于Loggers、Handlers等过滤的设置
如果一个过滤器初始化为'A.B',则允许'A.B/A.B.C/A.B.C.D/A.B.D'等,但不允许'A.BB/B.A'等通过
如果初始化为空字符串,则没有过滤。
它有filter()方法
'''
'''LogRecord '''
'''class logging.LogRecord(name, level, pathname, lineno, msg, args, exc_info, func=None)
LogRecord 实例可以被Logger自动创建.也可以通过makeLogRecord()来创建'''
#http://docs.python.org/2.7/library/logging.html#logrecord-objects
  
  参考:http://docs.python.org/2.7/howto/logging.html#logging-basic-tutorial
  http://www.iyunv.com/dkblog/archive/2011/08/26/2155018.html
  http://blog.iyunv.com/jgood/article/details/4340740
  
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-60529-1-1.html 上篇帖子: Python天天美味(21) 下篇帖子: python开发_tkinter_获取文本框内容_给文本框添加键盘输入事件
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表