[python]logging 有支援 multi-thread
以往,寫 log 都是很直覺,自己開個檔案就寫下去了。
      f = open(filename,mode)
      f.write(str(datetime.datetime.now())+ " " + string_to_write + "\n")
      f.close()然而,寫久了的確很煩,於是,進一步的,會寫成一個 module 來簡化。
def log(filename,mode,string_to_write):
  try:
    f = open(filename,mode)
    f.write(str(datetime.datetime.now())+ " " + string_to_write + "\n")
    f.close()
  except:
    if f != None:
      f.close()但是,最近遇到,我的程式開始有 multi-thread,這樣子開檔寫, 
  
有時會漏 log,有時會干擾,像這樣
2012-02-17 23:47:45.211000 DEBUG doing ('e02_v2.py',)
2012-02-17 23:47:45.211000 DEBUG doing ('e02_v2.py',)
',)
2012-02-17 23:47:45.211000 DEBUG doing ('c17_json_v3.py',)
2012-02-17 23:47:52.215000 DEBUG done ('e02_v2.py',)
這當然不能忍受,但是,要馬上處理這種問題又不會。 
  
還好,python 內建的 logging 是 thread-safe 就可以應付 multi-thread。(還沒辦法處理 multi-process 寫檔案)
logging 最基本的使用方法:
  logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s %(levelname)s %(message)s',
                    filename=filename,
                    filemode=mode)
  logging.debug(log_string)第 1 行是設定 logging 的 level、每個記錄的格式、檔名、及開檔模式。 
  
第 5 行就是寫 log。
level 預設是 NOTSET, DEBUG, INFO, WARNING, ERROR 及 CRITICAL 等 6 種。 
  
最後面的等級越高。 
  
舉例來說明,設定的等級為 INFO,則 logging.debug 是不會寫入 log 裡, 
  
要 logging.info, logging.warn, logging.error, logging.critical 才會寫入 log 裡。
記錄的格式,可以使用的變數,這裡就不寫,請參考 python 線上手冊。 
  
這裡要提的是,若我們要的,原來沒提供怎辦? 
  
例如,%(asctime)s 寫出來的是:
2012-02-17 23:52:02,157 DEBUG mylog doing ('e02_v2.py',)
可是我想要這樣,但 time.strftime 不支援 %f
2012-02-17 23:47:52.215000 DEBUG done ('e02_v2.py',)
這時候可以這樣改,在format 裡加一個變數名,例如 %(curdatetime)s 
  
然後準備一個 d = {'curdatetime' : datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')} 
  
在寫 log 的時候,帶在 extra 的變數裡。logging.debug(log_string,extra=d) 
  
為了方便,我又打包成一個 module 如下:
import datetime, logging
def log(filename,mode,log_string):
  logging.basicConfig(level=logging.DEBUG,
                    format='%(curdatetime)s %(levelname)s %(message)s',
                    filename=filename,
                    filemode=mode)
  d = {'curdatetime':datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')}
  logging.debug(log_string,extra=d)這樣就不用每次寫 log 都自帶一個 extra 的 dict。
用了 logging,也就不怕 multi-thread 了。
當然 logging 還有很多其他功能。以後不用自己寫了。
http://docs.python.org/library/logging.html#logrecord-attributes