python記錄日志
配置logger文件,記錄日志
-
首先導(dǎo)入依賴包
import logging #日志 import time # 時間 import os # 路徑
-
創(chuàng)建一個logger
logger = logging.getLogger() #獲取logger logger.setLevel(logging.DEBUG) # 設(shè)置記錄等級時debug
-
創(chuàng)建日志文件
rq = time.strftime('%Y-%m-%d-%H', time.localtime(time.time())) #以小時分割記錄日志 log_path = os.getcwd() + '/../Logs/all/' #設(shè)置日志路徑 log_name = log_path + rq + '_all.log' #設(shè)置日志名稱 logfile = log_name if not os.path.exists(log_path): # 創(chuàng)建路徑 os.makedirs(log_path) for root, dirs, files in os.walk(os.path.dirname(log_path)): # 刪除空文件 for i in files: fpath = os.path.join(root, i) if os.path.getsize(fpath) == 0: os.remove(fpath) if not os.path.exists(logfile): # 創(chuàng)建文件 f = open(logfile, mode='w', encoding="utf-8") f.close() fh_all = logging.FileHandler(logfile, mode='a', encoding='utf-8') # 輸出到文件 fh_all.setLevel(logging.DEBUG) # 以上是所有日志吞杭,其他分類日志同上 ch = logging.StreamHandler() ch.setLevel(logging.WARNING) # 控制臺輸出的日志級別
-
定義輸出格式
formatter = logging.Formatter( "%(asctime)s - %(filename)s[line:%(lineno)d](%(funcName)s) - %(levelname)s: %(message)s") fh_debug.setFormatter(formatter) # 添加格式 logger.addHandler(fh_debug) # 保存 ch.setFormatter(formatter) logger.addHandler(ch)
完整代碼
import logging
import os
import time
logger = logging.getLogger()
logger.setLevel(logging.DEBUG) # Log等級總開關(guān)
# 第二步盏浇,創(chuàng)建一個 file handler,用于寫入日志文件
def log(func):
@functools.wraps(func)
def wrapper(*args, **kw):
dicc = {}
dinp = {}
varnames = func.__code__.co_varnames
deft = func.__defaults__
if deft is None:
deft = ()
for i in range(len(args)):
dinp[varnames[i]] = str(args[i])
for j in range(len(deft)):
dinp[varnames[i + j + 1]] = str(deft[j])
for i, j in kw.items():
dinp[i] = str(j)
# print(str(func.__name__))
filter = ContextFilter(
os.path.basename(str(func.__code__.co_filename)), int(func.__code__.co_firstlineno), str(func.__name__))
try:
aa = func(*args, **kw)
except Exception as e:
aa = 'err:' + str(e)
if aa is None:
dretrun = ''
elif isinstance(aa, str):
dretrun = aa
elif isinstance(aa, tuple):
dretrun = list(aa)
else:
dretrun = str(aa)
# dicc['run_info'] = dinfo
dicc['run_input'] = dinp
dicc['run_return'] = dretrun
logger.addFilter(filter)
logger.debug(dicc)
logger.error(func.__name__ + '運行錯誤:', exc_info=True)
logger.removeFilter(filter)
raise e
if aa is None:
dretrun = ''
elif isinstance(aa, str):
dretrun = aa
elif isinstance(aa, tuple):
dretrun = list(aa)
else:
dretrun = str(aa)
# dicc['run_info'] = dinfo
dicc['run_input'] = dinp
dicc['run_return'] = dretrun
logger.addFilter(filter)
logger.debug(dicc)
logger.removeFilter(filter)
return aa
return wrapper
-
使用logger記錄日志
logger.error('err', exc_info=True) #exc_info 記錄錯誤信息
使用@log裝飾器記錄log
-
導(dǎo)入依賴包
import functools
-
完整代碼
def log(func): @functools.wraps(func) def wrapper(*args, **kw): dicc = {} dinp = {} varnames = func.__code__.co_varnames deft = func.__defaults__ if deft is None: deft = () for i in range(len(args)): dinp[varnames[i]] = str(args[i]) for j in range(len(deft)): dinp[varnames[i + j + 1]] = str(deft[j]) for i, j in kw.items(): dinp[i] = str(j) # print(str(func.__name__)) filter = ContextFilter( os.path.basename(str(func.__code__.co_filename)), int(func.__code__.co_firstlineno), str(func.__name__)) try: aa = func(*args, **kw) except Exception as e: aa = 'err:' + str(e) if aa is None: dretrun = '' elif isinstance(aa, str): dretrun = aa elif isinstance(aa, tuple): dretrun = list(aa) else: dretrun = str(aa) # dicc['run_info'] = dinfo dicc['run_input'] = dinp dicc['run_return'] = dretrun logger.addFilter(filter) logger.debug(dicc) logger.error(func.__name__ + '運行錯誤:', exc_info=True) logger.removeFilter(filter) raise e if aa is None: dretrun = '' elif isinstance(aa, str): dretrun = aa elif isinstance(aa, tuple): dretrun = list(aa) else: dretrun = str(aa) # dicc['run_info'] = dinfo dicc['run_input'] = dinp dicc['run_return'] = dretrun logger.addFilter(filter) logger.debug(dicc) logger.removeFilter(filter) return aa return wrapper
-
發(fā)現(xiàn)輸出文件格式不是喜歡的類型只是記錄芽狗,修改绢掰,在最上方添加方法
class ContextFilter(logging.Filter): # filename = 'IP' # lineno = 'USER' def __init__(self, filename, lineno, funcname): self.filename = filename self.lineno = lineno self.funcname = funcname def filter(self, record): record.filename = self.filename record.lineno = self.lineno record.funcName = self.funcname return True