Last active
August 29, 2015 14:13
-
-
Save SteveBate/54f82fe3ea171223450f to your computer and use it in GitHub Desktop.
Sample of monitoring a log file for changes and filtering out lines that describe an error
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bufio" | |
"flag" | |
"fmt" | |
"log" | |
"os" | |
"regexp" | |
"strings" | |
"time" | |
"gopkg.in/fsnotify.v1" | |
) | |
var ( | |
fileToWatch string | |
appName string | |
keyword string | |
interval int | |
) | |
func init() { | |
flag.StringVar(&fileToWatch, "file", "", "the path and name of the file to be monitored for changes") | |
flag.StringVar(&appName, "appname", "", "the name of the application being monitored") | |
flag.StringVar(&keyword, "keyword", "EXCEPTION", "the word to look for that indicates an error line") | |
flag.IntVar(&interval, "interval", 20, "time to wait in seconds before parsing file contents") | |
flag.Parse() | |
} | |
func main() { | |
dateRegex := regexp.MustCompile(`^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}`) | |
keywordRegex := regexp.MustCompile(keyword + ` - (.*)`) | |
watcher, err := fsnotify.NewWatcher() | |
if err != nil { | |
log.Fatal(err) | |
} | |
defer watcher.Close() | |
done := make(chan bool) | |
analyze := make(chan bool) | |
// monitor for file changes or errors | |
go func() { | |
for { | |
select { | |
case event := <-watcher.Events: | |
if event.Op&fsnotify.Write == fsnotify.Write { | |
analyze <- true | |
} | |
case err := <-watcher.Errors: | |
fmt.Println("error", err) | |
} | |
} | |
}() | |
// parse file when change detected every <interval> seconds | |
go func() { | |
lineNo := 0 | |
on := true | |
for { | |
select { | |
case <-time.After(time.Duration(interval) * time.Second): | |
fmt.Println("checking...") | |
select { | |
case <-analyze: | |
go func() { | |
if on { | |
f, err := os.Open(fileToWatch) | |
if err != nil { | |
log.Fatal(err) | |
} | |
defer f.Close() | |
reader := bufio.NewReader(f) | |
scanner := bufio.NewScanner(reader) | |
current := 0 | |
for scanner.Scan() { | |
current += 1 | |
if current > lineNo { | |
str := scanner.Text() | |
if strings.Contains(str, keyword) { | |
date := dateRegex.FindString(str) | |
groups := keywordRegex.FindStringSubmatch(str) | |
if len(groups) == 2 { | |
// insert into db | |
fmt.Printf("App: %s - Date: %s - Error: %s\n", appName, date, groups[1]) | |
} | |
} | |
} | |
} | |
lineNo = current | |
} | |
on = !on | |
}() | |
default: | |
// nothing to do here but stop the routine from blocking | |
} | |
} | |
} | |
}() | |
err = watcher.Add(fileToWatch) | |
if err != nil { | |
log.Fatal(err) | |
} | |
fmt.Println("monitoring...") | |
<-done | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment