2010-02-04 62 views
4

我正在linux上記錄日誌。
記錄器在init上打開一個文件。
並在程序運行時寫入該文件描述符。
如果日誌文件將在文件描述符創建後被刪除,
將不會檢測到異常/錯誤。
我曾嘗試:ofstream - 檢測文件是否在打開和關閉之間被刪除

out.fail() 
!out.is_open() 

我有谷歌這個,發現這個職位。
http://www.daniweb.com/forums/thread23244.html

所以我現在明白,即使該文件被刪除通過使用rm。它仍然存在,它完全沒有聯繫。
處理這個問題的最佳方法是什麼?
1.這是一個日誌應用程序,所以性能是一個問題,我不想在每次寫入時使用stat()
2.我不在乎日誌文件中的某些行是否會在開始
3.允許用戶刪除日誌文件,重新開始。記錄器應該重新打開文件。

+0

你用什麼函數寫入文件? 例如對於fwrite,您可以測試返回結果。如果大小不同於預期,然後重新打開(創建)文件.. – 2010-02-04 11:05:23

+0

@ Dyatlov測試結果不會幫助,因爲文件存在它只是取消鏈接,寫成功。檢查文件大小也是如此,謝謝 – jojo 2010-02-04 12:15:10

+0

我在調查同樣的問題時遇到了這個問題,除了做刪除的過程是logrotate - 我的情況要修復得更乾淨 - logrotate有一個選項 - copytruncate - 它會通過根本不刪除文件來解決此問題。 – 2013-04-15 23:54:57

回答

6

文件是'unlinked'通過rm

一個文件可以有很多名字。當它沒有名字時,沒有人打開它,然後它被文件系統回收,並且它佔據的空間可以被重新使用。

Linux有一個用於'看'文件的API,名爲inotify,但這引起了複雜性和競爭條件。

所以更大的問題是,運行時還有誰會刪除此文件,爲什麼?說服他們不要!

+0

我們的系統讓用戶刪除日誌文件,以便他可以重新開始,這就是我們的系統的工作方式,我無法更改這個:( – jojo 2010-02-04 10:46:23

+1

),那麼您需要爲用戶提供一個過程來發送'truncate'消息記錄器,而不是在文件系統上進行手動刪除,您需要更改某些內容,但目前的方法將無法通過設計進行工作 – Will 2010-02-04 10:50:09

+0

inotify可能是解決此問題的最佳方法,即使它很複雜。 – 2012-03-05 16:16:25

1

您在評論中指出,原因是允許用戶刪除日誌文件,在這種情況下,您希望應用程序在其位置開始編寫新的文件。

處理這個問題的傳統UNIX機制是讓你的程序安裝一個信號處理程序(通常爲SIGHUP,因爲這對於守護進程來說沒有意義)。信號處理程序包括使程序關閉並重新打開日誌文件的代碼。

然後指示用戶刪除日誌文件後,他們需要向程序發送SIGHUP

0

處理此問題的唯一明智方法是嘗試寫入日誌。如果寫入失敗(大部分時間不會),那麼你需要找出原因。此時,您可以執行諸如使用stat來查看日誌是否仍然存在的信息 - 如果是,則會出現某種磁盤已滿或權限錯誤,如果不是,則可能很難或無法恢復,重新打開並重新嘗試寫入。

+0

@Neil rm不會刪除該文件,而是簡單地取消它的鏈接。文件仍然存在並被應用程序使用,寫入將成功。 因此檢查錯誤將無濟於事 – jojo 2010-02-04 12:22:49