1. 程式人生 > >使用pyinotify實現加強版的linux tail -f 命令,並且對日誌類型的文本進行單獨優化著色顯示。

使用pyinotify實現加強版的linux tail -f 命令,並且對日誌類型的文本進行單獨優化著色顯示。

ear 文件 mon 而且 pri att lose linux monitor

tail -f命令不能自動切換切片文件,例如日誌是每100M生成一個新文件,tail -f不能自動的切換文件,必須關閉然後重新運行tail -f

此篇使用pyinotify,檢測文件更新,並實現tail -f以外,還能自動識別切換切片文件。而且針對日誌類型的文件做了單獨樣式優化。

運行 ./tailf.py + 文件路徑

此文件夠自動從普通文本中,對日誌就行著色處理,如果不是日誌類型的文件,將直接輸出,不進行著色處理。

技術分享圖片

tailf.py文件的實現代碼如下:

 
import os
import sys
import re
import pyinotify

DIRMASK 
= pyinotify.IN_MODIFY | pyinotify.IN_ATTRIB | pyinotify.IN_MOVE_SELF | pyinotify.IN_CREATE class Handler(pyinotify.ProcessEvent): def __init__(self, filename): self._fh = None self._path = filename super(Handler, self).__init__()
def my_init(self): try: self._fh = open(self._path, r) except IOError as e: sys.stderr.write(open file failed, %s % e) else: self._fh.seek(0, 2) def process_IN_CREATE(self, event): path = self._path if path in
os.path.join(event.path, event.name): if hasattr(self, fh): self._fh.close() try: self._fh = open(self._path, r) except IOError as e: sys.stderr.write(open file failed, %s % e) else: self._fh.seek(0, 2) for r in self._fh.readlines(): # sys.stdout.write(r) process_line(r) def process_IN_MODIFY(self, event): path = self._path if path not in os.path.join(event.path, event.name): return if not self._fh.closed: for r in self._fh.readlines(): # sys.stdout.write(r) process_line(r) def process_IN_MOVE_SELF(self, event): path = self._path if path in os.path.join(event.path, event.name): sys.stderr.write(monitor file move) def process_IN_ATTRIB(self, event): pass class Tailer(object): def __init__(self, filename): super(Tailer, self).__init__() self._path = filename self._notifier = None self._init() def __del__(self): self._notifier.stop() def _init(self): path = self._path index = path.rfind(/) wm = pyinotify.WatchManager() wm.add_watch(path[:index], DIRMASK) handler = Handler(path) self._notifier = pyinotify.Notifier(wm, handler) def run(self): self.read_last_10240_word() while True: self._notifier.process_events() if self._notifier.check_events(): self._notifier.read_events() def read_last_10240_word(self): with open(self._path,rb) as f: f.seek(-10240,2) for l in f.readlines(): # print(l.decode()) process_line(l.decode()) def process_line(line_str): pass #matcher = re.search(r‘\d{4}-\d{2}-\d{2}.*?- (DEBUG|INFO|WARNING|ERROR|CRITICAL) -[\s\S]*?(File ".*?.py", line \d*)‘, line_str) matcher = re.search(r\d{4}-\d{2}-\d{2}.*?- (DEBUG|INFO|WARNING|ERROR|CRITICAL), line_str) if not matcher: print(line_str) else: log_level_str = matcher.group(1) if log_level_str == DEBUG: print(\033[0;32m%s\033[0m % line_str) elif log_level_str == INFO: print(\033[0;96m%s\033[0m % line_str) elif log_level_str == WARNING: print(\033[0;33m%s\033[0m % line_str) elif log_level_str == ERROR: print(\033[0;35m%s\033[0m % line_str) elif log_level_str == CRITICAL: print(\033[0;31m%s\033[0m % line_str) if __name__ == __main__: if len(sys.argv[1:]) != 1: print(Usage: python tail.py </path/to/filename>) sys.exit(0) path = sys.argv[1] Tailer(path).run()

使用pyinotify實現加強版的linux tail -f 命令,並且對日誌類型的文本進行單獨優化著色顯示。