RobotHardware-UESTC/Hardware/UPbot-Tools/pypibot/log.py

260 lines
8.6 KiB
Python
Raw Normal View History

2024-01-23 15:09:47 +08:00
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys,os
import datetime
import threading
import pypibot.assistant as assistant
import platform
if assistant.is_python3():
import _thread
else:
import thread
import traceback
"""
%a Locales abbreviated weekday name.
%A Locales full weekday name.
%b Locales abbreviated month name.
%B Locales full month name.
%c Locales appropriate date and time representation.
%d Day of the month as a decimal number [01,31].
%H Hour (24-hour clock) as a decimal number [00,23].
%I Hour (12-hour clock) as a decimal number [01,12].
%j Day of the year as a decimal number [001,366].
%m Month as a decimal number [01,12].
%M Minute as a decimal number [00,59].
%p Locales equivalent of either AM or PM. (1)
%S Second as a decimal number [00,61]. (2)
%U Week number of the year (Sunday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Sunday are considered to be in week 0. (3)
%w Weekday as a decimal number [0(Sunday),6].
%W Week number of the year (Monday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Monday are considered to be in week 0. (3)
%x Locales appropriate date representation.
%X Locales appropriate time representation.
%y Year without century as a decimal number [00,99].
%Y Year with century as a decimal number.
%Z Time zone name (no characters if no time zone exists).
%% A literal '%' character.
"""
isWindows=False
if platform.system()=='Windows':
isWindows=True
defaultEncodeing="utf8"
if "-utf8" in sys.argv:
defaultEncodeing="utf-8"
if "-gbk" in sys.argv:
defaultEncodeing="gbk"
TRACE=5
DEBUG=4
INFORMATION=3
WARNING=2
ERROR=1
NONE=0
MAX_MSG_SIZE = 4096
def getLevelFromString(level):
level=level.lower()
if level=='t' or level=='trace':return 5
elif level=='d' or level=='debug':return 4
elif level=='i' or level=='info':return 3
elif level=='w' or level=='wran':return 2
elif level=='e' or level=='error':return 1
else :return 0
def getLevelString(level):
if level==TRACE:return "T"
elif level==DEBUG:return "D"
elif level==INFORMATION:return "I"
elif level==WARNING:return "W"
elif level==ERROR:return "E"
else:return "N"
class PibotLog:
def __init__(self):
self.isEnableControlLog=True
self.fileTemple=None
self.filePath=""
self.level=5
self._lock=threading.RLock()
self.fd=None
self.fd_day=-1
def setLevel(self,level):
self.level=getLevelFromString(level)
def enableControllog(self,enable):
self.isEnableControlLog=enable
def enableFileLog(self,fileName):
self.fileTemple=fileName
self.updateFilelog()
def updateFilelog(self):
fn=assistant.SF(self.fileTemple)
if fn!=self.filePath:
self.i("new log file:%s",fn)
if self.fd:
self.fd.close()
self.fd=None
self.fd_day=-1
self.filePath=""
try:
path=os.path.dirname(fn)
if path!="" and not os.path.isdir(path):os.makedirs(path)
self.fd=open(fn,mode="w")
try:
linkfn = fn.split(".log.", 1)[0] + ".INFO"
if os.path.exists(linkfn):
os.remove(linkfn)
(filepath, tempfilename) = os.path.split(fn)
os.symlink(tempfilename, linkfn)
except:
pass
self.fd_day=datetime.datetime.now().day
self.filePath=fn
except Exception as e:
print("open file fail!file=%s,err=%s"%(fn,e))
def _output(self,level,msg,args):
if self.level<level:return
try:
if len(args)>0:
t=[]
for arg in args:
if isinstance(arg,Exception):
t.append(traceback.format_exc(arg).decode('utf-8'))
elif isinstance(arg,bytes) :
t.append(arg.decode('utf-8'))
else:
t.append(arg)
args=tuple(t)
try:
msg=msg%args
except:
try:
for arg in args:
msg=msg+str(arg)+" "
except Exception as e:
msg=msg+"==LOG ERROR==>%s"%(e)
if len(msg)>MAX_MSG_SIZE:msg=msg[0:MAX_MSG_SIZE]
now=datetime.datetime.now()
msg=msg+"\r\n"
if assistant.is_python3():
id = _thread.get_ident()
else:
id = thread.get_ident()
s="[%s] %04d-%02d-%02d %02d:%02d:%02d.%03d (0x%04X):%s"%(getLevelString(level),now.year,now.month,now.day,now.hour,now.minute,now.second,now.microsecond/1000,(id>>8)&0xffff,msg)
prefix=''
suffix=''
if not isWindows:
suffix='\033[0m'
if level==TRACE:
prefix='\033[0;37m'
elif level==DEBUG:
prefix='\033[1m'
elif level==INFORMATION:
prefix='\033[0;32m'
elif level==WARNING:
prefix='\033[0;33m'
elif level==ERROR:
prefix='\033[0;31m'
else:
pass
self._lock.acquire()
try:
if self.isEnableControlLog:
sys.stdout.write((prefix+s+suffix))
if self.fd:
if self.fd_day!=now.day:
self.updateFilelog()
if assistant.is_python3():
self.fd.write(s)
else:
self.fd.write(s.encode('utf-8'))
self.fd.flush()
finally:
self._lock.release()
except Exception as e:
if assistant.is_python3():
print(e)
else:
print("PibotLog._output crash!err=%s"%traceback.format_exc(e))
def trace(self,msg,*args):
self._output(TRACE,msg,args)
def t(self,msg,*args):
self._output(TRACE,msg,args)
def debug(self,msg,*args):
self._output(DEBUG, msg,args)
def d(self,msg,*args):
self._output(DEBUG, msg,args)
def info(self,msg,*args):
self._output(INFORMATION, msg,args)
def i(self,msg,*args):
self._output(INFORMATION, msg,args)
def warn(self,msg,*args):
self._output(WARNING, msg,args)
def w(self,msg,*args):
self._output(WARNING, msg,args)
def error(self,msg,*args):
self._output(ERROR, msg,args)
def e(self,msg,*args):
self._output(ERROR, msg,args)
def _log(self,level,msg,args):
self._output(level, msg,args)
def createNamedLog(self,name):
return NamedLog(name)
log=PibotLog()
class NamedLog:
def __init__(self,name=None):
global log
self.name=''
if name:
self.name='['+name+']'
self.log=log
def trace(self,msg,*args):
msg=self.name+msg
self.log._log(TRACE,msg,args)
def t(self,msg,*args):
msg=self.name+msg
self.log._log(TRACE,msg,args)
def debug(self,msg,*args):
msg=self.name+msg
self.log._log(DEBUG, msg,args)
def d(self,msg,*args):
msg=self.name+msg
self.log._log(DEBUG, msg,args)
def info(self,msg,*args):
msg=self.name+msg
self.log._log(INFORMATION, msg,args)
def i(self,msg,*args):
msg=self.name+msg
self.log._log(INFORMATION, msg,args)
def warn(self,msg,*args):
msg=self.name+msg
self.log._log(WARNING, msg,args)
def w(self,msg,*args):
msg=self.name+msg
self.log._log(WARNING, msg,args)
def error(self,msg,*args):
msg=self.name+msg
self.log._log(ERROR, msg,args)
def e(self,msg,*args):
msg=self.name+msg
self.log._log(ERROR, msg,args)
if __name__ == "__main__":
log.trace("1%s","hello")
log.debug("2%d",12)
try:
raise Exception("EXC")
except Exception as e:
log.info("3%s",e)
log.warn("1")
log.error("1")
#log.enableFileLog("$(scriptpath)test_$(Date8)_$(filenumber2).log")
log.trace("1")
log.debug("1")
log.info("1")
log.warn("1")
log.error("1")
log=NamedLog("test")
log.d("1")
log.i("1")
log.warn("1")
log.error("1=%d,%s",100,e)