1515import java .net .URL ;
1616import java .time .LocalTime ;
1717import java .time .format .DateTimeFormatter ;
18+ import java .lang .management .ManagementFactory ;
1819
1920/**
2021 * Binds port 49155 and serves a plain-text status report on demand.
@@ -33,6 +34,8 @@ public class ConnectionStatusServer extends Thread
3334
3435 private ServerSocket serverSocket ;
3536
37+ private final long startTime = System .currentTimeMillis ();
38+
3639 public ConnectionStatusServer (String host , CurrentConnections watched , int watchedPort )
3740 {
3841 if (host == null || watched == null ) throw new SecurityException ("//bodi/connect" );
@@ -83,16 +86,25 @@ private void respond(Socket client)
8386 String geoLine = fetchGeo (remoteIp );
8487 String localTime = LocalTime .now ().format (DateTimeFormatter .ofPattern ("h:mm a" ));
8588
89+ long uptimeSecs = (System .currentTimeMillis () - startTime ) / 1000 ;
90+ String uptime = (uptimeSecs / 3600 ) + "hrs " + ((uptimeSecs % 3600 ) / 60 ) + "mins " + (uptimeSecs % 60 ) + "secs" ;
91+
92+ Runtime rt = Runtime .getRuntime ();
93+ long totalMB = rt .totalMemory () / (1024 * 1024 );
94+ long usedMB = (rt .totalMemory () - rt .freeMemory ()) / (1024 * 1024 );
95+
8696 String banner =
8797 "╔══════════════════════════════════════════════╗\n " +
8898 "║ National JDK Finance Engine v2811.1 v12.1 ║\n " +
8999 "╚══════════════════════════════════════════════╝\n " ;
90100
91101 String report = banner +
92- "Remote IP: " + remoteIp + "\n " +
93- "Geo Location: " + geoLine + "\n " +
102+ "Remote IP: " + remoteIp + "\n " +
103+ "Geo Location: " + geoLine + "\n " +
94104 "Local Server Time: " + localTime + "\n " +
95- "Current Connections: " + count + "\n " ;
105+ "Server Uptime: " + uptime + "\n " +
106+ "Total Memory: " + totalMB + "MB (used: " + usedMB + "MB)\n " +
107+ "Current Connections: " + count + "\n " ;
96108
97109 CommonRails .printSystemComponent (this , this .hashCode (),
98110 ". ConnectionStatusServer >> status query: port=" + watchedPort
@@ -118,22 +130,29 @@ private void respond(Socket client)
118130
119131 /**
120132 * Returns "City, Country" for the given IP, or "Unknown" on failure.
133+ * Private/loopback IPs fall back to the server's own public IP.
121134 */
122135 private String fetchGeo (String ip )
123136 {
124137 try
125138 {
126- HttpURLConnection conn = (HttpURLConnection ) new URL ("http://ip-api.com/line/" + ip + "?fields=city,country" ).openConnection ();
139+ boolean isPrivate = ip .startsWith ("127." ) || ip .startsWith ("10." )
140+ || ip .startsWith ("192.168." ) || ip .equals ("::1" ) || ip .equals ("0:0:0:0:0:0:0:1" );
141+
142+ String target = isPrivate ? "" : ip ;
143+
144+ HttpURLConnection conn = (HttpURLConnection ) new URL ("http://ip-api.com/line/" + target + "?fields=city,country" ).openConnection ();
127145 conn .setConnectTimeout (2000 );
128146 conn .setReadTimeout (2000 );
129147
130148 try (BufferedReader br = new BufferedReader (new InputStreamReader (conn .getInputStream ())))
131149 {
132150 String country = br .readLine ();
133- String city = br .readLine ();
151+ String city = br .readLine ();
134152 return (city != null ? city : "?" ) + ", " + (country != null ? country : "?" );
135153 }
136- } catch (Exception e )
154+ }
155+ catch (Exception e )
137156 {
138157 return "Unknown" ;
139158 }
0 commit comments