douzhi9921 2018-04-20 00:41
浏览 14
已采纳

如何重复关闭并建立执行例程?

every one,I am new to golang.I wanna get the data from log file generated by my application.cuz roll-back mechanism, I met some problem.For instance,my target log file is chats.log,it will be renamed to chats.log.2018xxx and a new chats.log will be created.so my go routine that read log file will fail to work. so I need detect the change and shutdown the previous go routine and then establish the new go routine.

I looked for modules that can help me,and I found

func ExampleNewWatcher(fn string, createnoti chan string, wg sync.WaitGroup) {
    wg.Add(1)
    defer wg.Done()
    watcher, err := fsnotify.NewWatcher()
    if err != nil {
        log.Fatal(err)
    }
    defer watcher.Close()

    done := make(chan bool)
    go func() {
        for {
            select {
            case event := <-watcher.Events:
                if event.Op == fsnotify.Create && event.Name==fn{
                        createnoti <- "has been created"
                }
            case err := <-watcher.Errors:
                log.Println("error:", err)
            }
        }
    }()

    err = watcher.Add("./")
    if err != nil {
        log.Fatal(err)
    }
    <-done
}

I use fsnotify to detech the change,and make sure the event of file is my log file,and then send some message to a channel.

this is my worker go routine:

func tailer(fn string,isfollow bool, outchan chan string, done <-chan interface{},wg sync.WaitGroup) error {
    wg.Add(1)
    defer wg.Done()
    _, err := os.Stat(fn)
    if err != nil{
        panic(err)
    }
    t, err := tail.TailFile(fn, tail.Config{Follow:isfollow})
    if err != nil{
        panic(err)
    }
    defer t.Stop()

    for line := range t.Lines{
        select{
        case outchan <- line.Text:
            case <- done:
                return nil
        }
    }

    return nil
}

I using tail module to read the log file,and I add a done channel to it to shutdown the cycle(I don't know whether I put it in the right way) And I will send every log content to a channel to consuming it. So here is the question:how should I put it together?

ps: Actually,I can use some tool to do this job.like apache-flume,but all of those tools need dependency. Thank you a lot!

  • 写回答

1条回答 默认 最新

  • douhui8025 2018-04-20 01:05
    关注

    Here is a complete example that reloads and rereads the file as it changes or gets deleted and recreated:

    package main
    
    import (
            "github.com/fsnotify/fsnotify"
            "io/ioutil"
            "log"
    )
    
    const filename = "myfile.txt"
    
    func ReadFile(filename string) string {
            data, err := ioutil.ReadFile(filename)
            if err != nil {
                    log.Println(err)
            }
            return string(data)
    }
    
    func main() {
            watcher, err := fsnotify.NewWatcher()
            if err != nil {
                    log.Fatal(err)
            }
            defer watcher.Close()
            err = watcher.Add("./")
            if err != nil {
                    log.Fatal(err)
            }
            for {
                    select {
                    case event := <-watcher.Events:
                            if event.Op == fsnotify.Create && event.Name == filename {
                                    log.Println(ReadFile(filename))
                            }
                    case err := <-watcher.Errors:
                            log.Println("error:", err)
                    }
            }
    }
    

    Note this doesn't require goroutines, channels or a WaitGroup. Better to keep things simple and reserve those for when they're actually needed.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!