大体思路如下,想要获取启动时处理器数量、jvm 相关信息,操作系统信息、运行机器信息
运行机器信息
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.invoke.MethodHandles;
/**
* 机器工具类
*/
public abstract class ServerUtils {
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
/**
* 获取可用处理器数量
*
* @return
*/
public static int getAvailableProcessors() {
return Runtime.getRuntime().availableProcessors();
}
public static void printAvailableProcessors() {
logger.info("processors={}", Runtime.getRuntime().availableProcessors());
}
}
系统信息
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.invoke.MethodHandles;
/**
* 系统信息工具类
*
* @author Rike
* @date 2023/6/28
*/
public abstract class SystemUtils {
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
public static String getOsName() {
return System.getProperty("os.name");
}
public static void printOsName() {
logger.info("os.name={}", System.getProperty("os.name"));
}
public static boolean isWindows() {
return getOsName().startsWith("Windows");
}
public static boolean isLinux() {
return getOsName().startsWith("Linux");
}
public static boolean isWindows(String osName) {
return osName.startsWith("Windows");
}
public static boolean isLinux(String osName) {
return osName.startsWith("Linux");
}
}
通过 System.getProperty() 实现。
jvm 信息
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.invoke.MethodHandles;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
/**
* jvm 信息工具类
*/
public abstract class JvmUtils {
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
/**
* 打印 jvm 信息
*/
public static void printJvmInfo() {
RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
logger.info("jvm name={}", runtimeMXBean.getName());
logger.info("class={}", runtimeMXBean.getClass());
logger.info("java.class.path={}", runtimeMXBean.getClassPath());
logger.info("java.library.path={}", runtimeMXBean.getLibraryPath());
logger.info("bootClassPath={}", runtimeMXBean.getBootClassPath());
logger.info("java.vm.vendor={}", runtimeMXBean.getVmVendor());
logger.info("java.vm.name={}", runtimeMXBean.getVmName());
logger.info("java.vm.version={}", runtimeMXBean.getVmVersion());
logger.info("java.vm.specification.name={}", runtimeMXBean.getSpecName());
logger.info("java.vm.specification.vendor={}", runtimeMXBean.getSpecVendor());
logger.info("java.vm.specification.version={}", runtimeMXBean.getSpecVersion());
logger.info("java.version={}", System.getProperty("java.version"));
logger.info("java.runtime.version={}", System.getProperty("java.runtime.version"));
logger.info("java.class.version={}", System.getProperty("java.class.version"));
logger.info("inputArguments={}", runtimeMXBean.getInputArguments());
logger.info("managementSpecVersion={}", runtimeMXBean.getManagementSpecVersion());
logger.info("startTime={}", runtimeMXBean.getStartTime());
logger.info("uptime={}", runtimeMXBean.getUptime());
/*logger.info("+++++++++++++++++++++++++++++++++++++++");
runtimeMXBean.getSystemProperties().entrySet().parallelStream().forEach(entry -> {
System.out.println(entry.getKey() + "=" + entry.getValue());
});
logger.info("+++++++++++++++++++++++++++++++++++++++");*/
}
}
通过 ManagementFactory 获取 RuntimeMXBean 对象获取相关信息。
spring 环境信息
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.stereotype.Component;
import java.lang.invoke.MethodHandles;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* spring Environment 信息获取工具类
*/
@Component
public class SpringEnvironmentUtils implements ApplicationContextAware {
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private static ConfigurableEnvironment environment = null;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
environment = (ConfigurableEnvironment) applicationContext.getBean(ConfigurableApplicationContext.ENVIRONMENT_BEAN_NAME);
}
public static void printPropertyValue(String property) {
logger.info("[{}]={}", property, environment.getProperty(property));
}
public static String getPropertyValue(String property) {
return environment.getProperty(property);
}
/**
* 打印所有的 Environment 信息
*/
public static void printAllEnvironmentInfo() {
// printSystemEnvironment();
// printSystemProperties();
printPropertySources();
printProfiles();
}
public static void printSystemEnvironment() {
logger.info("+++++++++++++++++++++++++++++++++++++++");
logger.info("print system environment begin");
logger.info("+++++++++++++++++++++++++++++++++++++++");
environment.getSystemEnvironment().entrySet().parallelStream().forEach(entry -> {
// System.out.println(entry.getKey() + "=" + entry.getValue());
logger.info("{}={}", entry.getKey(), entry.getValue());
});
logger.info("+++++++++++++++++++++++++++++++++++++++");
logger.info("print system environment end");
logger.info("+++++++++++++++++++++++++++++++++++++++");
Map<String, String> map = System.getenv();
map.entrySet().stream().forEach(entry -> {
// System.out.println(entry.getKey() + "=" + entry.getValue());
logger.info("{}={}", entry.getKey(), entry.getValue());
});
}
public static void printSystemProperties() {
logger.info("+++++++++++++++++++++++++++++++++++++++");
logger.info("print system properties begin");
logger.info("+++++++++++++++++++++++++++++++++++++++");
environment.getSystemProperties().entrySet().parallelStream().forEach(entry -> {
// System.out.println(entry.getKey() + "=" + entry.getValue());
logger.info("{}={}", entry.getKey(), entry.getValue());
});
logger.info("+++++++++++++++++++++++++++++++++++++++");
logger.info("print system properties end");
logger.info("+++++++++++++++++++++++++++++++++++++++");
}
public static void printPropertySources() {
logger.info("+++++++++++++++++++++++++++++++++++++++");
logger.info("print property sources begin");
logger.info("+++++++++++++++++++++++++++++++++++++++");
// 筛选继承 EnumerablePropertySource 的类和实现 Map 的类
List<PropertySource<?>> list = environment.getPropertySources().stream().filter(ps -> (ps instanceof EnumerablePropertySource && ps.getSource() instanceof Map)).collect(Collectors.toList());
list.stream().forEach(ps -> {
String name = ps.getName();
logger.info("[{}] include property and value begin", name);
Map source = (Map) ps.getSource();
StringBuffer stringBuffer = new StringBuffer();
int size = source.entrySet().size();
// 记录当前下标
int index = -1;
for (Object entry : source.entrySet()) {
index++;
Map.Entry temp = (Map.Entry) entry;
// System.out.println(temp.getKey() + "="+ temp.getValue());
// logger.info("{}={}", temp.getKey(), temp.getValue());
// 将参数进行拼接方便日志打印
stringBuffer.append(temp.getKey()).append("=").append(temp.getValue());
/**
* 换行符打印的情况
*
* 总数量大于1
*
* 下标小于总数减1
*
*/
if (size > 1 && index < size -1) {
stringBuffer.append("\n");
}
}
// 拼接的字符串不为空时打印
if (stringBuffer.length() > 0) {
logger.info("{}", stringBuffer);
}
logger.info("[{}] include property and value end", name);
});
logger.info("+++++++++++++++++++++++++++++++++++++++");
logger.info("print property sources end");
logger.info("+++++++++++++++++++++++++++++++++++++++");
}
public static void printProfiles() {
logger.info("+++++++++++++++++++++++++++++++++++++++");
logger.info("print profiles begin");
logger.info("+++++++++++++++++++++++++++++++++++++++");
String[] defaultProfiles = environment.getDefaultProfiles();
logger.info("defaultProfiles={}", defaultProfiles);
String[] activeProfiles = environment.getActiveProfiles();
logger.info("activeProfiles={}", activeProfiles);
logger.info("+++++++++++++++++++++++++++++++++++++++");
logger.info("print profiles end");
logger.info("+++++++++++++++++++++++++++++++++++++++");
}
}
借助于 ApplicationContext 获取 ConfigurableEnvironment 对象,进而获取 System.getProperty() 和 System.getenv() 相关信息。
整合
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
/**
* 启动信息
*/
@Component
public class StartInfo implements InitializingBean, Ordered {
@Override
public void afterPropertiesSet() throws Exception {
SpringEnvironmentUtils.printPropertyValue("spring.cloud.nacos.server-addr");
ServerUtils.printAvailableProcessors();
SystemUtils.printOsName();
JvmUtils.printJvmInfo();
SpringEnvironmentUtils.printAllEnvironmentInfo();
}
@Override
public int getOrder() {
return LOWEST_PRECEDENCE;
}
}
创建一个类实现 InitializingBean 接口,添加 @Component 注解,在 spring ioc 容器启动时执行其中的逻辑,对代码无侵入性,无需修改其他代码即可实现最终的功能。
可以参照 zookeeper 中源码
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.9.1</version>
</dependency>
package org.apache.zookeeper;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
/**
* Provide insight into the runtime environment.
*
*/
public class Environment {
public static final String JAAS_CONF_KEY = "java.security.auth.login.config";
public static class Entry {
private String k;
private String v;
public Entry(String k, String v) {
this.k = k;
this.v = v;
}
public String getKey() {
return k;
}
public String getValue() {
return v;
}
@Override
public String toString() {
return k + "=" + v;
}
}
private static void put(List<Entry> l, String k, String v) {
l.add(new Entry(k, v));
}
public static List<Entry> list() {
List<Entry> l = new ArrayList<>();
put(l, "zookeeper.version", Version.getFullVersion());
try {
put(l, "host.name", InetAddress.getLocalHost().getCanonicalHostName());
} catch (UnknownHostException e) {
put(l, "host.name", "<NA>");
}
put(l, "java.version", System.getProperty("java.version", "<NA>"));
put(l, "java.vendor", System.getProperty("java.vendor", "<NA>"));
put(l, "java.home", System.getProperty("java.home", "<NA>"));
put(l, "java.class.path", System.getProperty("java.class.path", "<NA>"));
put(l, "java.library.path", System.getProperty("java.library.path", "<NA>"));
put(l, "java.io.tmpdir", System.getProperty("java.io.tmpdir", "<NA>"));
put(l, "java.compiler", System.getProperty("java.compiler", "<NA>"));
put(l, "os.name", System.getProperty("os.name", "<NA>"));
put(l, "os.arch", System.getProperty("os.arch", "<NA>"));
put(l, "os.version", System.getProperty("os.version", "<NA>"));
put(l, "user.name", System.getProperty("user.name", "<NA>"));
put(l, "user.home", System.getProperty("user.home", "<NA>"));
put(l, "user.dir", System.getProperty("user.dir", "<NA>"));
// Get memory information.
Runtime runtime = Runtime.getRuntime();
int mb = 1024 * 1024;
put(l, "os.memory.free", runtime.freeMemory() / mb + "MB");
put(l, "os.memory.max", runtime.maxMemory() / mb + "MB");
put(l, "os.memory.total", runtime.totalMemory() / mb + "MB");
return l;
}
public static void logEnv(String msg, Logger log) {
List<Entry> env = Environment.list();
for (Entry e : env) {
log.info(msg + e.toString());
}
}
}
参考链接