当创建新文件时,Golang会替换先前打开的文件。

huangapple go评论79阅读模式
英文:

Golang replace previously opened file when new file is created

问题

好的,以下是翻译好的内容:

好的,我正在监控某个文件,并对该文件进行一些tail -f分析。
然而,另一个应用程序具有特定的逻辑,它将在下一个日期或之前创建一个新文件。

我正在寻找一种方法来检测新创建的文件(主机是Linux机器),然后在不重启当前的Go服务的情况下开始跟踪新创建的文件。

这是我目前用于跟踪“当前文件”的逻辑:

func main(){

    currentTime := time.Now().Local()
    currentFileName := strings.Replace(currentTime.Format("2006-01-02"), "-", "", 2)
    newFileName := currentFileName + "_1111.log.txt"

    //使用github.com/hpcloud/tail进行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)

        //检查新行中是否有错误
        if strings.Contains(strings.ToLower(line.Text), "mfc"){
            fmt.Println("MFC located: ", line.Text)

            //现在向所有相关方发送电子邮件
            //sendEmail(line.Text)
        }

    }

    fmt.Println(err)
}

当前文件可能是20161219_1111.log或类似的文件,而在第二天它将从20161220_1111.log等开始。

欢迎提供任何提示。

英文:

Ok so I am monitoring certain file and doing some tail -f analysis of that file.
However another application has specific logic and it will create a new file on next date or even before.

I'm looking for a way to detect newly created file (host is linux machine) and then without restart of my current go service to start tailing newly created file.

Here is my current logic for tailing "current file":

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)
}

Well current file instead 20161219_1111.log can be 20161219_2222.log or similar, and on next day it starts from 20161220_1111.log etc.

Any hints are welcome.

答案1

得分: 3

尝试使用github.com/fsnotify/fsnotify进行操作。

以下是一个简单的示例:

func newFileCheck() (newFilename chan string, err error) {
    watcher, err := fsnotify.NewWatcher()
    if err != nil {
        // 记录一些日志
        return
    }

    err = watcher.Watch("testDir")
    if err != nil {
        // 记录一些日志
        return
    }

    newFilename = make(chan string)

    // 处理事件
    go func() {
        for {
            select {
            case ev := <-watcher.Event:
                log.Println("event:", ev)
                newFilename <- ev.Name // 文件的相对路径
            case err := <-watcher.Error:
                log.Println("error:", err)
            }
        }
    }()

    return
}

func yourApp() {

    newFilenameChan, err := newFileCheck()
    if err != nil {
        // 错误检查
    }


    go func() {
        for {
            select {
            case name := <-newFilenameChan:
                // 关闭旧文件并读取新文件
            }
        }
    }()
}

更多详细信息,请参阅文档。

英文:

have a try with github.com/fsnotify/fsnotify

a simple example:

func newFileCheck() (newFilename chan string, err error) {
	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		// do some log
		return
	}

	err = watcher.Watch(&quot;testDir&quot;)
	if err != nil {
		// do some log
		return
	}

	newFilename = make(chan string)

	// Process events
	go func() {
		for {
			select {
			case ev := &lt;-watcher.Event:
				log.Println(&quot;event:&quot;, ev)
				newFilename &lt;- ev.Name // Relative path to the file
			case err := &lt;-watcher.Error:
				log.Println(&quot;error:&quot;, err)
			}
		}
	}()

	return
}

func yourApp() {

	newFilenameChan, err := newFileCheck()
	if err != nil {
		// err check
	}


	go func() {
		for {
			select {
			case name := &lt;-newFilenameChan:
				// close the old one and read new file
			}
		}
	}()
}

more details, see the doc

答案2

得分: 1

请稍等,我会为您进行翻译。

英文:

Treat the following as a hacked up example.

I'm not sure about the procedure to close a tail.Tail properly, assuming you call Stop or StopAtEOF and then Cleanup.

Also the concurrency aspects need to be refined. Goroutines need to be gracefully shut down.

Imports :

  • github.com/fsnotify/fsnotify
  • github.com/hpcloud/tail

Function to check for New Files :

func newFileCheck(dir string) (newFileAlert &lt;-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 := &lt;-watcher.Events:
				log.Println(&quot;Event : &quot;, ev)
				if ev == fsnotify.Create {
					newFileAlertSender &lt;- ev.Name
				}
			case err := &lt;-watcher.Errors:
				log.Println(&quot;Watcher Error : &quot;, err)
			}
		}
	}()

	return
}

Function to Tail a file :

func tailFile(dir, newFileName string, cfg tail.Config, stop &lt;-chan struct{}) {

	t, err := tail.TailFile(dir+newFileName, cfg)
	if err != nil {
		log.Fatalln(&quot;TailFile failed - &quot;, err)
	}

	for line := range t.Lines {

		if strings.Contains(strings.ToLower(line.Text), &quot;mfc&quot;) {
			fmt.Println(&quot;MFC located: &quot;, line.Text)
			//sendEmail(line.Text)
		}

		select {
		case &lt;-stop:
			t.StopAtEOF()
		default:
		}

	}

	t.Cleanup()
}

Main :

func main() {

	dir := &quot;/var/log/&quot;

	currentTime := time.Now().Local()
	currentFileName := currentTime.Format(&quot;20060102&quot;)
	newFileName := currentFileName + &quot;_1111.log.txt&quot;

	newFileAlert, err := newFileCheck(dir)
	if err != nil {
		log.Fatalln(&quot;File watching failed - &quot;, err)
	}

	stop := make(chan struct{})

	cfg := tail.Config{Follow: true, ReOpen: true}

	go tailFile(dir, newFileName, cfg, stop)

	for fileName := range newFileAlert {
		stop &lt;- struct{}{}
		go tailFile(dir, fileName, cfg, stop)
	}
}

huangapple
  • 本文由 发表于 2016年12月19日 23:18:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/41225759.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定