python实现tailf
1 # -*- coding:utf-8 -*- 2 ''' 3 Created on 2016年10月28日 4 5 @author: zhangsongbin 6 ''' 7 8 import time 9 class file_read: 10 def __init__(self,logfilename): 11 self._logfilename=logfilename 12 13 def file_readlines(self,line): 14 print line 15 16 # def file_readline(self): 17 def file_readline(self): 18 f=open(self._logfilename,'r') 19 f.seek(0,2) #直接到文件结尾 20 while True: 21 offset=f.tell()#得到现在的偏移量 22 line=f.readline()#得到现在偏移量后面一行的内容,这里如果下一行是空的话,偏移量不会变大;如不是空,偏移量会变大。 23 if not line: 24 f.seek(offset)#设置新的偏移量 25 time.sleep(20) 26 else: 27 self.file_readlines(line) 28 29 30 f.close() 31 32 if __name__ == '__main__': 33 a=file_read('./trace_order.log') 34 a.file_readline()
一个简单的tailf程序,这个程序后续可以拿来做日志分析,目前还有个缺点就是,这个文件如果被删除了,即使新建一个一样的名字的问题,也得把程序再跑一边,后续会优化。
优化版本如下:
1 # -*- coding:utf-8 -*- 2 ''' 3 Created on 2016年10月28日 4 5 @author: zhangsongbin 6 ''' 7 import os.path 8 import time 9 class test(object): 10 pass 11 class file_read: 12 def __init__(self,logfilename): 13 self._logfilename=logfilename 14 def get_time(self,_logfilename):#得到ctime的方法,里面做了些判断 15 if os.path.exists(_logfilename): 16 return time.ctime(os.path.getctime(_logfilename)) 17 else: 18 print str(self._logfilename)+'is not exist,after 1s system will check again' 19 time.sleep(1) 20 self.get_time(_logfilename) 21 def file_readlines(self,line): 22 print line 23 24 def file_readline(self): 25 if os.path.exists(self._logfilename):#检测文件是否存在 26 f=open(self._logfilename,'r') 27 else: 28 print str(self._logfilename)+'is not exist,after 1s system will check again' 29 time.sleep(1) 30 self.file_readline()#重新调用自己这个方法,再次检测文件 31 32 f.seek(0,2) #到文件结尾 33 #before_ctime=time.ctime(os.path.getctime(self._logfilename)) #得到文件的目前的状态时间 34 before_ctime=self.get_time(self._logfilename) 35 while True: 36 offset=f.tell()#得到现在的偏移量 37 line=f.readline()#得到现在偏移量后面一行的内容,这里如果下一行是空的话,偏移量不会变大;如不是空,偏移量会变大。 38 if not line: 39 #after_ctime=time.ctime(os.path.getctime(self._logfilename)) #得到文件当line是空值的状态时间 40 after_ctime=self.get_time(self._logfilename) 41 after_offset=f.tell() #得到当line为空的offset 42 if offset == after_offset and before_ctime != after_ctime and os.path.exists(self._logfilename): #当文件状态时间不一致时,而offset又每次都一样就表示之前的log文件被删除了,我们要重新打开一次log文件 43 f.close() 44 f=open(self._logfilename,'r') 45 line=f.readline() #log的第一行 46 self.file_readlines(line) #打印第一行,然后跳过本次循环到while true 47 before_ctime=self.get_time(self._logfilename) #从新去得到before_ctime 48 continue 49 time.sleep(0.1)#这个sleep比较重要,如果log文件生成的速度很快,time值就小点,如果生成时间长就写大点。 50 else: 51 self.file_readlines(line) 52 #before_ctime=time.ctime(os.path.getctime(self._logfilename)) #当line不为空表示log正常在读出来了,重新获取一次log的状态时间 53 before_ctime=self.get_time(self._logfilename) 54 55 56 f.close() 57 58 if __name__ == '__main__': 59 a=file_read('./echo_log.log') 60 a.file_readline()
模拟日志生成的shell脚本:
1 #!/bin/sh 2 n=0 3 while true; 4 do 5 echo $(date +%Y-%m-%d\;%H:%M:%S) >> echo_log.log 6 echo $(date +%Y-%m-%d\;%H:%M:%S) 7 let n=$n+1 8 sleep 0.5 9 if (( $n == 15 ));then 10 rm -rf echo_log.log 11 n=0 12 fi 13 done
大家可以测试下,先开shell脚本生成日志,再用优化过后的Python程序读出日志。