當咱們維護一個網站時,不管前臺仍是後臺,常常會出現各類個樣的問題。有時候問題很難直觀的發現,這個時候只能查看各類日誌來跟蹤問題。可是查看日誌有各類個樣的問題。首先,要用各類工具登錄到服務器,這個有時候很麻煩。登陸上去可能沒有合適的工具查看日誌,就算有,中文偶爾也會來個亂碼啥的。最鬱悶的是有的日誌文件很大,打開要等好久,看起來也不方便。html
基於上面的緣由,我用python的bottle模塊作了個web版的分頁日誌查看器,bottle怎麼安裝使用具體可看下面的指南:
http://bottlepy.org/docs/dev/tutorial.htmlpython
這裏沒有太多考慮安全因素,若是考慮安全最好加個簡單的登陸功能,或者直接對請求ip進行校驗。性能方面還須要優化,文件太大仍是有點慢。
下面是實現代碼,只有一個文件:
web
1 #coding=utf-8 2 ''' 3 日誌文件查看器 4 Created on 2013年8月20日 5 6 @author: alala 7 ''' 8 9 import os 10 import bottle 11 from bottle import route, run, template 12 13 #將自定義模板目錄添加到模板搜索路徑集合 14 templatesDir = os.getcwd() 15 bottle.TEMPLATE_PATH.insert(0,templatesDir) 16 17 #日誌根目錄 18 LOG_DIR = "/Tem/" 19 #每頁顯示日誌行數 20 PAGE_SIZE = 4000 21 22 #列出某個子目錄的全部日誌文件 23 @route('/') 24 @route('/<dirName>') 25 def listDir(dirName='logs'): 26 if dirName == 'favicon.ico': 27 return 0 28 #讀取目錄 29 files = os.listdir(LOG_DIR + dirName) 30 return template('logList', files=files,dirName=dirName) 31 32 #查看某個日誌文件 33 @route('/<dirName>/<logFile>') 34 @route('/<dirName>/<logFile>/<pageNo>') 35 def viewLog(dirName,logFile,pageNo=-1): 36 filePath = LOG_DIR + dirName + "/" + logFile; 37 pageNo = int(pageNo) 38 39 #獲取日誌行數 40 lineCount = 0 41 f = open(filePath, 'rb') 42 try: 43 while True: 44 buf = f.read(1024*1024) 45 if not buf: 46 break 47 lineCount += buf.count('\n') 48 finally: 49 f.close() 50 #計算頁數 51 pageCount = lineCount / PAGE_SIZE 52 if lineCount % PAGE_SIZE != 0: 53 pageCount += 1 54 #調整當前頁碼 55 print (pageNo, pageCount, pageNo >= pageCount) 56 if (pageNo < 0) or (pageNo >= pageCount) or (pageNo == -1): 57 pageNo = pageCount - 1 58 59 #讀取當頁日誌 60 lines = [] 61 f = open(filePath, 'r') 62 try: 63 maxNo = (pageNo + 1) * PAGE_SIZE 64 minNo = pageNo * PAGE_SIZE 65 lineNo = 0 66 for line in f: 67 if lineNo >= maxNo: 68 break 69 elif lineNo >= minNo: 70 lines.append(line) 71 lineNo += 1 72 finally: 73 f.close() 74 #使用模板構建顯示頁面 75 return template('logView', dirName = dirName, logFile = logFile, 76 pageNo = pageNo,lines = lines, pageCount = pageCount) 77 78 run(host='localhost', port=5200) 79 #paste提供多線程請求處理,性能比默認的好 80 #run(host='localhost', port=5200,server='paste')
下面是使用到的兩個模板:
安全
%for f in files: <a href="{{'/%s/%s' % (dirName, f)}}">{{f}}</a><br/> %end
%for i in range(0,pageCount): <a href="{{'/%s/%s/%s' % (dirName, logFile, i)}}" style="color:{{'red' if pageNo == i else 'black'}};">{{i}}</a> %end <br/> <br/> %for line in lines: {{line}}<br/> %end