- 论坛徽章:
- 11
|
回复 5# lzzfriend
看你提到文件可能会比较大,那么fd.readlines()就不太合适,它会把整个文件读入内存并生成list,这是爆内存的节奏。我这里有个内存占用相对可控的demo- #!/usr/bin/env python
- import os
- import sys
- def get_last_n_lines(logfile, n):
- blk_size_max = 4096
- n_lines = []
- with open(logfile, 'rb') as fp:
- fp.seek(0, os.SEEK_END)
- cur_pos = fp.tell()
- while cur_pos > 0 and len(n_lines) < n:
- blk_size = min(blk_size_max, cur_pos)
- fp.seek(cur_pos - blk_size, os.SEEK_SET)
- blk_data = fp.read(blk_size)
- assert len(blk_data) == blk_size
- lines = blk_data.split('\n')
- # adjust cur_pos
- if len(lines) > 1 and len(lines[0]) > 0:
- n_lines[0:0] = lines[1:]
- cur_pos -= (blk_size - len(lines[0]))
- else:
- n_lines[0:0] = lines
- cur_pos -= blk_size
- fp.seek(cur_pos, os.SEEK_SET)
- if len(n_lines) > 0 and len(n_lines[-1]) == 0:
- del n_lines[-1]
- return n_lines[-n:]
- def main():
- if len(sys.argv) != 3:
- sys.exit('usage: %s logfile n_lines' % sys.argv[0])
- for line in get_last_n_lines(sys.argv[1], int(sys.argv[2])):
- print line
- if __name__ == '__main__':
- main()
复制代码 注:
1. 不用读取整个文件,从文件尾部开始,以4KiB为一个Block向前迭代,直到取到指定的行数,这里假设你只关心后面若干行,内存占用不大。
2. 如果日志文件是动态增长的,而且写日志的程序和分析日志的程序没有做进程间同步,那么就要考虑一点解析日志的容错性,比如某次读取的最后一行是不完整的。合理的处理方式应该是每次最多读取最后两行,如果最后一行格式不对,应该取倒数第二行。
|
|