SystemHealth.java 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. package com.sig.common.utils;
  2. import com.sun.management.OperatingSystemMXBean;
  3. import lombok.Getter;
  4. import java.io.File;
  5. import java.lang.management.GarbageCollectorMXBean;
  6. import java.lang.management.ManagementFactory;
  7. import java.lang.management.MemoryMXBean;
  8. import java.time.Instant;
  9. import java.time.ZoneId;
  10. @Getter
  11. public class SystemHealth {
  12. private String osName = System.getProperty("os.name");
  13. private String osVersion = System.getProperty("os.version");
  14. private int cpuCores = Runtime.getRuntime().availableProcessors();
  15. private long maxMemory = Runtime.getRuntime().maxMemory();
  16. private long totalMemory = 0; // MB
  17. private long freeMemory = 0; // MB
  18. private long usedMemory = 0; // MB
  19. private long heapUsed;
  20. private long nonHeapUsed;
  21. private double memUsage = 0.;
  22. private double cpuUsage = 0.;
  23. private double loadAverage; // CPU 부하
  24. private int threadCount = 0; // 현재스레드 수
  25. private int peakThreadCount; // 어플리케이션 운영중 최대 스레드 수
  26. private long jvmUptime; // milliseconds, - 예: uptimeMillis = 3600000 → JVM이 1시간(60분) 동안 실행 중이라는 뜻
  27. private long loadedClassCount;
  28. // private final Map<String, Double> diskUsageMap = new HashMap<>();
  29. private long diskTotal;
  30. private long diskFree;
  31. private double diskUsage;
  32. // private final Map<String, GcStats> gcStatsMap = new HashMap<>();
  33. private String gcName;
  34. private long gcTotalCount = 0;
  35. private long gcTotalTime = 0;
  36. private long gcTotalAvgTime = 0;
  37. private long gcRecentCount = 0;
  38. private long gcRecentTime = 0;
  39. private long gcRecentAvgTime = 0;
  40. private final String jvmStartTime;
  41. public SystemHealth() {
  42. this.jvmStartTime = Instant.ofEpochMilli(
  43. ManagementFactory.getRuntimeMXBean().getStartTime()
  44. ).atZone(ZoneId.systemDefault()).toString();
  45. Runtime runtime = Runtime.getRuntime();
  46. this.maxMemory = runtime.maxMemory() / 1024 / 1024;
  47. this.cpuCores = runtime.availableProcessors();
  48. this.osName = System.getProperty("os.name");
  49. this.osVersion = System.getProperty("os.version");
  50. }
  51. public void checkHealth(boolean useDisk) {
  52. Runtime runtime = Runtime.getRuntime();
  53. this.totalMemory = runtime.totalMemory(); // Byte
  54. this.freeMemory = runtime.freeMemory(); // Byte
  55. this.usedMemory = this.totalMemory - this.freeMemory; // Byte
  56. MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
  57. this.heapUsed = memoryMXBean.getHeapMemoryUsage().getUsed() / 1024 / 1024;
  58. this.nonHeapUsed = memoryMXBean.getNonHeapMemoryUsage().getUsed() / 1024 / 1024;
  59. this.totalMemory = this.totalMemory / 1024 / 1024;
  60. this.freeMemory = this.freeMemory / 1024 / 1024;
  61. this.usedMemory = this.usedMemory / 1024 / 1024;
  62. // System.out.println("사용 중인 메모리: " + (usedMemory / 1024 / 1024) + " MB");
  63. // System.out.println("최대 메모리: " + (maxMemory / 1024 / 1024) + " MB");
  64. this.memUsage = (double) this.usedMemory / this.maxMemory * 100;
  65. // For Linux/Unix, Windows(Perhaps)
  66. try {
  67. OperatingSystemMXBean osBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
  68. if (osBean != null) {
  69. this.cpuUsage = osBean.getSystemCpuLoad() * 100;
  70. this.loadAverage = osBean.getSystemLoadAverage(); // 1분 평균
  71. }
  72. else {
  73. this.cpuUsage = 0;
  74. this.loadAverage = 0;
  75. }
  76. }
  77. catch (Throwable t) {
  78. this.cpuUsage = 0;
  79. this.loadAverage = 0;
  80. }
  81. this.threadCount = ManagementFactory.getThreadMXBean().getThreadCount();
  82. this.peakThreadCount = ManagementFactory.getThreadMXBean().getPeakThreadCount();
  83. this.jvmUptime = ManagementFactory.getRuntimeMXBean().getUptime();
  84. // long uptimeSeconds = this.jvmUptime / 1000;
  85. // long uptimeMinutes = uptimeSeconds / 60;
  86. // long uptimeHours = uptimeMinutes / 60;
  87. // long uptimeDays = uptimeHours / 24;
  88. // System.out.println("JVM Uptime: "
  89. // + uptimeDays + "d "
  90. // + (uptimeHours % 24) + "h "
  91. // + (uptimeMinutes % 60) + "m "
  92. // + (uptimeSeconds % 60) + "s");
  93. this.loadedClassCount = ManagementFactory.getClassLoadingMXBean().getLoadedClassCount();
  94. if (useDisk) {
  95. File root = new File("/");
  96. if (root.exists() && root.canRead()) {
  97. this.diskTotal = root.getTotalSpace();
  98. this.diskFree = root.getFreeSpace();
  99. long used = this.diskTotal - this.diskFree;
  100. this.diskUsage = (double) used / this.diskTotal * 100;
  101. }
  102. }
  103. long totalGcCount = 0;
  104. long totalGcTime = 0;
  105. for (GarbageCollectorMXBean gc : ManagementFactory.getGarbageCollectorMXBeans()) {
  106. totalGcCount += gc.getCollectionCount();
  107. totalGcTime += gc.getCollectionTime();
  108. // this.gcName = gc.getName();
  109. // gcStatsMap.put(gc.getName(), new GcStats(gc.getCollectionCount(), gc.getCollectionTime()));
  110. }
  111. // 누적 평균
  112. this.gcTotalAvgTime = totalGcTime > 0 ? Math.round((double) totalGcTime / totalGcCount) : 0;
  113. // 최근 변화량
  114. this.gcRecentCount = totalGcCount - this.gcTotalCount;
  115. this.gcRecentTime = totalGcTime - this.gcTotalTime;
  116. this.gcRecentAvgTime = gcTotalCount > 0 ? Math.round((double) this.gcRecentTime / gcTotalCount) : 0;
  117. this.gcTotalCount = totalGcCount;
  118. this.gcTotalTime = totalGcTime;
  119. // for (File root : File.listRoots()) {
  120. // if (root.exists() && root.canRead()) {
  121. // long total = root.getTotalSpace();
  122. // long free = root.getFreeSpace();
  123. // double usage = (double) (total - free) / total * 100;
  124. // diskUsageMap.put(root.getAbsolutePath(), usage);
  125. // }
  126. // }
  127. // GC가 전체 실행 시간의 몇 %를 차지했는지 확인 가능
  128. // long uptime = ManagementFactory.getRuntimeMXBean().getUptime(); // ms
  129. // long gcTime = this.gcTime;
  130. // double gcRatio = (double) gcTime / uptime * 100;
  131. // log.info("GC Time: {}ms, JVM Uptime: {}ms, GC 비중: {:.2f}%", gcTime, uptime, gcRatio);
  132. }
  133. public String getFormattedUptime() {
  134. long uptimeSeconds = this.jvmUptime / 1000;
  135. long uptimeMinutes = uptimeSeconds / 60;
  136. long uptimeHours = uptimeMinutes / 60;
  137. long uptimeDays = uptimeHours / 24;
  138. return uptimeDays + "d " + (uptimeHours % 24) + "h " + (uptimeMinutes % 60) + "m " + (uptimeSeconds % 60) + "s";
  139. }
  140. }