/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ package main import ( "context" "errors" "flag" "fmt" "io" "log" "os" "os/signal" "regexp" "time" ) // -3 silent // -2 fatal // -1 error // // 0 warn // 1 info // 2 debug var ( LogLevel int Version, Build string ) func debug(fmt string, msg ...any) { if LogLevel < 2 { return } fmt = "debug: " + fmt if len(msg) == 0 { log.Printf(fmt) return } log.Printf(fmt, msg...) } var Options = struct { pattern *regexp.Regexp command string jumpToEnd, matchOnce, printNonmatching, verbose, debug bool }{} func main() { ctx, cancel := context.WithCancel(context.Background()) go func() { sig := make(chan os.Signal, 1) // catch signals signal.Notify(sig, os.Interrupt, os.Kill) for { switch <-sig { case os.Interrupt, os.Kill: log.Printf("Caught SIGINT/SIGTERM.") cancel() } } }() handlePatternFlag := func(p string) error { var err error Options.pattern, err = regexp.Compile(p) return err } flags := flag.NewFlagSet("watchlogs", flag.ExitOnError) flags.SetOutput(os.Stderr) flags.Func("pattern", "process lines matching pattern", handlePatternFlag) flags.Func("p", "process lines matching pattern", handlePatternFlag) flags.BoolVar(&Options.jumpToEnd, "jump", false, "jump to end of file before processing") flags.BoolVar(&Options.jumpToEnd, "j", false, "jump to end of file before processing") flags.BoolVar(&Options.matchOnce, "once", false, "stop after first matching line is processed") flags.BoolVar(&Options.matchOnce, "1", false, "stop after first matching line is processed") flags.BoolVar(&Options.printNonmatching, "n", false, "print all lines, not just matching ones") flags.BoolVar(&Options.verbose, "v", false, "increase verbosity") flags.BoolVar(&Options.debug, "debug", false, "print debugging information") flags.StringVar(&Options.command, "command", "", "execute command on match, passing the matched line as input") flags.Parse(os.Args[1:]) logPath := flags.Arg(0) if len(flags.Args()) == 0 { fmt.Printf("%s %s\n", Version, Build) fmt.Printf("usage: %s [