logging 模块的简单使用:

配置输出日志到文件

导入模块
import logging,os
FILE = os.getcwd()
设置文件路径,默认是追加到文件中,不过可以设置filemode="w",为重写进去。
logging.basicConfig(filename=os.path.join(FILE,"dosubprocess.log"),filemode="w",
                    format="%(levelname)s:%(message)s",level=logging.INFO)
                    
                    
                    

可以在外面设置级别

import logging
logging.basicConfig(level="laowang")
#必须调用getLOgger获得一个loggging对象后,才可以为他设置级别。
log=logging.getLogger(__name__)
#logging的属性,propagate,意思是是否消息是否层层上传。
print(log.propagate)
#设置logging对象的级别
log.setLevel(logging.WARN)

logging创建流handler,将信息显示到控制台,

import logging,os
logging.basicConfig(filename=os.path.join(os.getcwd(),"my_property.log"),
                    format="%(levelname)-10s %(asctime)-20s %(message)s",
                    datefmt="%m/%d/%Y %I:%M:%S",
                    level=logging.DEBUG,
                    filemode="w")
​
console=logging.StreamHandler()
console.setLevel(logging.INFO)
formatter=logging.Formatter("%(levelname)-10s %(asctime)-20s %(message)s")
console.setFormatter(formatter)
logging.getLogger("").addHandler(console)
'''
快速入门
基础知识
日志的作用是跟踪,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或之上时才被跟踪。
有两种方式记录跟踪,一种输出控制台,另一种是记录到文件中,如日志文件。
​
日志一共分成5个等级,从低到高分别是:DEBUG INFO WARNING ERROR CRITICAL。这5个等级,也分别对应5种打日志的方法: debug 、info 、warning 、error 、critical。
默认的是WARNING,当在WARNING或之上时才被跟踪。
有两种方式记录跟踪,一种输出控制台,另一种是记录到文件中,如日志文件
​
'''
​
'''
简单日志操作
写入一个文件里面:
'''
#logging to file
# import os
# import logging
#
# # with open("log.txt","w",encoding="utf-8") as f:
# #     f.write("")
#
# FILE =os.getcwd()
# logging.basicConfig(filename=os.path.join(FILE,"log.txt"),level=logging.DEBUG)
# logging.debug("写进去")
# logging.info("滚进去")
# logging.warning("也滚进去")
'''
来学习一些日志组件以及一些高级部分。
日志组件包括: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:设置显示格式
​
'''
'''
ogging.basicConfig ( [ * * kwargs ] )
该语句是日志模块配置基本信息。kwargs 支持如下几个关键字参数:
​
filename :日志文件的保存路径。如果配置了些参数,将自动创建一个FileHandler作为Handler;
​
filemode :日志文件的打开模式。 默认值为’a’,表示日志消息以追加的形式添加到日志文件中。如果设为’w’, 那么每次程序启动的时候都会创建一个新的日志文件;
​
format :设置日志输出格式;
​
datefmt :定义日期格式;
​
level :设置日志的级别.对低于该级别的日志消息将被忽略;
​
stream :设置特定的流用于初始化StreamHandler。
​
'''
'''
logging.getLogger ( [ name ] )
创建Logger对象。日志记录的工作主要由Logger对象来完成。
​
在调用getLogger时要提供Logger的名称(注:多次使用相同名称 来调用getLogger,
返回的是同一个对象的引用。),Logger实例之间有层次关系,这些关系通过Logger名称来体现,如
'''
# import logging
​
'''命名'''
# log2=logging.getLogger("BeginMan") #生成一个日志对象
# print(log2)#<logging.Logger object at 0x00000000026D1710>
'''无名'''
# log3=logging.getLogger()
# print(log3)
​
'''最好的方式'''
# log = logging.getLogger(__name__)#_name__ is the module’s name in the Python package namespace.
# print(log)
# print(__name__)
'''
Logger对象,
有如下属性和方法:
Logger.propagate
​
具体参考:http://docs.python.org/2.7/library/logging.html 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)
#
# log.setLevel(logging.WARN) #日志记录级别为WARNNING
# log.info("msg")
# log.debug("msg")
# log.warning("msg")
# log.error("msg")
#
'''
Handler对象、Formatter对象、Filter对象、Filter对象
​
'''
​
# import logging
# import os
# '''logger'''
# l=logging.Logger("root")  #创建logger对象
# log=logging.getLogger("root")  #通过logging.getlogger创建对象
#
# print(l)
# print(log)
#
# '''Handler'''
# handler=logging.Handler() #创建Handler对象
# handler.__init__(logging.DEBUG)  #通过设置levell劳初始刷handler实例
# handler.createLock()#初始化一个县城索,可以用来序列化,访问底层i/ogongneng,这可鞥不是县城安全的
# handler.acquire() #获取线程锁,通过handler.createLock()
# handler.release() #释放获得的县城索
# handler.setLevel(logging.DEBUG) #设置临界值,如果logging信息级别小于他的责被忽视
# handler.setFormatter("%(levelname)s,%(message)s") #设置格式
# handler.addFilter(filter)#
'''
3.将日志同时输出到文件和屏幕
'''
# import logging
# 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="myapp.log",
#                     filemode="w")
# 定义一个StreamHandler,将INFO级别或更高的日志信息打印到标准错误,
# 并将其添加到当前的日志处理对象
# console=logging.StreamHandler()
# console.setLevel(logging.INFO)
# formatter=logging.Formatter("%(name)-12s:%(levelname)-8s %(message)s")
# console.setFormatter(formatter)
# logging.getLogger("").addHandler(console)
#
# logging.debug("This is debug message")
# logging.info("This is info message ")
# logging.warning("Thsi is warning message")
​
​
# level: 设置日志级别,默认为logging.WARNING
# stream: 指定将日志的输出流,
# 可以指定输出到sys.stderr,sys.stdout或者文件,默认输出到sys.stderr,
# 当stream和filename同时指定时,stream被忽略
​
'''
. 每一个Logger实例的level如同入口,让水流进来,如果这个门槛太高,信息就进不来。例如log2.info('log3 info'),如果log2定义的级别高于info级别,就不会又信息通过log2
​
2. 如果level没有设置,就用父logger的,如果父logger的level也没有设置,继续找父的父的,最终找到root上,如果root设置了就用它的,如果root没有设置,root的默认值是WARNING
​
3.消息传递流程:
​
在某个logger上产生某种级别的信息,首先和logger的level检查,如果消息level低于logger的EffectiveLevl有效级别,消息丢弃,不会再向父logger传递该消息。如果通过(大于等于)检查后,则把消息交给logger所有的handler处理,每一个handler需要和自己level比较来决定是否处理。
​
 
