diff --git a/main.go b/main.go index 7e91d92..9bf96b9 100644 --- a/main.go +++ b/main.go @@ -5,6 +5,7 @@ import ( "fmt" "log" "os" + "os/exec" "os/signal" "sync" "syscall" @@ -29,6 +30,19 @@ func main() { switch command { case "run": + // Check for daemon flag + isDaemon := false + for _, arg := range os.Args { + if arg == "--daemon" { + isDaemon = true + break + } + } + + if isDaemon { + startDaemon() + return + } runEngine(cfg) case "recover": @@ -61,14 +75,45 @@ func main() { } func printUsage() { - fmt.Println("Usage: engine [command]") + fmt.Println("Usage: engine [command] [--daemon]") fmt.Println("\nCommands:") fmt.Println(" run Start the WebSocket ingestor and processing engine") + fmt.Println(" Use --daemon to run in background and log to engine.log") fmt.Println(" recover Run startup recovery to migrate stale ticks") fmt.Println(" maintain Run a single maintenance cycle (cleanup/retention)") fmt.Println(" help Show this help message") } +func startDaemon() { + // Prepare arguments for the child process (remove --daemon) + args := []string{} + for _, arg := range os.Args[1:] { + if arg != "--daemon" { + args = append(args, arg) + } + } + + // Prepare the command + cmd := exec.Command(os.Args[0], args...) + + // Open log file for output redirection + logFile, err := os.OpenFile("engine.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) + if err != nil { + log.Fatalf("Failed to open log file: %v", err) + } + + cmd.Stdout = logFile + cmd.Stderr = logFile + + // Start the process + if err := cmd.Start(); err != nil { + log.Fatalf("Failed to start daemon: %v", err) + } + + fmt.Printf("Engine started in background (PID: %d). Logs: engine.log\n", cmd.Process.Pid) + os.Exit(0) +} + func runEngine(cfg Config) { log.Println("=== Bybit BTC/USDT Tick Ingest Engine ===") log.Printf("Config: symbol=%s, hot_retention=%dh, feature_retention=%dd",