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.

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

报告相同问题?

悬赏问题

  • ¥15 做个有关计算的小程序
  • ¥15 MPI读取tif文件无法正常给各进程分配路径
  • ¥15 如何用MATLAB实现以下三个公式(有相互嵌套)
  • ¥30 关于#算法#的问题:运用EViews第九版本进行一系列计量经济学的时间数列数据回归分析预测问题 求各位帮我解答一下
  • ¥15 setInterval 页面闪烁,怎么解决
  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
  • ¥15 TLE9879QXA40 电机驱动
  • ¥20 对于工程问题的非线性数学模型进行线性化