#### 实现一个简单的日志收集程序。
定时任务定时去请求HTT服务获取最新的配置(配置包含日志文件的路径,正则表达式),根据获取到的配置去实时监控日志完成日志收集。
注:不重启程序的前提下更换不同日志路径和正则表达式去完成日志收集。(服务器由于某些原因提取日志困难)
```
// 实时读取文件更新内容
func GetErrorLog(path string, rule string) {
filename := path //文件名
tails, err := tail.TailFile(filename, tail.Config{
ReOpen: true,
Follow: true,
Location: &tail.SeekInfo{Offset: 0, Whence: 2},
MustExist: false,
Poll: true,
})
if err != nil {
fmt.Println("tail file err:", err)
return
}
var msg *tail.Line
var ok bool
for true {
msg, ok = <-tails.Lines
if !ok {
time.Sleep(100 * time.Millisecond)
continue
}
compile, _ := regexp.Compile(rule) //rule :^(.*)\\[E\\](.*)
compileFindString := compile.FindString(msg.Text)
if compileFindString != "" {
fmt.Println("[E]:", compileFindString)
}
}
}
func crontask() {
c := cron.New()
spec1 := "*/5 * * * * ?"
c.AddFunc(spec1, func() {
aa := GetInfo()
})
c.Run()
}
func main() {
/*
将GetInfo获取的配置写入文件,viper去监控文件的更新
*/
go GetErrorLog(path, "^(.*)\\[E\\](.*)")
crontask()
}
```
看了3遍,总算明白了……
你需要做的是,发现文件更新后,Close了tail的lines这个cha。
```
if !ok {
time.Sleep(100 * time.Millisecond)
continue
}
```
这一段改掉,改成退出
然后重新启一个监听协程,即再 go GetErrorLog一下
另外你这个正则的编译明显不该放在循环内
#3
更多评论
实话说,我咋感觉这更像是一篇文章,介绍实时读取文件更新的内容时如何在不重启程序的情况下更换日志文件路径和正则表达式。
所以,不知道你的问题是啥?你这代码有问题还是怎么的?
#1
我现在遇见的问题是,运行程序后我更新配置文件的内容viper也能监听到文件修改但是`go GetErrorLog(path, "^(.*)\\[E\\](.*)")`中监控的文件的path并没有发生变化。
#2