​
如果没有一个handler,或者消息已经被handler处理过了,则需要通过本logger的propagate属性是否为True,Ture则把这个消息会继续发给父Logger,当前Logger的父Logger称为当前Logger,新的Logger的所有Handler继续处理消息。
​
4. logger实例初始的propagate属性为True,即允许想父logger传递消息
​
5. logger.basicConfig
​
如果root没有handler,就默认创建一个StreamHandler,如果设置了filename,就创建一个FileHandler。如果设置了format参数,就会用它生成一个formatter对象,并把这个formatter加入到刚才创建的handler上,然后把这些handler加入到root.handlers列表上。level 是设置给root.logger的。
​
如果root.handlers列表不为空,logging.basicConfig的调用什么都不做。
​
​
​
标准库里面的logging模块,在前面学习线程安全时曾用来解决print被打断的问题,这里会介绍logging模块的功能。
​
logging模块是线程安全的,不需要客户做任何特殊的工作。它通过使用线程锁实现了这一点; 有一个锁来序列化访问模块的共享数据,
每个处理程序还创建一个锁来序列化访问其底层 I/O。
​
​
使用工厂方法返回一个Logger实例。
​
logging.getLogger([name=None])
​
 指定name,返回一个名称为name的Logger实例。如果再次使用相同的名字,是实例化一个对象。未指定name,返回Logger实例,名称是root,即根Logger。
​
Logger是层次结构的,使用 '.' 点号分割,如'a'、'a.b'或'a.b.c.d','a'是'a.b'的父parent,a.b是a的子child。对于foo来说,名字为foo.bar、foo.bar.baz、foo.bam都是foo的后代。
​
'''
​
# import logging
# DATEFMT="[%Y-%m-%d %H:%M:%s]"
# FORMAT="%(asctime)s %(thread)d %(message)s"
# logging.basicConfig(level=logging.INFO,format=FORMAT,datefmt=DATEFMT,filename="log.txt")
#
# root=logging.getLogger()
# print(root.name,type(root),root.parent,id(root))
#
# logger=logging.getLogger(__name__)
# print(logger.name,type(logger),id(logger),id(logger.parent))
#
# logger1=logging.getLogger(__name__+".ok")
# print(logger1.name,type(logger1),id(logger1),id((logger1.parent)))
#
# print(logger1.parent,id(logger.parent))
'''
子child的级别设置,不影响父parent的级别:
'''
# import logging
#
# FORMAT="%(asctime)s %(thread)d %(message)s"
# logging.basicConfig(level=logging.WARNING,format=FORMAT,datefmt="[%Y-%m-%d %H:%M:%S]")
#
# root=logging.getLogger()
# print(1,root,id(root))
# root.info("my root")
#
# loga=logging.getLogger(__name__)
# print(2,id(loga),id(loga.parent))
# print(3,loga.getEffectiveLevel())
#
# loga.warning("before")
# loga.setLevel(28)
# print(4,loga.getEffectiveLevel)
# loga.info("after")
# loga.warning("after")
'''
Handler
​
  StreamHandler #不指定使用sys.strerr
