diff --git a/direct/src/directnotify/RotatingLog.py b/direct/src/directnotify/RotatingLog.py new file mode 100755 index 0000000000..48b23f2623 --- /dev/null +++ b/direct/src/directnotify/RotatingLog.py @@ -0,0 +1,84 @@ + + +import os +import time + + +class RotatingLog: + """ + A file() (or open()) replacement that will automatically open and write + to a new file if the prior file is too large or after a time interval. + """ + + def __init__(self, path="./log_file", timeInterval=24, megabyteLimit=1024): + """ + path is a full or partial path with file name. + timeInterval is the number of hours at which to rotate the file. + megabyteLimit is the number of megabytes of file size the log + may grow to, afterwhich the log is rotated. + """ + self.path=path + self.timeInterval=None + self.timeLimit=None + self.sizeLimit=None + if timeInterval is not None: + self.timeInterval=timeInterval*60*60 + self.timeLimit=time.time()+self.timeInterval + if megabyteLimit is not None: + self.sizeLimit=megabyteLimit*1024*1024 + + def shouldRotate(self): + """ + Returns a bool about whether a new log file should + be created and written to (while at the same time + stopping output to the old log file and closing it). + """ + if not hasattr(self, "file"): + return 1 + if self.timeLimit is not None and time.time() > self.timeLimit: + return 1 + if self.sizeLimit is not None and self.file.tell() > self.sizeLimit: + return 1 + return 0 + + def filePath(self): + dateString=time.strftime("%Y_%m_%d_%H", time.localtime()) + for i in range(26): + path="%s_%s_%s.txt"%(self.path, dateString, chr(i+97)) + if not os.path.exists(path) or os.stat(path)[6] < self.sizeLimit: + return path + # Hmm, 26 files are full? throw the rest in z: + # Maybe we should clear the self.sizeLimit here... maybe. + return path + + def rotate(self): + """ + Rotate the log now. You normally shouldn't need to call this. + See write(). + """ + path=self.filePath() + file=open(path, "a") + if file: + if hasattr(self, "file"): + self.file.flush() + self.file.close() + del self.file + self.file=file + if self.timeLimit is not None and time.time() > self.timeLimit: + self.timeLimit=time.time()+self.timeInterval + else: + # I guess we keep writing to the old file. + print "unable to open new log file \"%s\""%(path,) + + def write(self, data): + """ + Write the data to either the current log or a new one, + depending on the return of shouldRotate() and whether + the new file can be opened. + """ + if self.shouldRotate(): + self.rotate() + if hasattr(self, "file"): + self.file.write(data) + self.file.flush() +