mirror of
https://github.com/postmannen/ctrl.git
synced 2024-12-14 12:37:31 +00:00
108 lines
2.4 KiB
Go
108 lines
2.4 KiB
Go
|
package steward
|
||
|
|
||
|
import (
|
||
|
"bufio"
|
||
|
"fmt"
|
||
|
"io"
|
||
|
"log"
|
||
|
"os"
|
||
|
|
||
|
"github.com/fsnotify/fsnotify"
|
||
|
)
|
||
|
|
||
|
// getMessagesFromFile will start a file watcher for the given directory
|
||
|
// and filename. It will take a channel of []byte as input, and it is
|
||
|
// in this channel the content of a file that has changed is returned.
|
||
|
func getMessagesFromFile(directoryToCheck string, fileName string, fileContentCh chan []byte) {
|
||
|
fileUpdated := make(chan bool)
|
||
|
go fileWatcherStart(directoryToCheck, fileUpdated)
|
||
|
|
||
|
for {
|
||
|
select {
|
||
|
case <-fileUpdated:
|
||
|
//load file, read it's content
|
||
|
b, err := readTruncateMessageFile(fileName)
|
||
|
if err != nil {
|
||
|
log.Printf("error: reading file: %v", err)
|
||
|
}
|
||
|
|
||
|
fileContentCh <- b
|
||
|
fmt.Printf("File content read: %s\n", b)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
// readTruncateMessageFile, will read all the messages in the given
|
||
|
// file, and truncate the file after read.
|
||
|
// A []byte will be returned with the content read.
|
||
|
func readTruncateMessageFile(fileName string) ([]byte, error) {
|
||
|
|
||
|
f, err := os.OpenFile(fileName, os.O_APPEND|os.O_RDWR, os.ModeAppend)
|
||
|
if err != nil {
|
||
|
log.Printf("Failed to open file %v\n", err)
|
||
|
return nil, err
|
||
|
}
|
||
|
defer f.Close()
|
||
|
|
||
|
scanner := bufio.NewScanner(f)
|
||
|
|
||
|
lines := []byte{}
|
||
|
|
||
|
for scanner.Scan() {
|
||
|
lines = append(lines, scanner.Bytes()...)
|
||
|
}
|
||
|
|
||
|
fmt.Printf("*** DEBUG : %s\n", lines)
|
||
|
|
||
|
fmt.Printf("read: %s\n", lines)
|
||
|
|
||
|
// empty the file after all is read
|
||
|
ret, err := f.Seek(0, io.SeekStart)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("f.Seek failed: %v", err)
|
||
|
}
|
||
|
fmt.Printf("** ret=%v\n", ret)
|
||
|
|
||
|
err = f.Truncate(0)
|
||
|
if err != nil {
|
||
|
fmt.Printf("******* %#v\n", err)
|
||
|
return nil, fmt.Errorf("f.Truncate failed: %v", err)
|
||
|
}
|
||
|
|
||
|
return lines, nil
|
||
|
}
|
||
|
|
||
|
func fileWatcherStart(directoryToCheck string, fileUpdated chan bool) {
|
||
|
watcher, err := fsnotify.NewWatcher()
|
||
|
if err != nil {
|
||
|
log.Println("Failed fsnotify.NewWatcher")
|
||
|
return
|
||
|
}
|
||
|
defer watcher.Close()
|
||
|
|
||
|
done := make(chan bool)
|
||
|
go func() {
|
||
|
//Give a true value to updated so it reads the file the first time.
|
||
|
fileUpdated <- true
|
||
|
for {
|
||
|
select {
|
||
|
case event := <-watcher.Events:
|
||
|
if event.Op&fsnotify.Write == fsnotify.Write {
|
||
|
log.Println("modified file:", event.Name)
|
||
|
//testing with an update chan to get updates
|
||
|
fileUpdated <- true
|
||
|
}
|
||
|
case err := <-watcher.Errors:
|
||
|
log.Println("error:", err)
|
||
|
}
|
||
|
}
|
||
|
}()
|
||
|
|
||
|
err = watcher.Add(directoryToCheck)
|
||
|
if err != nil {
|
||
|
log.Printf("error: watcher add: %v\n", err)
|
||
|
}
|
||
|
<-done
|
||
|
}
|