在上一篇中解決了系統的性能問題,但寫log又引入了問題,多進程寫log會引起混亂。
查詢了多進程寫log 的方案, 主要有2種:
利用多進程的Queue,把log放到統一的有個log queue里面,一個單獨的線程寫log
起一個單獨的socket
server,由 這個server來接受log,并負責寫log
我覺得這2重方案都太重了,很多寫log的地方就需要改動了,希望找到一個方案能直接不改動老代碼寫log的方式,開始考慮的是每個進程單獨寫一個log,但這樣統計數據有點小不方便。 繼續探索到,有個開源的項目(https://launchpad.net/python-concurrent-log-handler),已經實現了多進程寫log,但目前只是實現了按文件大小RotatingFileHandler, 按時間rotate 的功能還沒實現。不過這個已經足夠用了。
try: from cloghandler import ConcurrentRotatingFileHandler as RFHandler except ImportError: from warnings import warn warn("ConcurrentLogHandler package not installed. Using builtin log handler") from logging.handlers import RotatingFileHandler as RFHandler rotateHandler = RFHandler("sim.log", "a", 10*1024*1024, 5) formatter = logging.Formatter('%(asctime)s [%(processName)s %(threadName)s %(levelname)s %(module)s:%(lineno)d] %(message)s') rotateHandler.setFormatter(formatter) log = logging.getLogger() log.addHandler(rotateHandler) log.setLevel(20) rotateHandler = RFHandler("sim.log", "a", 10*1024*1024, 5) |
log文件名為sim.log, 文件到10M就會rotate, 最多保留5個文件
formatter = logging.Formatter('%(asctime)s [%(processName)s %(threadName)s %(levelname)s %(module)s:%(lineno)d] %(message)s') 設置log輸出的格式, 包括時間,進程名,線程名,模塊名字,代碼行數
log.setLevel(20) 設置什么級別的log輸出, CRITICAL 50; ERROR 40; WARNING 30; INFO 20; DEBUG 10, NOSET 0;
import logging import time import multiprocessing class Customer(multiprocessing.Process): def __init__(self,mp_name): multiprocessing.Process.__init__(self,name=mp_name) def run(self): while 1: logging.debug(" I am here") time.sleep(1) for i in xrange(2): mp=Customer("customer"+str(i)) mp.start() |
最后輸出log的例子是:
2013-12-05 21:42:10,961 [customer0 MainThread DEBUG testqueue_old:115] I am here 2013-12-05 21:42:15,361 [customer1 MainThread DEBUG testqueue_old:115] I am here |
相關
文章: