一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - python日志記錄模塊實例及改進

python日志記錄模塊實例及改進

2020-09-21 10:42sxhlinux Python

許多應用程序中都會有日志模塊,用于記錄系統在運行過程中的一些關鍵信息,以便于對系統的運行狀況進行跟蹤。在python中,我們不需要第三方的日志組件,因為它已經為我們提供了簡單易用、且功能強大的日志模塊:logging。

python 打印對象的所有屬性值:

?
1
2
def prn_obj(obj):
  print '\n'.join(['%s:%s' % item for item in obj.__dict__.items()])

Python logger對象屬性(由上述函數獲取的)

?
1
2
3
4
5
6
7
8
9
name:get_data
parent:<logging.RootLogger instance at 0x1d8bd88>
handlers:[<logging.FileHandler instance at 0x21bcc68>]
level:10
disabled:1   #當前的logger是否有效,默認為0
manager:<logging.Manager instance at 0x1d8bea8>
propagate:0   #是否將本級日志
filters:[]

部分日志無法輸出

File:logger.conf

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
[formatters]
keys=default
 
[formatter_default]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
class=logging.Formatter
 
[handlers]
keys=console, error_file
 
[handler_console]
class=logging.StreamHandler
formatter=default
args=tuple()
 
[handler_error_file]
class=logging.FileHandler
level=INFO
formatter=default
args=("logger.log", "a")
 
[loggers]
keys=root
 
[logger_root]
level=DEBUG
formatter=default
handlers=console,error_file

File:logger.py

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#!/bin/env python
 
import logging
from logging.config import logging
 
class Test(object):
  """docstring for Test"""
  def __init__(self):
    logging.config.fileConfig("logger.conf")
    self.logger = logging.getLogger(__name__)
 
  def test_func(self):
    self.logger.error('test_func function')
 
class Worker(object):
  """docstring for Worker"""
  def __init__(self):
    logging.config.fileConfig("logger.conf")
    self.logger = logging.getLogger(__name__)
 
    data_logger = logging.getLogger('data')
    handler = logging.FileHandler('./data.log')
    fmt = logging.Formatter('%(asctime)s|%(message)s')
    handler.setFormatter(fmt)
    data_logger.addHandler(handler)
    data_logger.setLevel(logging.DEBUG)
    self.data_logger = data_logger
 
  def test_logger(self):
    self.data_logger.error("test_logger function")
    instance = Test()
    self.data_logger.error("test_logger output")
    instance.test_func()
 
 
def main():
  worker = Worker()
  worker.test_logger()
 
if __name__ == '__main__':
  main()

問題一:測試過程中,只能打印出test_logger function一條語句
問題二:明明只在data_logger中打印出語句,但是logger的日志中也出現了相關的日志。

問題一解決方案:

利用python -m pdb logger.py 語句對腳本進行調試發現,在執行instance = Test()語句后,通過print '\n'.join(['%s:%s' % item for item in self.data_logger.__dict__.items()])調試語句看到data_logger的disable屬性值由0變成了True,此時logger的對應屬性也發生了相同的變化。這種變化導致了logger對象停止記錄日志。參考python  logging模塊的相關手冊發現“The fileConfig() function takes a default parameter, disable_existing_loggers, which defaults to True for reasons of backward compatibility. This may or may not be what you want, since it will cause any loggers existing before the fileConfig() call to be disabled unless they (or an ancestor) are explicitly named in the configuration.” 的說明,即調用fileconfig()函數會將之前存在的所有logger禁用。在python 2.7版本該fileConfig()函數添加了一個參數,logging.config.fileConfig(fname, defaults=None, disable_existing_loggers=True),可以顯式的將disable_existing_loggers設置為FALSE來避免將原有的logger禁用。將上述代碼中的Test類中的logging.config.fileConfig函數改成logging.config.fileConfig("./logger.conf", disable_existing_loggers=0)就可以解決問題。 不過該代碼中由于位于同一程序內,可以直接用logging.getLogger(LOGGOR_NAME)函數引用同一個logger,不用再調用logging.config.fileConfig函數重新加載一遍了。

問題二解決方案:

logger對象有個屬性propagate,如果這個屬性為True,就會將要輸出的信息推送給該logger的所有上級logger,這些上級logger所對應的handlers就會把接收到的信息打印到關聯的日志中。logger.conf配置文件中配置了相關的root logger的屬性,這個root logger就是默認的logger日志。
 
修改后的如下:

File:logger.conf

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
[formatters]
keys=default, data
 
[formatter_default]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
class=logging.Formatter
 
[formatter_data]
format=%(asctime)s|%(message)s
class=logging.Formatter
 
[handlers]
keys=console, error_file, data_file
 
[handler_console]
class=logging.StreamHandler
formatter=default
args=tuple()
 
[handler_error_file]
class=logging.FileHandler
level=INFO
formatter=default
args=("logger.log", "a")
 
[handler_data_file]
class=logging.FileHandler
level=INFO
formatter=data
args=("data_new.log", "a")
 
[loggers]
keys=root, data
 
[logger_root]
level=DEBUG
handlers=console,error_file
 
[logger_data]
level=DEBUG
handlers=data_file
qualname=data
propagate=0

File:logger.py

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/bin/env python
 
import logging
from logging.config import logging
 
class Test(object):
  """docstring for Test"""
  def __init__(self):
    self.logger = logging.getLogger(__name__)
 
  def test_func(self):
    self.logger.error('test_func function')
 
class Worker(object):
  """docstring for Worker"""
  def __init__(self):
    logging.config.fileConfig("logger.conf")
    self.logger = logging.getLogger(__name__)
    self.data_logger = logging.getLogger('data')
 
  def test_logger(self):
    self.data_logger.error("test_logger function")
    instance = Test()
    self.data_logger.error("test_logger output")
    instance.test_func()
 
 
def main():
  worker = Worker()
  worker.test_logger()
 
if __name__ == '__main__':
  main()

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 深夜在线网址 | 深夜在线网址 | jm漫天堂破解版 | jk制服蕾丝超短裙流白浆 | 亚洲AV午夜福利精品香蕉麻豆 | 国产一区二区免费不卡在线播放 | 五花大绑esebdsm国产 | 韩国久播影院理论片不卡影院 | 毛片视频在线免费观看 | 鸥美三级 | 午夜影院免费入口 | 日韩欧美一区二区在线观看 | 无码精品AV久久久奶水 | 504神宫寺奈绪大战黑人 | 国产成人综合久久精品红 | 国产精品久久久久久影视 | 久久毛片基地 | 欧美图片小说 | 亚洲国产成人精品无码区5566 | 欧美老人与小伙子性生交 | 天天色视频 | 满城尽带黄金甲大胸片 | 国产日韩精品一区二区 | 成人免费公开视频 | 含羞草国产亚洲精品岁国产精品 | 国产精品林美惠子在线观看 | 国产视频自拍一区 | 丝瓜茄子绿巨人秋葵榴莲污 | 1377大但人文艺术包子铺 | 韩国美女豪爽一级毛片 | 国产免费资源 | www.毛片在线观看 | 偷偷狠狠的日日高清完整视频 | 我们中文在线观看免费完整版 | 免费一级毛片完整版在线看 | 久久精品无码人妻无码AV蜜臀 | 免费av在线看 | 天美传媒在线视频 | boobsmilking流奶水野战 | 欧美成人tv在线观看免费 | 动漫人物差差差动漫人物免费观看 |