@@ -102,8 +102,8 @@ func RunApplication(ctx context.Context, args []string) int {
102102 }
103103 }
104104
105- logging .Info ("Starting %s v%s (+%s)" , version .ProjectName , version .ProjectVersion , version .ProjectGitHubURL )
106- logging .Info ("User-Agent: %s" , version .UserAgent )
105+ logging .Notice ("Starting %s v%s (+%s)" , version .ProjectName , version .ProjectVersion , version .ProjectGitHubURL )
106+ logging .Notice ("User-Agent: %s" , version .UserAgent )
107107
108108 ctx , cancel := context .WithCancel (ctx )
109109 defer cancel ()
@@ -142,31 +142,31 @@ func RunApplication(ctx context.Context, args []string) int {
142142 }
143143
144144 // LOG_LEVEL was applied earlier so subsequent logs respect the selected level.
145- logging .Info ("Configuration loaded. WebPort: %d, MaxCache: %d, DataDir: %s" , cfg .WebPort , cfg .MaxCache , cfg .DataDir )
145+ logging .Notice ("Configuration loaded. WebPort: %d, MaxCache: %d, DataDir: %s" , cfg .WebPort , cfg .MaxCache , cfg .DataDir )
146146
147147 // Debug configuration details
148148 logging .Debug ("CLUSTERS JSON: '%s'" , cfg .RawClustersJSON )
149149 logging .Debug ("Global Callsign: '%s'" , cfg .Callsign )
150150
151151 if len (cfg .Clusters ) > 0 {
152- logging .Info ("DX Clusters configured: %d" , len (cfg .Clusters ))
152+ logging .Notice ("DX Clusters configured: %d" , len (cfg .Clusters ))
153153 for i , cluster := range cfg .Clusters {
154154 sotaFlag := "no"
155155 if cluster .SOTA {
156156 sotaFlag = "yes"
157157 }
158- logging .Info (" Cluster %d: %s:%s callsign=%s sota=%s" , i + 1 , cluster .Host , cluster .Port , cluster .Callsign , sotaFlag )
158+ logging .Notice (" Cluster %d: %s:%s callsign=%s sota=%s" , i + 1 , cluster .Host , cluster .Port , cluster .Callsign , sotaFlag )
159159 }
160160 } else {
161161 logging .Warn ("No DX Clusters configured." )
162162 }
163163 if cfg .EnablePOTA {
164- logging .Info ("POTA integration enabled. Polling interval: %s" , cfg .POTAPollInterval )
164+ logging .Notice ("POTA integration enabled. Polling interval: %s" , cfg .POTAPollInterval )
165165 } else {
166166 logging .Info ("POTA integration disabled." )
167167 }
168168 if cfg .Redis .Enabled {
169- logging .Info ("Redis cache enabled. Host: %s:%s, DB: %d, TLS: %t" , cfg .Redis .Host , cfg .Redis .Port , cfg .Redis .DB , cfg .Redis .UseTLS )
169+ logging .Notice ("Redis cache enabled. Host: %s:%s, DB: %d, TLS: %t" , cfg .Redis .Host , cfg .Redis .Port , cfg .Redis .DB , cfg .Redis .UseTLS )
170170 } else {
171171 logging .Info ("Redis cache disabled (using in-memory)." )
172172 }
@@ -191,7 +191,7 @@ func RunApplication(ctx context.Context, args []string) int {
191191 log .Fatalf ("FATAL: Failed to initialize Redis client: %v\n " , err )
192192 }
193193 defer rdb .Close ()
194- logging .Info ("Redis client initialized and connected." )
194+ logging .Notice ("Redis client initialized and connected." )
195195 }
196196
197197 // --- 3. Initialize LoTW Client ---
@@ -207,7 +207,7 @@ func RunApplication(ctx context.Context, args []string) int {
207207 }
208208
209209 // Perform initial synchronous LoTW data check and download BEFORE starting spot sources
210- logging .Info ("Checking LoTW data status..." )
210+ logging .Notice ("Checking LoTW data status..." )
211211 lastLoTWUpdate , err := lotwClient .GetLastDownloadTime (ctx )
212212 if err != nil {
213213 logging .Warn ("Failed to check LoTW last update time: %v" , err )
@@ -244,7 +244,7 @@ func RunApplication(ctx context.Context, args []string) int {
244244 }
245245
246246 // Perform initial synchronous DXCC data check and download BEFORE starting spot sources
247- logging .Info ("Checking DXCC data status..." )
247+ logging .Notice ("Checking DXCC data status..." )
248248 lastDXCCUpdate , err := dxccClient .GetLastDownloadTime (ctx )
249249 if err != nil {
250250 logging .Warn ("Failed to check DXCC last update time: %v" , err )
@@ -253,9 +253,9 @@ func RunApplication(ctx context.Context, args []string) int {
253253 if needsDXCCUpdate {
254254 logging .Info ("DXCC data needs update, downloading now (this may take a moment)..." )
255255 dxccClient .FetchAndStoreData (ctx )
256- logging .Info ("DXCC data downloaded and loaded successfully." )
256+ logging .Notice ("DXCC data downloaded and loaded successfully." )
257257 } else {
258- logging .Info ("DXCC data is up to date (last updated: %s)" , lastDXCCUpdate .Format (time .RFC3339 ))
258+ logging .Notice ("DXCC data is up to date (last updated: %s)" , lastDXCCUpdate .Format (time .RFC3339 ))
259259 // Load in-memory maps from database NOW to ensure they're ready before spots arrive
260260 if err := dxccClient .LoadMapsFromDB (ctx ); err != nil {
261261 log .Fatalf ("FATAL: Failed to load DXCC maps from database: %v\n " , err )
@@ -264,7 +264,7 @@ func RunApplication(ctx context.Context, args []string) int {
264264 if len (dxccClient .PrefixesMap ) == 0 {
265265 logging .Warn ("DXCC database is empty despite recent update timestamp. Forcing download now..." )
266266 dxccClient .FetchAndStoreData (ctx )
267- logging .Info ("DXCC data downloaded and loaded successfully after empty database detection." )
267+ logging .Notice ("DXCC data downloaded and loaded successfully after empty database detection." )
268268 }
269269 }
270270
@@ -425,7 +425,13 @@ func RunApplication(ctx context.Context, args []string) int {
425425 select {
426426 case err := <- c .ErrorChan :
427427 if err != nil {
428- logging .Error ("from DX Cluster: %v" , err )
428+ // Suppress "use of closed network connection" during graceful shutdown
429+ // This is expected when Close() is called while read loop is active
430+ if strings .Contains (err .Error (), "use of closed network connection" ) {
431+ logging .Debug ("DX Cluster connection closed (expected during shutdown): %v" , err )
432+ } else {
433+ logging .Error ("from DX Cluster: %v" , err )
434+ }
429435 }
430436 case msg := <- c .MessageChan :
431437 _ = msg // Ignore generic messages for now
0 commit comments