python logging 探究

python logging 探究

针对python的日志我们慢慢探究,建议有一定python基础再去探究,小白误入

import logging

root = logging.root
print (root is logging.Logger.root)
r = logging.getLogger()
print (r)

#从这我们发现logging 的日志都是从根出发

输出结果:
True
<RootLogger root (WARNING)>
进程已结束,退出代码0

探究python logging的父子关系 主要关系parnet

import logging

l1 = logging.getLogger('t1')
l2 = logging.getLogger('t2')
print (id(l1),id(l2),l1 is l2 )
l3 = logging.getLogger('t3')
print (id(l3))

print (l1.name,l2.name,l3.name)

root = logging.getLogger() #默认为root为根,层级递增
print (1,root.name,type(root),root.parent)
#从这发现parnet的parnet是root
parnet = logging.getLogger('a')
print (2,parnet.name,type(parnet),parnet.parent.name,parnet.parent is root )

#从这发现child的parnet是parnet
child = logging.getLogger('a.b')
print (3,child.name,type(child),child.parent.name,child.parent is parnet )

输出结果:
2349971106256 2349971308304 False
2349970911392
t1 t2 t3
1 root <class 'logging.RootLogger'> None
2 a <class 'logging.Logger'> root True
3 a.b <class 'logging.Logger'> a True

进程已结束,退出代码0


探究python logging的消息级别

import logging

#消息级别,
logging.basicConfig(level=logging.INFO,format="%(asctime)s %(name)s %(threadName)s [%(message)s]") #自定义消息类型,后续回把输出结果放出
logging.basicConfig(level=logging.INFO) #定义消息类型 
logging.basicConfig(filename="D:\syslog.txt",filemode='w') #定义输出到文件,并且为w
logging.info('info msg') #发送 info消息
logging.debug('debug msg') #发送 debug消息
logging.warning('warn msg' ) #发送 warn消息 

#可以按住ctrl在pycharm 中查看logging类中查看 

#消息级别一共有5种
#ERROR = 40
#WARNING = 30
#WARN = WARNING
#INFO = 20
#DEBUG = 10
#NOTSET = 0

输出结果:
2023-02-22 22:44:57,130 root MainThread [info msg]
2023-02-22 22:44:57,130 root MainThread [warn msg]

其实logging中工作的都是handler,所以我们在收集服务日志中直接定义handler

import logging

handler = logging.FileHandler('D:\syslog.txt','w','utf-8') #定义handler日志文件和日志格式以及权限w
handler.setFormatter(logging.WARNING)#定义handler的消息级别只有告警在这个级别之上才会发送
formatter = logging.Formatter('#%(asctime)s <%s(message)s>#') #定义消息类型,acstime是时间格式,,message 是日志消息
print (logging.root.handlers) #查看一下

输出结果:
1 []


那我们现在定义一个logging-handler,其实在抓取服务日志时可以根据条件判断进行输出不同的日志或者保存为不同的文件

import logging

#根log
logging.basicConfig(level=logging.INFO,format="%(asctime)s %(name)s %(threadName)s [%(message)s]")
print (logging.root.handlers)

mylogger = logging.getLogger(__name__) 
mylogger.info("my info ")

#定义处理器
handler = logging.FileHandler('D:\syslog.txt','w','utf-8')
handler.setLevel(logging.WARNING)
#定义格式化器
formatter = logging.Formatter('#%(asctime)s <%(message)s>#')
#为处理器定义格式化器
handler.setFormatter(formatter)

#为日志记录器追加处理器
mylogger.addHandler(handler)
mylogger.propagate = False
mylogger.info( 'my in fo 2 ~~~')
mylogger.warning('my warnning 2 ~~~')
mylogger.propagate = True
mylogger.warning('my warnning 3 ~~~')

输出结果:
2023-02-22 22:45:37,227 __main__ MainThread [my info ]
2023-02-22 22:45:37,227 __main__ MainThread [my warnning 3 ~~~]
[<StreamHandler <stderr> (NOTSET)>]

另一种写法,在logging中有现成的handlers库,TimedRotatingFileHandler

我们看一下输出结果


import  logging
from logging.handlers import TimedRotatingFileHandler
import  time


logging.basicConfig(level=logging.INFO,format='%(asctime)s %(name)s %(threadName)s [%(message)s]')  #定义logging的config
print (logging.root.handlers)

