package main import ( "bufio" "fmt" "os" "strings" "time" "github.com/fsnotify/fsnotify" "github.com/getsentry/sentry-go" ) var debug bool func main() { // Check if debug mode is enabled if os.Getenv("DEBUG") == "true" { debug = true } // Get the DSN from the environment dsn := os.Getenv("GLITCHTIP_DSN") if dsn == "" { fmt.Fprintf(os.Stderr, "Error: GLITCHTIP_DSN environment variable is not set.\n") os.Exit(1) } // Initialize Sentry err := sentry.Init(sentry.ClientOptions{ Dsn: dsn, }) if err != nil { fmt.Fprintf(os.Stderr, "Error initializing GlitchTip: %s\n", err) os.Exit(1) } defer sentry.Flush(2 * time.Second) // Get the log files from the environment logFilesEnv := os.Getenv("LOG_FILES") if logFilesEnv == "" { fmt.Fprintf(os.Stderr, "Error: LOG_FILES environment variable is not set.\n") os.Exit(1) } logFiles := strings.Split(logFilesEnv, ",") // Create a new file watcher watcher, err := fsnotify.NewWatcher() if err != nil { fmt.Fprintf(os.Stderr, "Error creating watcher: %s\n", err) os.Exit(1) } defer watcher.Close() // Add log files to the watcher for _, logFile := listFiles(logFiles) { if debug { fmt.Printf("Adding file to watcher: %s\n", logFile) } err = watcher.Add(logFile) if err != nil { fmt.Fprintf(os.Stderr, "Error adding file to watcher: %s\n", err) os.Exit(1) } } // Watch for file changes go func() { for { select { case event, ok := <-watcher.Events: if !ok { return } if event.Op&fsnotify.Write == fsnotify.Write { if debug { fmt.Printf("File modified: %s\n", event.Name) } processLogFile(event.Name) } case err, ok := <-watcher.Errors: if !ok { return } fmt.Fprintf(os.Stderr, "Watcher error: %s\n", err) } } }() // Block forever select {} } func processLogFile(filePath string) { if debug { fmt.Printf("Processing log file: %s\n", filePath) } file, err := os.Open(filePath) if err != nil { fmt.Fprintf(os.Stderr, "Error opening file: %s\n", err) return } defer file.Close() scanner := bufio.NewScanner(file) for scanner.Scan() { line := scanner.Text() if debug { fmt.Printf("Read line: %s\n", line) } if strings.Contains(strings.ToLower(line), "error") { sendToSentry(line) } } if err := scanner.Err(); err != nil { fmt.Fprintf(os.Stderr, "Error reading file: %s\n", err) } } func sendToSentry(message string) { if debug { fmt.Printf("Sending message to GlitchTip: %s\n", message) } sentry.CaptureMessage(message) } // Utility function to list log files func listFiles(logFiles []string) []string { var validFiles []string for _, file := range logFiles { if _, err := os.Stat(file); err == nil { validFiles = append(validFiles, file) } else { fmt.Fprintf(os.Stderr, "Log file does not exist: %s\n", file) } } return validFiles }