AdvancedStartupLogger.java
· 4.9 KiB · Java
Ham
package com.example.startup;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.context.WebServerInitializedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import java.lang.management.ManagementFactory;
import java.net.DatagramSocket;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
@Slf4j
@Component
public class AdvancedStartupLogger implements ApplicationListener<WebServerInitializedEvent> {
private final Environment env;
private static final Instant START_TIME = Instant.now();
public AdvancedStartupLogger(Environment env) {
this.env = env;
}
@Override
public void onApplicationEvent(WebServerInitializedEvent event) {
int port = event.getWebServer().getPort();
String protocol = resolveProtocol();
String contextPath = resolveContextPath();
String appName = env.getProperty("spring.application.name", "application");
String profiles = Arrays.toString(env.getActiveProfiles());
String pid = getPid();
String javaVersion = System.getProperty("java.version");
String outboundIp = getOutboundIp();
boolean docker = isDocker();
boolean k8s = isK8s();
long startupMs = Duration.between(START_TIME, Instant.now()).toMillis();
List<String> allIps = getAllNetworkIps();
long maxHeapMb = Runtime.getRuntime().maxMemory() / 1024 / 1024;
String actuatorPath = env.getProperty("management.endpoints.web.base-path", "actuator");
log.info("\n" +
"================= 🚀 SERVICE STARTED =================\n" +
"App Name : {}\n" +
"PID : {}\n" +
"Profiles : {}\n" +
"Java Version : {}\n" +
"Startup Time : {} ms\n" +
"Max Heap : {} MB\n\n" +
"Access URLs:\n" +
"Local : {}://localhost:{}{}\n" +
"External : {}://{}:{}{}\n" +
"Actuator : {}://{}:{}{}{}\n\n" +
"All Network IPs : {}\n" +
"Docker : {}\n" +
"Kubernetes : {}\n" +
"=======================================================",
appName,
pid,
profiles,
javaVersion,
startupMs,
maxHeapMb,
protocol,
port,
contextPath,
protocol,
outboundIp,
port,
contextPath,
protocol,
outboundIp,
port,
contextPath,
actuatorPath,
allIps,
docker,
k8s
);
logStructuredJson(appName, port, outboundIp, startupMs);
}
private String resolveProtocol() {
return env.getProperty("server.ssl.key-store") != null ? "https" : "http";
}
private String resolveContextPath() {
return env.getProperty("server.servlet.context-path", "");
}
private String getPid() {
return ManagementFactory.getRuntimeMXBean().getName().split("@")[0];
}
private boolean isDocker() {
return new java.io.File("/.dockerenv").exists();
}
private boolean isK8s() {
return System.getenv("KUBERNETES_SERVICE_HOST") != null;
}
private String getOutboundIp() {
try (DatagramSocket socket = new DatagramSocket()) {
socket.connect(InetAddress.getByName("8.8.8.8"), 10002);
return socket.getLocalAddress().getHostAddress();
} catch (Exception e) {
return "Unknown";
}
}
private List<String> getAllNetworkIps() {
List<String> ips = new ArrayList<>();
try {
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface ni = interfaces.nextElement();
if (!ni.isUp() || ni.isLoopback()) continue;
Enumeration<InetAddress> addresses = ni.getInetAddresses();
while (addresses.hasMoreElements()) {
InetAddress addr = addresses.nextElement();
if (addr instanceof Inet4Address) {
ips.add(addr.getHostAddress());
}
}
}
} catch (Exception ignored) {
}
return ips;
}
private void logStructuredJson(String appName, int port, String ip, long startupMs) {
log.info("STARTUP_JSON: {{\"app\":\"{}\",\"port\":{},\"ip\":\"{}\",\"startupMs\":{}}}",
appName, port, ip, startupMs);
}
}
| 1 | package com.example.startup; |
| 2 | |
| 3 | import lombok.extern.slf4j.Slf4j; |
| 4 | import org.springframework.boot.web.context.WebServerInitializedEvent; |
| 5 | import org.springframework.context.ApplicationListener; |
| 6 | import org.springframework.core.env.Environment; |
| 7 | import org.springframework.stereotype.Component; |
| 8 | |
| 9 | import java.lang.management.ManagementFactory; |
| 10 | import java.net.DatagramSocket; |
| 11 | import java.net.Inet4Address; |
| 12 | import java.net.InetAddress; |
| 13 | import java.net.NetworkInterface; |
| 14 | import java.time.Duration; |
| 15 | import java.time.Instant; |
| 16 | import java.util.ArrayList; |
| 17 | import java.util.Arrays; |
| 18 | import java.util.Enumeration; |
| 19 | import java.util.List; |
| 20 | |
| 21 | @Slf4j |
| 22 | @Component |
| 23 | public class AdvancedStartupLogger implements ApplicationListener<WebServerInitializedEvent> { |
| 24 | |
| 25 | private final Environment env; |
| 26 | private static final Instant START_TIME = Instant.now(); |
| 27 | |
| 28 | public AdvancedStartupLogger(Environment env) { |
| 29 | this.env = env; |
| 30 | } |
| 31 | |
| 32 | @Override |
| 33 | public void onApplicationEvent(WebServerInitializedEvent event) { |
| 34 | |
| 35 | int port = event.getWebServer().getPort(); |
| 36 | String protocol = resolveProtocol(); |
| 37 | String contextPath = resolveContextPath(); |
| 38 | String appName = env.getProperty("spring.application.name", "application"); |
| 39 | String profiles = Arrays.toString(env.getActiveProfiles()); |
| 40 | String pid = getPid(); |
| 41 | String javaVersion = System.getProperty("java.version"); |
| 42 | String outboundIp = getOutboundIp(); |
| 43 | boolean docker = isDocker(); |
| 44 | boolean k8s = isK8s(); |
| 45 | |
| 46 | long startupMs = Duration.between(START_TIME, Instant.now()).toMillis(); |
| 47 | |
| 48 | List<String> allIps = getAllNetworkIps(); |
| 49 | long maxHeapMb = Runtime.getRuntime().maxMemory() / 1024 / 1024; |
| 50 | |
| 51 | String actuatorPath = env.getProperty("management.endpoints.web.base-path", "actuator"); |
| 52 | |
| 53 | log.info("\n" + |
| 54 | "================= 🚀 SERVICE STARTED =================\n" + |
| 55 | "App Name : {}\n" + |
| 56 | "PID : {}\n" + |
| 57 | "Profiles : {}\n" + |
| 58 | "Java Version : {}\n" + |
| 59 | "Startup Time : {} ms\n" + |
| 60 | "Max Heap : {} MB\n\n" + |
| 61 | "Access URLs:\n" + |
| 62 | "Local : {}://localhost:{}{}\n" + |
| 63 | "External : {}://{}:{}{}\n" + |
| 64 | "Actuator : {}://{}:{}{}{}\n\n" + |
| 65 | "All Network IPs : {}\n" + |
| 66 | "Docker : {}\n" + |
| 67 | "Kubernetes : {}\n" + |
| 68 | "=======================================================", |
| 69 | appName, |
| 70 | pid, |
| 71 | profiles, |
| 72 | javaVersion, |
| 73 | startupMs, |
| 74 | maxHeapMb, |
| 75 | protocol, |
| 76 | port, |
| 77 | contextPath, |
| 78 | protocol, |
| 79 | outboundIp, |
| 80 | port, |
| 81 | contextPath, |
| 82 | protocol, |
| 83 | outboundIp, |
| 84 | port, |
| 85 | contextPath, |
| 86 | actuatorPath, |
| 87 | allIps, |
| 88 | docker, |
| 89 | k8s |
| 90 | ); |
| 91 | |
| 92 | logStructuredJson(appName, port, outboundIp, startupMs); |
| 93 | } |
| 94 | |
| 95 | private String resolveProtocol() { |
| 96 | return env.getProperty("server.ssl.key-store") != null ? "https" : "http"; |
| 97 | } |
| 98 | |
| 99 | private String resolveContextPath() { |
| 100 | return env.getProperty("server.servlet.context-path", ""); |
| 101 | } |
| 102 | |
| 103 | private String getPid() { |
| 104 | return ManagementFactory.getRuntimeMXBean().getName().split("@")[0]; |
| 105 | } |
| 106 | |
| 107 | private boolean isDocker() { |
| 108 | return new java.io.File("/.dockerenv").exists(); |
| 109 | } |
| 110 | |
| 111 | private boolean isK8s() { |
| 112 | return System.getenv("KUBERNETES_SERVICE_HOST") != null; |
| 113 | } |
| 114 | |
| 115 | private String getOutboundIp() { |
| 116 | try (DatagramSocket socket = new DatagramSocket()) { |
| 117 | socket.connect(InetAddress.getByName("8.8.8.8"), 10002); |
| 118 | return socket.getLocalAddress().getHostAddress(); |
| 119 | } catch (Exception e) { |
| 120 | return "Unknown"; |
| 121 | } |
| 122 | } |
| 123 | |
| 124 | private List<String> getAllNetworkIps() { |
| 125 | List<String> ips = new ArrayList<>(); |
| 126 | try { |
| 127 | Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); |
| 128 | while (interfaces.hasMoreElements()) { |
| 129 | NetworkInterface ni = interfaces.nextElement(); |
| 130 | if (!ni.isUp() || ni.isLoopback()) continue; |
| 131 | |
| 132 | Enumeration<InetAddress> addresses = ni.getInetAddresses(); |
| 133 | while (addresses.hasMoreElements()) { |
| 134 | InetAddress addr = addresses.nextElement(); |
| 135 | if (addr instanceof Inet4Address) { |
| 136 | ips.add(addr.getHostAddress()); |
| 137 | } |
| 138 | } |
| 139 | } |
| 140 | } catch (Exception ignored) { |
| 141 | } |
| 142 | return ips; |
| 143 | } |
| 144 | |
| 145 | private void logStructuredJson(String appName, int port, String ip, long startupMs) { |
| 146 | log.info("STARTUP_JSON: {{\"app\":\"{}\",\"port\":{},\"ip\":\"{}\",\"startupMs\":{}}}", |
| 147 | appName, port, ip, startupMs); |
| 148 | } |
| 149 | } |
| 150 |