​
    FileHandler #文件
​
    _StderrHandler #标准输出
​
  NullHandler #什么都不做
​
logger实例,如果设置了level,就用它和信息的级别比较,否则,继承最近的祖先的level。
​
'''
​
# import logging
# FORMAT ="%(asctime)s %(thread)d %(message)s"
# logging.basicConfig(level=logging.INFO,format=FORMAT,datefmt="[%Y-%m-%d %H:%M:%S]")
#
# root=logging.getLogger()
# print("root",root.getEffectiveLevel())
#
# log1=logging.getLogger("s")
# log1.setLevel(logging.ERROR)
# print("log1:",log1.getEffectiveLevel())
# log1.error("log1 error")
#
# log2=logging.getLogger("s.s1")
# log2.setLevel(logging.WARNING)
# print("log2",log2.getEffectiveLevel())
# log2.warning("log2 warning")
#
#
​
'''
Handler:
​
Handler控制日志信息的输出目的地,可以是控制台、文件。
​
可以单独设置level
​
可以单独设置格式
​
可以设置过滤器
​
 
​
Handler
​
  StreamHandler #不指定使用sys.strerr
​
    FileHandler #文件
​
    _StderrHandler #标准输出
​
  NullHandler #什么都不做
​
'''
# import logging
#
# FORMAT ="%(asctime)s %(thread)d %(message)s"
# logging.basicConfig(level=logging.INFO,format=FORMAT,datefmt="[%Y-%m-%d %H:%M:%S]")
#
# root=logging.getLogger()
# print("root:",root.getEffectiveLevel())
#
# log1=logging.getLogger("s")
# log1.setLevel(logging.ERROR)
# print("log1:",log1.getEffectiveLevel())
# log1.error("log1.error")
#
# log2=logging.getLogger("s.s1")
# log2.setLevel(logging.WARNING)
# print("log2:",log2.getEffectiveLevel())
# log2.warning("log2.warning")
​
'''
loggerLevel --> FilterConditions --> HandlerLevel --> 
父LoggerFilter --> 父LoggerHandler --> RootHandler --> 标准输出或记录到日志:
​
​
'''
​
import logging,datetime
​
FORMAT="%(asctime)s %(thread)s %(message)s"
logging.basicConfig(level=logging.WARNING,format=FORMAT,datefmt="[%Y-%m-%d %H:%M:%S]")
​
"--------------root----------------------"
root=logging.getLogger()
print(1,root.getEffectiveLevel())
"---------------------log1---------------------"
log1=logging.getLogger("s")
log1.setLevel(logging.ERROR)
print(2,log1.getEffectiveLevel())
​
h1=logging.FileHandler("h1.log")
h1.setLevel(logging.INFO)
log1.addHandler(h1)
​
"----------------log2-----------"
log2=logging.getLogger("s.s2")
log2.setLevel(logging.WARNING)
print(3,log2.getEffectiveLevel())
​
h2=logging.FileHandler("h2.log")
h2.setLevel(logging.WARNING)
f2=logging.Filter("s.s3")
h2.addFilter(f2)
log2.addHandler(h2)
​
log2.warning("4,log2 warning---{}".format(datetime.datetime.now()))
如果要实现多个模块用一个定义好的logging模式,可以定义一个模板,
然后各个模块在导入的时候,调用一下,就好啦。
文件一  log1
import logging
from string import Template
​
def lo():
    logging.info("log1--------------")
    logging.warning("name:%s msg:%s","BeginMan","Hi")
    logging.warning("name:%s msg:%s"%("BeginMan","Hi"))
    logging.warning("name:{0} mag:{1}".format("b而过inMan","HI"))
    msg=Template("name:$who msg:$what")
    logging.warning(msg.substitute(who="BeginMan",what="Hi"))
    
文件log2    
import logging
import os
FIFE  =os.getcwd()
import log1
​
​
def main():
    logging.basicConfig(filename=os.path.join(FIFE,"log1.txt"),level=logging.INFO)
    logging.info("start-------------")
    log1.lo()
    logging.info("end---------")
if __name__=="__main__":
    main()
​
​

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值