好的,我正在监视某个文件并对该文件进行一些tail -f分析。 但是,另一个应用程序具有特定的逻辑,它将在下一个日期甚至之前创建一个新文件。
我正在寻找一种方法来检测新创建的文件(主机是linux机器),然后不重新启动我当前的go服务以开始拖尾新创建的文件。
这是我当前拖尾“当前文件”的逻辑:
func main(){
currentTime := time.Now().Local()
currentFileName := strings.Replace(currentTime.Format("2006-01-02"), "-","",2)
newFileName := currentFileName + "_1111.log.txt"
//using github.com/hpcloud/tail for tail
t, err := tail.TailFile("/var/log/"+newFileName, tail.Config{Follow: true, ReOpen: true})
for line := range t.Lines {
//fmt.Println("Line is:", line.Text)
//check do we have error inside new line
if strings.Contains(strings.ToLower(line.Text), "mfc"){
fmt.Println("MFC located: ", line.Text)
//now send e-mail to all interested parties
//sendEmail(line.Text)
}
}
fmt.Println(err)
}
当前文件而不是20161219_1111.log可以是20161219_2222.log或类似,第二天它从20161220_1111.log等开始。
欢迎任何提示。
答案 0 :(得分:3)
尝试使用github.com/fsnotify/fsnotify
一个简单的例子:
func newFileCheck() (newFilename chan string, err error) {
watcher, err := fsnotify.NewWatcher()
if err != nil {
// do some log
return
}
err = watcher.Watch("testDir")
if err != nil {
// do some log
return
}
newFilename = make(chan string)
// Process events
go func() {
for {
select {
case ev := <-watcher.Event:
log.Println("event:", ev)
newFilename <- ev.Name // Relative path to the file
case err := <-watcher.Error:
log.Println("error:", err)
}
}
}()
return
}
func yourApp() {
newFilenameChan, err := newFileCheck()
if err != nil {
// err check
}
go func() {
for {
select {
case name := <-newFilenameChan:
// close the old one and read new file
}
}
}()
}
更多详情,请参阅文档
答案 1 :(得分:1)
将以下内容视为一个被黑客攻击的例子。
我不确定正确关闭tail.Tail
的程序,假设您致电Stop
或StopAtEOF
然后Cleanup
。
还需要改进并发方面。 Goroutines需要优雅地关闭。
进口:
检查新文件的功能:
func newFileCheck(dir string) (newFileAlert <-chan string, err error) {
watcher, err := fsnotify.NewWatcher()
if err != nil {
return
}
err = watcher.Add(dir)
if err != nil {
return
}
newFileAlertSender := make(chan string)
newFileAlert = newFileAlertSender
go func() {
for {
select {
case ev.Op := <-watcher.Events:
log.Println("Event : ", ev)
if ev == fsnotify.Create {
newFileAlertSender <- ev.Name
}
case err := <-watcher.Errors:
log.Println("Watcher Error : ", err)
}
}
}()
return
}
Tail文件的功能:
func tailFile(dir, newFileName string, cfg tail.Config, stop <-chan struct{}) {
t, err := tail.TailFile(dir+newFileName, cfg)
if err != nil {
log.Fatalln("TailFile failed - ", err)
}
for line := range t.Lines {
if strings.Contains(strings.ToLower(line.Text), "mfc") {
fmt.Println("MFC located: ", line.Text)
//sendEmail(line.Text)
}
select {
case <-stop:
t.StopAtEOF()
default:
}
}
t.Cleanup()
}
主要:
func main() {
dir := "/var/log/"
currentTime := time.Now().Local()
currentFileName := currentTime.Format("20060102")
newFileName := currentFileName + "_1111.log.txt"
newFileAlert, err := newFileCheck(dir)
if err != nil {
log.Fatalln("File watching failed - ", err)
}
stop := make(chan struct{})
cfg := tail.Config{Follow: true, ReOpen: true}
go tailFile(dir, newFileName, cfg, stop)
for fileName := range newFileAlert {
stop <- struct{}{}
go tailFile(dir, fileName, cfg, stop)
}
}