2 * ============LICENSE_START=======================================================
3 * ONAP : ccsdk features
4 * ================================================================================
5 * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property.
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.onap.ccsdk.features.sdnr.wt.dataprovider.http.about;
25 import java.io.IOException;
26 import java.lang.management.ClassLoadingMXBean;
27 import java.lang.management.GarbageCollectorMXBean;
28 import java.lang.management.ManagementFactory;
29 import java.lang.management.MemoryMXBean;
30 import java.lang.management.OperatingSystemMXBean;
31 import java.lang.management.RuntimeMXBean;
32 import java.lang.management.ThreadMXBean;
33 import java.lang.reflect.Method;
34 import java.nio.file.Files;
35 import java.nio.file.Path;
36 import java.text.DecimalFormat;
37 import java.text.DecimalFormatSymbols;
38 import java.text.NumberFormat;
39 import java.util.Iterator;
40 import java.util.Locale;
41 import java.util.concurrent.Callable;
42 import java.util.regex.Matcher;
43 import java.util.regex.Pattern;
44 import java.util.stream.Stream;
45 import org.osgi.framework.Bundle;
46 import org.osgi.framework.BundleContext;
47 import org.osgi.framework.FrameworkUtil;
49 public class SystemInfo {
50 private static NumberFormat fmtI = new DecimalFormat("###,###", new DecimalFormatSymbols(Locale.ENGLISH));
51 private static NumberFormat fmtDec = new DecimalFormat("###,###.##", new DecimalFormatSymbols(Locale.ENGLISH));
52 private static NumberFormat fmtD = new DecimalFormat("###,##0.000", new DecimalFormatSymbols(Locale.ENGLISH));
53 private static OperatingSystemMXBean os = ManagementFactory.getOperatingSystemMXBean();
54 protected static boolean showMemoryPools = false;
56 public static String getOnapVersion(String def) {
57 return getOnapVersion("", def);
60 public static String getMdSalVersion(String def) {
61 return getMdSalVersion("", def);
64 public static String getYangToolsVersion(String def) {
65 return getYangToolsVersion("", def);
68 public static String getOnapVersion(String baseOdlDirectory, String def) {
69 return getFeatureVersionByFolder(baseOdlDirectory, "system/org/onap/sdnc/northbound/sdnc-northbound-all/", def);
72 public static String getMdSalVersion(String baseOdlDirectory, String def) {
73 return getFeatureVersionByFolder(baseOdlDirectory, "system/org/opendaylight/mdsal/mdsal-binding-api/", def);
76 public static String getYangToolsVersion(String baseOdlDirectory, String def) {
77 return getFeatureVersionByFolder(baseOdlDirectory, "system/org/opendaylight/yangtools/odl-yangtools-common/",
81 private static String getFeatureVersionByFolder(String baseOdlDirectory, String dir, String def) {
82 final String regex = "^[0-9]+\\.[0-9]+\\.[0-9]+(-SNAPSHOT)?$";
83 Stream<Path> entries = null;
85 if (baseOdlDirectory != null && baseOdlDirectory.length() > 0 && !baseOdlDirectory.endsWith("/")) {
86 baseOdlDirectory += "/";
88 entries = Files.list(new File(baseOdlDirectory + dir).toPath());
89 } catch (IOException e) {
92 if (entries == null) {
95 final Pattern pattern = Pattern.compile(regex);
97 Iterator<Path> it = entries.iterator();
100 while (it.hasNext()) {
103 if (f.isDirectory()) {
104 final Matcher matcher = pattern.matcher(f.getName().toString());
105 if (matcher.find()) {
106 def = matcher.group(0);
115 public static String get() throws Exception {
116 StringBuilder sb = new StringBuilder();
119 RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
120 ThreadMXBean threads = ManagementFactory.getThreadMXBean();
121 MemoryMXBean mem = ManagementFactory.getMemoryMXBean();
122 ClassLoadingMXBean cl = ManagementFactory.getClassLoadingMXBean();
125 // print Karaf informations
128 sb.append("Karaf\n");
129 printValue(sb, "Karaf version", maxNameLen, System.getProperty("karaf.version"));
130 printValue(sb, "Karaf home", maxNameLen, System.getProperty("karaf.home"));
131 printValue(sb, "Karaf base", maxNameLen, System.getProperty("karaf.base"));
132 String osgi = getOsgiFramework();
134 printValue(sb, "OSGi Framework", maxNameLen, osgi);
138 printValue(sb, "Java Virtual Machine", maxNameLen, runtime.getVmName() + " version " + runtime.getVmVersion());
139 printValue(sb, "Version", maxNameLen, System.getProperty("java.version"));
140 printValue(sb, "Vendor", maxNameLen, runtime.getVmVendor());
141 printValue(sb, "Pid", maxNameLen, getPid());
142 printValue(sb, "Uptime", maxNameLen, printDuration(runtime.getUptime()));
144 Class<?> sunOS = Class.forName("com.sun.management.OperatingSystemMXBean");
145 printValue(sb, "Process CPU time", maxNameLen,
146 printDuration(getValueAsLong(sunOS, "getProcessCpuTime") / 1000000.0));
147 printValue(sb, "Process CPU load", maxNameLen, fmtDec.format(getValueAsDouble(sunOS, "getProcessCpuLoad")));
148 printValue(sb, "System CPU load", maxNameLen, fmtDec.format(getValueAsDouble(sunOS, "getSystemCpuLoad")));
149 } catch (Throwable t) {
152 Class<?> unixOS = Class.forName("com.sun.management.UnixOperatingSystemMXBean");
153 printValue(sb, "Open file descriptors", maxNameLen,
154 printLong(getValueAsLong(unixOS, "getOpenFileDescriptorCount")));
155 printValue(sb, "Max file descriptors", maxNameLen,
156 printLong(getValueAsLong(unixOS, "getMaxFileDescriptorCount")));
157 } catch (Throwable t) {
159 printValue(sb, "Total compile time", maxNameLen,
160 printDuration(ManagementFactory.getCompilationMXBean().getTotalCompilationTime()));
162 sb.append("Threads\n");
163 printValue(sb, "Live threads", maxNameLen, Integer.toString(threads.getThreadCount()));
164 printValue(sb, "Daemon threads", maxNameLen, Integer.toString(threads.getDaemonThreadCount()));
165 printValue(sb, "Peak", maxNameLen, Integer.toString(threads.getPeakThreadCount()));
166 printValue(sb, "Total started", maxNameLen, Long.toString(threads.getTotalStartedThreadCount()));
168 sb.append("Memory\n");
169 printValue(sb, "Current heap size", maxNameLen, printSizeInKb(mem.getHeapMemoryUsage().getUsed()));
170 printValue(sb, "Maximum heap size", maxNameLen, printSizeInKb(mem.getHeapMemoryUsage().getMax()));
171 printValue(sb, "Committed heap size", maxNameLen, printSizeInKb(mem.getHeapMemoryUsage().getCommitted()));
172 printValue(sb, "Pending objects", maxNameLen, Integer.toString(mem.getObjectPendingFinalizationCount()));
173 for (GarbageCollectorMXBean gc : ManagementFactory.getGarbageCollectorMXBeans()) {
174 String val = "Name = '" + gc.getName() + "', Collections = " + gc.getCollectionCount() + ", Time = "
175 + printDuration(gc.getCollectionTime());
176 printValue(sb, "Garbage collector", maxNameLen, val);
179 // if (showMemoryPools) {
180 // List<MemoryPoolMXBean> memoryPools = ManagementFactory.getMemoryPoolMXBeans();
181 // sb.append("Memory Pools\n");
182 // printValue(sb, "Total Memory Pools", maxNameLen, printLong(memoryPools.size()));
183 // String spaces4 = " ";
184 // for (MemoryPoolMXBean pool : memoryPools) {
185 // String name = pool.getName();
186 // MemoryType type = pool.getType();
187 // printValue(sb, spaces4 + "Pool (" + type + ")", maxNameLen, name);
189 // // PeakUsage/CurrentUsage
190 // MemoryUsage peakUsage = pool.getPeakUsage();
191 // MemoryUsage usage = pool.getUsage();
193 // if (usage != null && peakUsage != null) {
194 // long init = peakUsage.getInit();
195 // long used = peakUsage.getUsed();
196 // long committed = peakUsage.getCommitted();
197 // long max = peakUsage.getMax();
198 // sb.append(spaces4 + spaces4 + "Peak Usage\n");
199 // printValue(sb, spaces4 + spaces4 + spaces4 + "init", maxNameLen, printLong(init));
200 // printValue(sb, spaces4 + spaces4 + spaces4 + "used", maxNameLen, printLong(used));
201 // printValue(sb, spaces4 + spaces4 + spaces4 + "committed", maxNameLen, printLong(committed));
202 // printValue(sb, spaces4 + spaces4 + spaces4 + "max", maxNameLen, printLong(max));
204 // init = usage.getInit();
205 // used = usage.getUsed();
206 // committed = usage.getCommitted();
207 // max = usage.getMax();
208 // sb.append(spaces4 + spaces4 + "Current Usage\n");
209 // printValue(sb, spaces4 + spaces4 + spaces4 + "init", maxNameLen, printLong(init));
210 // printValue(sb, spaces4 + spaces4 + spaces4 + "used", maxNameLen, printLong(used));
211 // printValue(sb, spaces4 + spaces4 + spaces4 + "committed", maxNameLen, printLong(committed));
212 // printValue(sb, spaces4 + spaces4 + spaces4 + "max", maxNameLen, printLong(max));
217 sb.append("Classes\n");
218 printValue(sb, "Current classes loaded", maxNameLen, printLong(cl.getLoadedClassCount()));
219 printValue(sb, "Total classes loaded", maxNameLen, printLong(cl.getTotalLoadedClassCount()));
220 printValue(sb, "Total classes unloaded", maxNameLen, printLong(cl.getUnloadedClassCount()));
222 sb.append("Operating system\n");
223 printValue(sb, "Name", maxNameLen, os.getName() + " version " + os.getVersion());
224 printValue(sb, "Architecture", maxNameLen, os.getArch());
225 printValue(sb, "Processors", maxNameLen, Integer.toString(os.getAvailableProcessors()));
227 printValue(sb, "Total physical memory", maxNameLen,
228 printSizeInKb(getSunOsValueAsLong(os, "getTotalPhysicalMemorySize")));
229 printValue(sb, "Free physical memory", maxNameLen,
230 printSizeInKb(getSunOsValueAsLong(os, "getFreePhysicalMemorySize")));
231 printValue(sb, "Committed virtual memory", maxNameLen,
232 printSizeInKb(getSunOsValueAsLong(os, "getCommittedVirtualMemorySize")));
233 printValue(sb, "Total swap space", maxNameLen,
234 printSizeInKb(getSunOsValueAsLong(os, "getTotalSwapSpaceSize")));
235 printValue(sb, "Free swap space", maxNameLen,
236 printSizeInKb(getSunOsValueAsLong(os, "getFreeSwapSpaceSize")));
237 } catch (Throwable t) {
239 return sb.toString();
242 private static String getPid() {
243 // In Java 9 the new process API can be used:
244 // long pid = ProcessHandle.current().getPid();
245 String name = ManagementFactory.getRuntimeMXBean().getName();
246 String[] parts = name.split("@");
250 private static long getSunOsValueAsLong(OperatingSystemMXBean os, String name) throws Exception {
251 Method mth = os.getClass().getMethod(name);
252 return (Long) mth.invoke(os);
255 private static long getValueAsLong(Class<?> osImpl, String name) throws Exception {
256 if (osImpl.isInstance(os)) {
257 Method mth = osImpl.getMethod(name);
258 return (Long) mth.invoke(os);
263 private static double getValueAsDouble(Class<?> osImpl, String name) throws Exception {
264 if (osImpl.isInstance(os)) {
265 Method mth = osImpl.getMethod(name);
266 return (Double) mth.invoke(os);
271 private static String printLong(long i) {
272 return fmtI.format(i);
275 private static String printSizeInKb(double size) {
276 return fmtI.format((long) (size / 1024)) + " kbytes";
279 protected static String printDuration(double uptime) {
282 return fmtD.format(uptime) + " seconds";
286 long minutes = (long) uptime;
287 String s = fmtI.format(minutes) + (minutes > 1 ? " minutes" : " minute");
292 long hours = (long) uptime;
293 long minutes = (long) ((uptime - hours) * 60);
294 String s = fmtI.format(hours) + (hours > 1 ? " hours" : " hour");
296 s += " " + fmtI.format(minutes) + (minutes > 1 ? " minutes" : " minute");
301 long days = (long) uptime;
302 long hours = (long) ((uptime - days) * 24);
303 String s = fmtI.format(days) + (days > 1 ? " days" : " day");
305 s += " " + fmtI.format(hours) + (hours > 1 ? " hours" : " hour");
310 static void printSysValue(StringBuilder sb, String prop, int pad) {
311 printValue(sb, prop, pad, System.getProperty(prop));
314 static void printValue(StringBuilder sb, String name, int pad, String value) {
315 sb.append(" " + // SimpleAnsi.INTENSITY_BOLD +
316 name + // SimpleAnsi.INTENSITY_NORMAL +
317 spaces(pad - name.length()) + " " + value + "\n");
320 static String spaces(int nb) {
321 StringBuilder sb = new StringBuilder();
322 for (int i = 0; i < nb; i++) {
325 return sb.toString();
328 static String getOsgiFramework() {
330 Callable<String> call = new Callable<String>() {
332 public String call() throws Exception {
333 BundleContext context = FrameworkUtil.getBundle(getClass()).getBundleContext();
334 Bundle sysBundle = context.getBundle(0);
335 return sysBundle.getSymbolicName() + "-" + sysBundle.getVersion();
339 } catch (Throwable t) {
340 // We're not in OSGi, just safely return null