英文:
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("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
}
}
}()
}
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 <-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
}
Function to Tail a file :
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()
}
Main :
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)
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论