#!/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 Locale’s abbreviated weekday name. %A Locale’s full weekday name. %b Locale’s abbreviated month name. %B Locale’s full month name. %c Locale’s 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 Locale’s 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 Locale’s appropriate date representation. %X Locale’s 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.level0: 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)