學習 Python
不久碰到過這個問題, 記得當時沒查出是什麼問題. 剛剛無意中發現了這個問題的原因及解決方案, 記錄一下.
第一種情況
參考文章中介紹說產生這個問題的原因是因爲創建了自定義的 Logger 對象後, 又使用了 logging
中的日誌輸出方法,這些方法使用的是默認配置的 Logger 對象,導致之後輸出的日誌信息會重複。
示例代碼:
import logging
# 日誌管理
logger = logging.getLogger('logger')
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
# 輸出到控制檯的log
sh = logging.StreamHandler()
sh.setLevel(logging.DEBUG)
sh.setFormatter(formatter)
logger.addHandler(sh)
logger.debug('a debug message')
logger.info('a info message')
logger.warning('a warning message')
logging.error('a error message')
logger.critical('a critical message')
打印結果如下:
2019-07-17 09:42:29,336 spider.py[line:92] DEBUG a debug message
2019-07-17 09:42:29,336 spider.py[line:93] INFO a info message
2019-07-17 09:42:29,336 spider.py[line:94] WARNING a warning message
ERROR:root:a error message
2019-07-17 09:42:29,336 spider.py[line:96] CRITICAL a critical message
CRITICAL:logger:a critical message
[Finished in 0.6s]
可以看到從 error message
開始出現格式異常, 之後下一條 message
開始重複打印. 之後每一條 log
都會打印出兩次. 去掉使用 logging
的日誌輸出方法後則打印正常.
第二種情況
封裝了 logger
到文件後在其他文件 import
引用這個 logger
. 卻又在文件中創建了新的 logger
. 如下:
封裝了 logger
的 base_utils
:
import configparser
import logging
import time
import os
# 配置文件管理
confLoad = configparser.ConfigParser()
confLoad.read('./spider.conf')
# 日誌管理
logger = logging.getLogger('logger')
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
# 輸出到log目錄下的當日log文件
log_dir = confLoad.get('logger','LOG_DIR')
if not os.path.exists(log_dir):
os.makedirs(log_dir)
logFile = log_dir + time.strftime("%Y-%m-%d", time.localtime()) + ".log"
fh = logging.FileHandler(logFile, encoding='utf-8')
fh.setLevel(int(confLoad.get('logger','LOGFILE_LEVEL')))
fh.setFormatter(formatter)
# 輸出到控制檯的log
sh = logging.StreamHandler()
sh.setLevel(int(confLoad.get('logger','CONSOLE_LEVEL')))
sh.setFormatter(formatter)
logger.addHandler(fh)
logger.addHandler(sh)
配置文件 spider.conf
:
# mongodb
[mongodb]
DB_MONGO_HOST=192.168.0.201
DB_MONGO_PORT=27017
DB_MONGO_DATABASE=foxsaas_spider
DB_MONGO_USERNAME=
DB_MONGO_PASSWORD=
[logger]
LOG_DIR = ./log/
# CRITICAL = 50
# FATAL = CRITICAL
# ERROR = 40
# WARNING = 30
# WARN = WARNING
# INFO = 20
# DEBUG = 10
# NOTSET = 0
CONSOLE_LEVEL = 10
LOGFILE_LEVEL = 10
在文件 spider.py
中引用:
from base_utils import logger
if __name__ == "__main__":
# 如果在此文件中再次創建 logger, 會產生兩個 logger 對象, 使 log 打印 2 次
logger = logging.getLogger('logger')
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
sh = logging.StreamHandler()
sh.setLevel(logging.DEBUG)
sh.setFormatter(formatter)
logger.addHandler(sh)
logger.debug('a debug message')
logger.info('a info message')
logger.warning('a warning message')
logger.error('a error message')
logger.critical('a critical message')
打印結果如下:
2019-07-17 10:01:21,969 spider.py[line:93] DEBUG a debug message
2019-07-17 10:01:21,969 spider.py[line:93] DEBUG a debug message
2019-07-17 10:01:21,970 spider.py[line:94] INFO a info message
2019-07-17 10:01:21,970 spider.py[line:94] INFO a info message
2019-07-17 10:01:21,970 spider.py[line:95] WARNING a warning message
2019-07-17 10:01:21,970 spider.py[line:95] WARNING a warning message
2019-07-17 10:01:21,971 spider.py[line:96] ERROR a error message
2019-07-17 10:01:21,971 spider.py[line:96] ERROR a error message
2019-07-17 10:01:21,971 spider.py[line:97] CRITICAL a critical message
2019-07-17 10:01:21,971 spider.py[line:97] CRITICAL a critical message
[Finished in 0.6s]
可以看到 log
打印了 2 次, 同樣的要避免這樣子使用.