mylogger = logging.getLogger(__name__)

handle = TimedRotatingFileHandler('D:\syslog.txt','s',30) #定义handler的file格式
handle.setLevel(logging.INFO) #定义handler 级别 

formatter = logging.Formatter('#%(asctime)s <%(message)s>#') #定义handler 输出消息格式

handle.setFormatter(formatter)  #定义handler 级别 

mylogger.addHandler(handle)##定义handler的file格式

for i in range(20):
    time.sleep(1)
    mylogger.info("my message {:3} +++ ".format(i))


mylogger.addHandler(handle)

输出结果:
[<StreamHandler <stderr> (NOTSET)>]
2023-02-22 22:45:57,842 __main__ MainThread [my message   0 +++ ]
2023-02-22 22:45:58,852 __main__ MainThread [my message   1 +++ ]
2023-02-22 22:45:59,856 __main__ MainThread [my message   2 +++ ]
2023-02-22 22:46:00,859 __main__ MainThread [my message   3 +++ ]
2023-02-22 22:46:01,865 __main__ MainThread [my message   4 +++ ]
2023-02-22 22:46:02,877 __main__ MainThread [my message   5 +++ ]
2023-02-22 22:46:03,887 __main__ MainThread [my message   6 +++ ]
2023-02-22 22:46:04,896 __main__ MainThread [my message   7 +++ ]
2023-02-22 22:46:05,898 __main__ MainThread [my message   8 +++ ]
2023-02-22 22:46:06,902 __main__ MainThread [my message   9 +++ ]
2023-02-22 22:46:07,917 __main__ MainThread [my message  10 +++ ]
2023-02-22 22:46:08,924 __main__ MainThread [my message  11 +++ ]
2023-02-22 22:46:09,935 __main__ MainThread [my message  12 +++ ]
2023-02-22 22:46:10,942 __main__ MainThread [my message  13 +++ ]
2023-02-22 22:46:11,956 __main__ MainThread [my message  14 +++ ]
2023-02-22 22:46:12,966 __main__ MainThread [my message  15 +++ ]
2023-02-22 22:46:13,978 __main__ MainThread [my message  16 +++ ]
2023-02-22 22:46:14,993 __main__ MainThread [my message  17 +++ ]
2023-02-22 22:46:16,002 __main__ MainThread [my message  18 +++ ]
2023-02-22 22:46:17,009 __main__ MainThread [my message  19 +++ ]

进程已结束,退出代码0


这个是logging.Formatter类的解释,所以我们需要自己学习,学会看python源码 
   """
    Formatter instances are used to convert a LogRecord to text.

    Formatters need to know how a LogRecord is constructed. They are
    responsible for converting a LogRecord to (usually) a string which can
    be interpreted by either a human or an external system. The base Formatter
    allows a formatting string to be specified. If none is supplied, the
    style-dependent default value, "%(message)s", "{message}", or
    "${message}", is used.

    The Formatter can be initialized with a format string which makes use of
    knowledge of the LogRecord attributes - e.g. the default value mentioned
    above makes use of the fact that the user's message and arguments are pre-
    formatted into a LogRecord's message attribute. Currently, the useful
    attributes in a LogRecord are described by:

    %(name)s            Name of the logger (logging channel)
    %(levelno)s         Numeric logging level for the message (DEBUG, INFO,
                        WARNING, ERROR, CRITICAL)
    %(levelname)s       Text logging level for the message ("DEBUG", "INFO",
                        "WARNING", "ERROR", "CRITICAL")
    %(pathname)s        Full pathname of the source file where the logging
                        call was issued (if available)
    %(filename)s        Filename portion of pathname
    %(module)s          Module (name portion of filename)
    %(lineno)d          Source line number where the logging call was issued
                        (if available)
    %(funcName)s        Function name
    %(created)f         Time when the LogRecord was created (time.time()
                        return value)
    %(asctime)s         Textual time when the LogRecord was created
    %(msecs)d           Millisecond portion of the creation time
    %(relativeCreated)d Time in milliseconds when the LogRecord was created,
                        relative to the time the logging module was loaded
                        (typically at application startup time)
    %(thread)d          Thread ID (if available)
    %(threadName)s      Thread name (if available)
    %(process)d         Process ID (if available)
    %(message)s         The result of record.getMessage(), computed just as
                        the record is emitted
    """
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值