diff --git a/cmd/smart-shutdown/main.go b/cmd/smart-shutdown/main.go index a8d7cf6..9e4de93 100644 --- a/cmd/smart-shutdown/main.go +++ b/cmd/smart-shutdown/main.go @@ -18,6 +18,7 @@ import ( ) var AppVersion = "dev" +var verbose bool func main() { if err := logger.InitLogger(); err != nil { @@ -42,6 +43,11 @@ func main() { var rootCommand = &cobra.Command{ Use: "smart-shutdown", Short: "智能网络状态检测与自动关机后台服务", + PersistentPreRun: func(cmd *cobra.Command, args []string) { + if verbose { + logger.EnableDebug() + } + }, Run: func(cmd *cobra.Command, args []string) { if showVersion { fmt.Printf("========== Smart Network Shutdown Monitor ==========\n") @@ -59,6 +65,7 @@ func main() { rootCommand.CompletionOptions.DisableDefaultCmd = true rootCommand.Flags().BoolVarP(&showVersion, "version", "V", false, "输出当前二进制内核版本并联网拉取发布树状态") + rootCommand.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "打印底层部署及环境追溯 Debug 信息") cmds := []*cobra.Command{ { @@ -69,7 +76,7 @@ func main() { currentExe, _ := os.Executable() if !strings.EqualFold(filepath.Clean(currentExe), filepath.Clean(targetExe)) { - logger.Info("预备自动配置系统级全局环境,本体克隆下放目录: %s", targetExe) + logger.Debug("检测到跨域部署: 待本体克隆存放底层根目录: %s", targetExe) if err := os.MkdirAll(targetDir, 0755); err != nil { logger.Fail("创建系统目录核心区路径溃败 (请核查最高系统权限身份执行需求): %v", err) return @@ -87,7 +94,7 @@ func main() { if err != nil { logger.Warn("改写操作系统的环境变量集合遭受阻拦: %v", err) } else { - logger.Info("执行路径已完备挂载进 Windows Global PATH 域内,用户可通过全局指引调取 smart-shutdown。") + logger.Debug("成功挂载底层环境变量: Windows Machine Path 追加了 %s 指引。", targetDir) } } } @@ -112,13 +119,14 @@ func main() { if !strings.EqualFold(filepath.Clean(currentExe), filepath.Clean(targetExe)) { if _, err := os.Stat(targetExe); err == nil { - logger.Info("查明曾执行过部署注入逻辑,现在开始彻底摘毁并清理目录: %s", targetExe) + logger.Debug("查明环境曾记录过全局部署逻辑,现已启动强力移除可执行源地址流: %s", targetExe) os.Remove(targetExe) if runtime.GOOS == "windows" { os.Remove(targetDir) envClearCmd := fmt.Sprintf(`$p=[Environment]::GetEnvironmentVariable("Path","Machine");$np=($p -split ';' | Where-Object {$_ -ne "%s" -and $_ -ne ""}) -join ';';[Environment]::SetEnvironmentVariable("Path",$np,"Machine")`, targetDir) exec.Command("powershell", "-Command", envClearCmd).Run() + logger.Debug("环境变量系统清理:Windows Global Path 中的指向挂载项业已剥除卸载完成。") } } } @@ -162,7 +170,7 @@ func main() { service.Control(svc, "start") fmt.Println("============ 热更新无感流闭环执行彻底成功! ============") } else { - fmt.Println("============ 热更核心接替执行完毕!============\n(注: 您的当前终端并不作为真正的宿存执行体。如目前您另行开启了 CMD 窗格在死循环执行此包前台,请人工叉掉那个窗口使其重新载入新版本!)") + fmt.Println("============ 热更核心接替执行完毕!============\n(注: 您的当前终端并不作为真正的宿存执行体。\n如目前您另行开启了 CMD 窗格在死循环执行此包前台,请人工叉掉那个窗口使其重新载入新版本!)") } }, }, diff --git a/pkg/daemon/service.go b/pkg/daemon/service.go index d6befee..392e179 100644 --- a/pkg/daemon/service.go +++ b/pkg/daemon/service.go @@ -3,11 +3,10 @@ package daemon import ( "context" + "github.com/kardianos/service" "smart-shutdown/pkg/config" "smart-shutdown/pkg/logger" "smart-shutdown/pkg/monitor" - - "github.com/kardianos/service" ) type program struct { @@ -41,13 +40,17 @@ func (p *program) Stop(s service.Service) error { return nil } -func GetService(cfg *config.Config) (service.Service, error) { +func GetService(cfg *config.Config, execPath ...string) (service.Service, error) { svcConfig := &service.Config{ Name: "SmartNetworkMonitor", DisplayName: "Smart Network Shutdown Monitor", Description: "A reliable daemon that periodically monitors network states and triggers node suspension logically.", } + if len(execPath) > 0 && execPath[0] != "" { + svcConfig.Executable = execPath[0] + } + prg := &program{ cfg: cfg, } diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go index 6ef5106..a6b14f5 100644 --- a/pkg/logger/logger.go +++ b/pkg/logger/logger.go @@ -12,6 +12,7 @@ import ( ) var fileLogger *lumberjack.Logger +var debugEnabled bool func InitLogger() error { logDir := config.GetLogDir() @@ -33,6 +34,10 @@ func InitLogger() error { return nil } +func EnableDebug() { + debugEnabled = true +} + func writeLog(level, plainPrefix, format string, v ...interface{}) { msg := fmt.Sprintf(format, v...) timestamp := time.Now().Format("2006/01/02 15:04:05") @@ -63,11 +68,19 @@ func getPrefixColor(level string) func(a ...interface{}) string { return color.New(color.FgRed).SprintFunc() case "CRITICAL": return color.New(color.FgHiRed).SprintFunc() + case "DEBUG": + return color.New(color.FgCyan).SprintFunc() default: return color.New(color.Reset).SprintFunc() } } +func Debug(format string, v ...interface{}) { + if debugEnabled { + writeLog("DEBUG", "[DEBUG]", format, v...) + } +} + func Info(format string, v ...interface{}) { writeLog("INFO", "[INFO]", format, v...) }