2009-07-30 76 views
5

我有一個網站在Django中運行。前端是lighttpd,並使用fcgi來承載django。Django和fcgi - 日誌問題

我開始我的FCGI流程如下:

python2.6 /<snip>/manage.py runfcgi maxrequests=10 host=127.0.0.1 port=8000 pidfile=django.pid 

對於記錄,我有一個RotatingFileHandler定義如下:

file_handler = RotatingFileHandler(filename, maxBytes=10*1024*1024, backupCount=5,encoding='utf-8') 

的日誌記錄工作。然而,它看起來像文件旋轉時,他們甚至達不到10Kb,更不用說10Mb。我的猜測是,每個fcgi實例只處理10個請求,然後重新產卵。每個fcgi的重生都創建一個新文件。我確認fcgi每隔一段時間都在新進程標識下啓動(很難完全確切地說出時間,但不到一分鐘)。

有沒有辦法解決這個問題?我希望所有fcgi實例都記錄到一個文件中,直到達到大小限制,此時將發生日誌文件輪換。

回答

6

正如Alex所說,日誌是線程安全的,但標準處理程序不能安全地用於從多個進程登錄到單個文件。

ConcurrentLogHandler使用文件鎖定允許從多個進程內進行登錄。

2

在你的鞋子裏,我會切換到TimedRotatingFileHandler - 我很驚訝基於尺寸的旋轉文件句柄給出了這個問題(因爲它應該不會影響生成日誌條目的過程),但是定時版本(儘管不能完全控制你喜歡的參數)應該解決它。或者,編寫自己的,更堅實的,旋轉的文件處理程序(可以從標準庫源獲取很多內容),確保不同的進程不是問題(因爲它們不應該是)。

0

由於您似乎正在使用append(「a」)的默認文件打開模式而不是寫入(「w」),因此如果進程重新生成,它應該追加到現有文件,然後在大小限制已達到。所以我不確定你所看到的是由重新產生CGI過程造成的。 (這當然假定當進程重新生成時文件名保持不變)。

儘管日誌包是線程安全的,但它並不處理來自多個進程的同一文件的併發訪問 - 因爲在stdlib中沒有標準的方法來執行它。我的正常建議是建立一個單獨的守護進程,它實現一個套接字服務器並將跨接收的事件記錄到文件中 - 其他進程然後只實現一個SocketHandler來與日誌守護進程進行通信。然後所有事件都會正確地序列化到磁盤。 Python文檔包含一個可用作此需求基礎的working socket server