python 日誌收集伺服器,python日誌收集
引因: python 的日誌收集服務是安全執行緒的(對同一個檔案的寫入,使用了鎖),但是對於多進程的情況,它是無法處理的。python 官方文檔推薦的做法是,使用tcp 伺服器專門用於日誌的收集,以確保對的檔案的寫入是安全的。這裡提供了日誌收集伺服器基於twisted的實現,可供參考,程式在centos上進行了測試,並可用於生產環境
當client 和server 在一台機器上時,每秒可以處理6000條日誌記錄
#!/usr/bin/env python# -*- coding:utf-8 -*-################################### logserver# 通過socket接收並儲存日誌資訊# 注:測試程式為test_logserver.py# 修改時間:2013-11-22#################################### standard libimport os, sysimport timeimport twistedimport loggingimport tracebackimport structimport cPickle # use cPickle for speedfrom logging.handlers import TimedRotatingFileHandlerfrom twisted.internet.protocol import Protocol, Factory# our own codeimport settingsfrom log_record import initlog# 根據logger name產生一個def gen_log_name(name): name = name.replace('.', '_') return name + '.log'class ReceiveProtocol(Protocol): HEADER_LENGTH = 4 def __init__(self): self.buf = '' self.state = 'init' self.require_length = ReceiveProtocol.HEADER_LENGTH # 記錄當前完成初始化的logger名稱 self.logger_dict = {} def connectionMade(self): logger = logging.getLogger('log_server') logger.info('[makeConnection]與logger_client建立socket串連。') def dataReceived(self, data): logger = logging.getLogger('log_server') try: if len(self.buf + data) >= self.require_length: self.buf = self.buf + data # 資料就緒進行相應動作 data = self.buf[0:self.require_length] # 把資料從緩衝區中取走 self.buf = self.buf[self.require_length:] self.solve(data) # 可能一次讀到了多條日誌記錄 if self.buf: self.dataReceived('') else: self.buf += data except BaseException, e: logger.error('處理簡訊記錄失敗' + str(e) + '\n' + traceback.format_exc()) def solve(self, data): logger = logging.getLogger('log_server') statehandler = None try: pto = 'proto_' + self.state statehandler = getattr(self,pto) except AttributeError: logger.error('callback',self.state,'not found') self.transport.loseConnection() statehandler(data) if self.state == 'done': self.transport.loseConnection() def connectionLost(self, reason): logger = logging.getLogger('log_server') logger.info('[connectionLost]與logger_client的socket串連關閉。') # 記錄日誌 def proto_record(self, data): logRecord = logging.makeLogRecord(cPickle.loads(data)) if logRecord.name not in self.logger_dict: logger = initlog(logRecord.name, settings.PATH, gen_log_name(logRecord.name), logLevel=logging.DEBUG) self.logger_dict[logRecord.name] = logger self.logger_dict[logRecord.name].handle(logRecord) # 修改下一步動作以及所需長度 self.state = 'init' self.require_length = ReceiveProtocol.HEADER_LENGTH # 處理頭部資訊 def proto_init(self, data): length = struct.unpack('!I', data[0:ReceiveProtocol.HEADER_LENGTH])[0] # 修改下一步動作以及所需長度 self.state = 'record' self.require_length = length if len(self.buf) >= self.require_length: data = self.buf[0:self.require_length] # 把資料從緩衝區中取走 self.buf = self.buf[self.require_length:] self.solve(data) class ReceiveFactory(Factory): def buildProtocol(self, addr): return ReceiveProtocol()def main(): print 'logserver has started.' logger = logging.getLogger('log_server') logger.info('logserver has started.') from twisted.internet import epollreactor epollreactor.install() reactor = twisted.internet.reactor reactor.listenTCP(settings.PORT, ReceiveFactory()) reactor.run() if __name__ == '__main__': main()
完成程式:
https://github.com/vearne/log_server/tree/master
參考資料:
https://docs.python.org/2/howto/logging-cookbook.html#logging-cookbook
我的的python語言指令碼監控的伺服器日誌,日誌出現錯誤的時根據錯誤關鍵字進行語音警示可是最近出現
keyword, wav = line.strip().split(':')中後面得到的列表中資料多於2個。
可以用下面兩種方法修改:
1.只關心用.分割的前兩項,修改為下面的樣子
l=list.strip().split('.)
keyword=l[0]
wav=l[1]
即不管有多少個項資料,只取前兩項
2.只關心以第一個.分割的兩項
l=s.find(".")
keyword=s[0:l]
wav=s[l+1:]
兩種處理方法哪個更符合你程式的意圖需要自己判斷,在修改前也可以在64行前列印line的值進行判斷 print line。
python apache django伺服器錯誤日誌一直是這樣的,問這是什問題
怪哉,怎麼會有PHP的警告?