2016-12-20 7 views
0

私はgolangにいくつかのログアナライザを作成しています。私が必要とするのは、新しく作成されたファイルのリアルタイムtail -fです。現在のテールを中断して新しいものを開始する

私はfsnotifyパッケージと共にテールパッケージを使用していますが、私はチャネルやルーチンをあまりよく知らないので、何か助けが必要です。

現在、プログラムは次のようになります。

package main 

import(
    "fmt" 
    "github.com/hpcloud/tail" 
    "strings" 
    "log" 
    "net/smtp" 
    "time" 
    "github.com/fsnotify/fsnotify" 
) 

//this function needs to monitor for new files in directory 
func newFileCheck() (newFilename chan string, err error) { 
    watcher, err := fsnotify.NewWatcher() 
    if err != nil { 
     return 
    } 

    err = watcher.Add("myDir") 
    if err != nil { 
     return 
    } 

    newFilename = make(chan string) 

    // Process events 
    go func() { 
     for { 
      select { 
      case ev := <-watcher.Events: 
       log.Println("event:", ev) 
       newFilename <- ev.Name // Relative path to the file 
       //t.Stop() //if I pass reference to t THIS IS NOT HAPPENING ? 
      case err := <-watcher.Errors: 
       log.Println("error:", err) 
      } 
     } 
    }() 

    return 
} 

func main() { 
    newFileName = "mylog_0000.log.txt" 

    fmt.Println("Processing log: ",newFileName) 

    newFilenameChan, err := newFileCheck() 
    if err != nil { 
     fmt.Println("ERR: ",err) 
    } 

    t := tailLog(newFileName) 

    go func() { 
     for { 
      select { 
       case name := <-newFilenameChan: 
        fmt.Println("New file created: ",name) //this will be printed only once and then on new events nothing is printed ? 

       //NONE of the lines abowe doesn't work 
       t.Stop() 
       t.Dead() 
       t.Done() 

       t = tailLog(name) 
      } 
     } 
    }() 
} 

func tailLog(fileName string) *tail.Tail{ 
    var count = 0 
    // close the old one and read new file 
    t, err := tail.TailFile("/mydir/"+fileName, tail.Config{Follow: true, ReOpen: true}) 

    for line := range t.Lines { 
     //fmt.Println("Line is:", line.Text) 

     //check do we have what we need 
     if strings.Contains(strings.ToLower(line.Text), "mfc"){ 

      count++ 
      //do other stuff 
     } 
    } 

    fmt.Println(err) 

    return t 
} 

newFileCheck機能のみ拳時間のイベントを印刷し、そしてまた、私はアクティブな尾をキャンセルする方法を見つけ出すことができないんだけど、なぜだから私は把握することはできません新しいイベントが発生したら、そのイベントの後に再びテールを開始しますか?

+0

ここに投稿する前に必ず 'go fmt'を使ってコードを実行する必要があります。これは、回答が得られる可能性が高くなるからです。ドキュメントの隣に –

答えて

0

はこのことを考えてみましょう:

すると機能の主が戻ると、プログラムが終了します。他の(メインではない)ゴルーチンが完了するまで、 を待つことはありません。

そして

あなたのコードのこのブロックを見て:

func main() { 
    newFileName = "mylog_0000.log.txt" 

    fmt.Println("Processing log: ",newFileName) 

    newFilenameChan, err := newFileCheck() 
    if err != nil { 
     fmt.Println("ERR: ",err) 
    } 

    t := tailLog(newFileName) 

    go func() { 
     for { 
      select { 
       case name := <-newFilenameChan: 
        fmt.Println("New file created: ",name) //this will be printed only once and then on new events nothing is printed ? 

       //NONE of the lines abowe doesn't work 
       t.Stop() 
       t.Dead() 
       t.Done() 

       t = tailLog(name) 
      } 
     } 
    }() 
} 

優雅で、このジョブを処理するために、あなたはGolangで並行処理についての詳細を学ぶ必要があります。チャンネルを使用して停止/開始/ etcなどのゴルーチンを制御し、タスクの実行/終了の順序に関心がある場合はWaitGroupを使用します。あなたのプログラムフローを制御できないとき、goroutineは自分の人生を生きることができ、それは悪い習慣です。

+0

、私はルーチンとチャネルについてもっと学ぶことができる良いリンクがありますか?私はドキュメントをカバーしましたが、これを動作させるには十分ではありません。ここでは2つの異なる公式ライブラリを扱っているので、 – Splendid

+0

[link](https://divan.github.io/posts/go_concurrency_visualize/)、[link](https://tour.golang.org/concurrency/1)およびこの[link](https:// github .com/golang/go/wiki/CommonMistakes)は、並行処理をしているすべての人にヒットしました。すべてのドキュメントと一緒に。ゴランは本当によく書かれています。また、他の人のコードは、多くの刺激を与えることができます。 – bigless

+0

Atmチャネルを見てください。なぜそれらを閉じ、いつブロックチャンネルを使用するか、バッファされたチャンネルを使用する。また、あなたのタイルを止める方法を紹介します。 – bigless

関連する問題