@@ -3,8 +3,8 @@ package main
33import (
44 "encoding/json"
55 "flag"
6- "io/ioutil "
7- "log"
6+ "fmt "
7+ "log/slog "
88 "os"
99 "os/exec"
1010 "time"
@@ -31,79 +31,95 @@ type ProcessDetails struct {
3131}
3232
3333func main () {
34- configFile := flag .String ("config" , "config.json" , "path to a configuration file" )
35- flag .Parse ()
34+ slog .SetLogLoggerLevel (slog .LevelInfo )
3635
37- config , err := loadConfigFile (* configFile )
36+ slog .Debug ("Loading flags" )
37+ configFile := * flag .String ("config" , "config.json" , "path to a configuration file" )
38+ verbose := * flag .Bool ("verbose" , false , "show all logs" )
39+
40+ if verbose {
41+ slog .SetLogLoggerLevel (slog .LevelDebug )
42+ }
43+
44+ config , err := loadConfigFile (configFile )
3845 if err != nil {
39- log . Fatalf ("Cannot load config file %s : %s" , * configFile , err )
46+ exitWithMsg ( fmt . Sprintf ("Cannot load config file %s : %s" , configFile , err ) )
4047 }
4148
42- runningProcs , err := startProcesses (config .Applications , true )
49+ runningProcs , err := startProcesses (config .Applications )
4350 if err != nil {
44- log . Fatalf ("Error launching apps : %s" , err )
51+ exitWithMsg ( fmt . Sprintf ("Error launching apps : %s" , err ) )
4552 }
4653
4754 time .Sleep (time .Duration (config .WaitCheck ) * time .Second )
4855 checkRunningProcesses (runningProcs )
4956
5057 time .Sleep (time .Duration (config .WaitExit ) * time .Second )
5158 killProcesses (runningProcs )
52- log . Printf ( "Done " )
59+ slog . Debug ( "Exiting " )
5360}
5461
55- func loadConfigFile (configFile string ) (ConfigFile , error ) {
56- file , err := ioutil .ReadFile (configFile )
62+ func loadConfigFile (configFile string ) (* ConfigFile , error ) {
63+ slog .Debug (fmt .Sprintf ("Loading config file %s" , configFile ))
64+ file , err := os .ReadFile (configFile )
5765 if err != nil {
58- log . Fatalf ( "Error opening config %s : %s" , configFile , err )
66+ return nil , err
5967 }
6068
6169 var jsonData ConfigFile
6270 err = json .Unmarshal ([]byte (file ), & jsonData )
6371
64- return jsonData , err
72+ return & jsonData , err
6573}
6674
67- func startProcesses (apps []AppConfig , checkCurrentProcesses bool ) (map [int ]ProcessDetails , error ) {
75+ func startProcesses (apps []AppConfig ) (map [int ]ProcessDetails , error ) {
6876 procs := make (map [int ]ProcessDetails )
6977
7078 runningProcs , err := ps .Processes ()
7179 if err != nil {
72- log . Fatalf ("Error listing processed (%s)" , err )
80+ exitWithMsg ( fmt . Sprintf ("Error listing processed (%s)" , err ) )
7381 }
7482
7583 for _ , app := range apps {
7684 newProc := ProcessDetails {path : app .Path , pid : - 1 , killOnExit : app .KillOnExit }
7785
7886 if app .UseExistingInstance {
87+ // check existing processes
7988 currentPid , err := findPidFromPath (app .Path , runningProcs )
8089 if err != nil {
81- log . Fatalf ( "Error checking running processes : %s" , err )
90+ slog . Warn ( fmt . Sprintf ( "Error checking running processes : %s" , err ) )
8291 }
8392 if currentPid != - 1 {
8493 newProc .pid = currentPid
85- log . Printf ( "Found running app %s [PID : %d]\n " , newProc .path , newProc .pid )
94+ slog . Info ( fmt . Sprintf ( "Found running app %s [PID : %d]\n " , newProc .path , newProc .pid ) )
8695 }
8796 }
8897
98+ // start app if not found in existing processes
8999 if newProc .pid == - 1 {
90100 cmd := exec .Command (app .Path )
91101 err := cmd .Start ()
92102 if err != nil {
93103 return nil , err
94104 }
95105 newProc .pid = cmd .Process .Pid
96- log . Printf ( "Starting apps %s [PID : %d]\n " , newProc .path , newProc .pid )
106+ slog . Info ( fmt . Sprintf ( "Starting apps %s [PID : %d]" , newProc .path , newProc .pid ) )
97107 }
98108 procs [newProc .pid ] = newProc
99109 }
100110
101111 return procs , nil
102112}
103113
114+ func exitWithMsg (msg string ) {
115+ slog .Error (msg )
116+ os .Exit (1 )
117+ }
118+
104119func findPidFromPath (path string , procs []ps.Process ) (int , error ) {
105120 for _ , proc := range procs {
106121 if procPath , _ := proc .Path (); procPath == path {
122+ slog .Debug (fmt .Sprintf ("Found running app %s with PID %d" , path , proc .Pid ()))
107123 return proc .Pid (), nil
108124 }
109125 }
@@ -124,33 +140,49 @@ func checkRunningProcesses(procs map[int]ProcessDetails) {
124140 go checkRunningProcess (pid , chanProcesses )
125141 }
126142 closedProcess := <- chanProcesses
127- log . Printf ( "Process closed %s [PID: %d]" , procs [closedProcess ].path , closedProcess )
143+ slog . Info ( fmt . Sprintf ( "Process closed %s [PID: %d]" , procs [closedProcess ].path , closedProcess ) )
128144}
129145
130146func checkRunningProcess (pid int , processes chan int ) {
131147 process , err := os .FindProcess (pid )
132148 if err != nil {
133149 processes <- pid
134150 }
151+
152+ // Wait the process to exit
153+ slog .Debug (fmt .Sprintf ("Waiting process [PID: %d] to exit" , pid ))
135154 processState , err := process .Wait ()
136155 if err != nil {
156+ slog .Warn (fmt .Sprintf ("Error while waiting process [PID: %d]" , pid ))
137157 processes <- pid
158+ return
138159 }
160+
139161 if processState .Exited () {
162+ slog .Info (fmt .Sprintf ("Process [PID: %d] exited with code %d" , pid , processState .ExitCode ()))
140163 processes <- pid
164+ return
141165 }
166+
167+ // something went wrong (?), let's assume process is over
168+ slog .Warn (fmt .Sprintf ("Process [PID: %d] exited but : %s " , pid , processState ))
169+ processes <- pid
142170}
143171
144172func killProcesses (procs map [int ]ProcessDetails ) {
173+ slog .Info ("Killing other apps" )
145174 for _ , proc := range procs {
146175 if proc .killOnExit {
176+ slog .Debug (fmt .Sprintf ("Killing process %s [PID: %d]" , proc .path , proc .pid ))
147177 procKilled , err := killProcess (proc .pid )
148178 if err != nil {
149- log . Printf ( "Error when killing process%s [PID: %d] : %s" , proc .path , proc .pid , err )
179+ slog . Warn ( fmt . Sprintf ( "Error when killing process %s [PID: %d] : %s" , proc .path , proc .pid , err ) )
150180 }
151181 if procKilled {
152- log . Printf ( "Killed process %s [PID: %d]" , proc .path , proc .pid )
182+ slog . Info ( fmt . Sprintf ( "Killed process %s [PID: %d]" , proc .path , proc .pid ) )
153183 }
184+ } else {
185+ slog .Debug (fmt .Sprintf ("Skipping process %s [PID: %d]" , proc .path , proc .pid ))
154186 }
155187 }
156188}
@@ -163,7 +195,7 @@ func killProcess(pid int) (bool, error) {
163195 process , _ := os .FindProcess (pid )
164196 err := process .Kill ()
165197 if err != nil {
166- log . Printf ( "Cannot kill process %d" , pid )
198+ slog . Warn ( fmt . Sprintf ( "Cannot kill process %d" , pid ) )
167199 return false , err
168200 }
169201 return true , nil
0 commit comments