package daemon import ( "fmt" "os" "os/exec" "path/filepath" "syscall" ) // GetLogFilePath returns the log file path for a given config file func GetLogFilePath(configPath string) (string, error) { logDir, err := getLogDir() if err != nil { return "", err } absConfigPath, err := filepath.Abs(configPath) if err != nil { return "", fmt.Errorf("failed to get absolute config path: %w", err) } basename := filepath.Base(configPath) name := filepath.Base(filepath.Dir(absConfigPath)) + "_" + basename return filepath.Join(logDir, name+".log"), nil } // Daemonize spawns the process as a daemon and returns func Daemonize(configPath string) error { // Get absolute path to the current executable executable, err := os.Executable() if err != nil { return fmt.Errorf("failed to get executable path: %w", err) } // Get absolute path to config absConfigPath, err := filepath.Abs(configPath) if err != nil { return fmt.Errorf("failed to get absolute config path: %w", err) } // Check if already running _, running, err := ReadPID(configPath) if err != nil { return fmt.Errorf("failed to check if instance is running: %w", err) } if running { return fmt.Errorf("instance is already running") } // Spawn the process in background with --daemon flag cmd := exec.Command(executable, "--daemon", absConfigPath) cmd.SysProcAttr = &syscall.SysProcAttr{ Setsid: true, // Create new session } // Redirect stdout/stderr to log file logDir, err := getLogDir() if err != nil { return fmt.Errorf("failed to get log directory: %w", err) } if err := os.MkdirAll(logDir, 0755); err != nil { return fmt.Errorf("failed to create log directory: %w", err) } basename := filepath.Base(configPath) name := filepath.Base(filepath.Dir(absConfigPath)) + "_" + basename logFile := filepath.Join(logDir, name+".log") f, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) if err != nil { return fmt.Errorf("failed to open log file: %w", err) } defer f.Close() cmd.Stdout = f cmd.Stderr = f if err := cmd.Start(); err != nil { return fmt.Errorf("failed to start daemon: %w", err) } fmt.Printf("Started KVS instance '%s' (PID will be written by daemon)\n", filepath.Base(configPath)) fmt.Printf("Logs: %s\n", logFile) return nil }