3 回答
TA貢獻1786條經(jīng)驗 獲得超11個贊
這是使用fsnotifylib 監(jiān)視日志文件的另一種方法。fsnotify監(jiān)控xxx.log所在的目錄,告訴lumberjackRotate()什么時候刪除xxx.log。
import (
"fmt"
"log"
"path/filepath"
"time"
"github.com/fsnotify/fsnotify"
"gopkg.in/natefinch/lumberjack.v2"
)
func main() {
logPath := "./xxx.log"
logName := filepath.Base(logPath)
logger := &lumberjack.Logger{
// Log path
Filename: logPath,
// Log size MB
MaxSize: 10,
// Backup count
MaxBackups: 3,
// expire days
// MaxAge: 28,
// gzip compress
Compress: false,
}
watcher, err := fsnotify.NewWatcher()
if err != nil {
log.Fatal(err)
}
defer watcher.Close()
go func() {
for event := range watcher.Events {
if event.Op&fsnotify.Remove == fsnotify.Remove &&
event.Name == logName {
log.Println("rotate log", event.Name)
logger.Rotate()
}
}
}()
err = watcher.Add(filepath.Dir(logPath))
if err != nil {
log.Fatal(err)
}
for {
logger.Write([]byte(fmt.Sprintf("current time:%v\n", time.Now())))
time.Sleep(3 * time.Second)
}
}
TA貢獻1831條經(jīng)驗 獲得超9個贊
問題”
基于所述行為,我假設(shè)這發(fā)生在為文件實現(xiàn) POSIX 兼容行為的操作系統(tǒng)上(因此它運行在具有 Unix 遺產(chǎn)的某些內(nèi)核上 - 例如 *BSD 或 Linux,或者它是 Mac OS 系統(tǒng))。在這些系統(tǒng)上,從文件系統(tǒng)中刪除文件對該文件系統(tǒng)上的文件存儲沒有任何影響——只要它至少在一個正在運行的進程中打開。
具體來說,要引用POSIX 文檔open(2):
如果文件的鏈接計數(shù)為0,則當與該文件關(guān)聯(lián)的所有文件描述符都關(guān)閉時,該文件占用的空間將被釋放,該文件將不再可訪問。
打開文件被認為將其鏈接計數(shù)增加 1,從其文件系統(tǒng)中刪除文件與將鏈接計數(shù)減 1 相同。您可以在此處
閱讀有關(guān)鏈接計數(shù)的更多信息。
假設(shè)您正在使用的日志記錄包保持日志文件處于打開狀態(tài),因此您只需從文件系統(tǒng)的目錄中刪除文件名,但這絕不會影響日志記錄過程。
此外,當任何文件名消失時,不會通知打開文件的進程(在類 Unix 系統(tǒng)上,一個文件可能同時有多個名稱——請閱讀硬鏈接)。
解決方案
通常,對于類 Unix 操作系統(tǒng),有一種方法可以明確要求進程重新打開其日志文件。
偶然地,SIGUSR1為此使用了一個信號,因此您可以設(shè)置一個處理程序(通過signal.Notify)為此類信號設(shè)置一個處理程序,然后將您的日志輪換代碼設(shè)置kill -USR1為正在運行的進程,以告訴它重新打開日志文件,這將是重新創(chuàng)建。
當然,可以實施更多涉及的方案,因為您可以使用任何形式的IPC將該命令傳達給正在運行的進程。
TA貢獻1869條經(jīng)驗 獲得超4個贊
刪除 xxx.log 后,您可以向正在運行的進程發(fā)送一個信號,然后下面的代碼將處理該信號并告訴伐木工人創(chuàng)建新的日志文件。
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGUSR1)
go func() {
for _ = range sigs {
// call Rotate() method of lumberjack to create new log file
logger.Rotate()
}
}()
用于刪除和輪換日志的命令
# delete log file
rm path/to/xxx.log
# this command would not kill your process, just send a signal to it.
kill -USR1 <your process id>
- 3 回答
- 0 關(guān)注
- 284 瀏覽
添加回答
舉報
