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;
46 import org.osgi.framework.Bundle;
47 import org.osgi.framework.BundleContext;
48 import org.osgi.framework.FrameworkUtil;
50 public class SystemInfo {
51 private static NumberFormat fmtI = new DecimalFormat("###,###", new DecimalFormatSymbols(Locale.ENGLISH));
52 private static NumberFormat fmtDec = new DecimalFormat("###,###.##", new DecimalFormatSymbols(Locale.ENGLISH));
53 private static NumberFormat fmtD = new DecimalFormat("###,##0.000", new DecimalFormatSymbols(Locale.ENGLISH));
54 private static OperatingSystemMXBean os = ManagementFactory.getOperatingSystemMXBean();
55 protected static boolean showMemoryPools = false;
57 public static String getMdSalVersion(String def) {
58 return getMdSalVersion("", def);
61 public static String getYangToolsVersion(String def) {
62 return getYangToolsVersion("", def);
65 public static String getMdSalVersion(String baseOdlDirectory, String def) {
66 return getFeatureVersionByFolder(baseOdlDirectory, "system/org/opendaylight/mdsal/mdsal-binding-api/", def);
69 public static String getYangToolsVersion(String baseOdlDirectory, String def) {
70 return getFeatureVersionByFolder(baseOdlDirectory, "system/org/opendaylight/yangtools/odl-yangtools-common/",
74 private static String getFeatureVersionByFolder(String baseOdlDirectory, String dir, String def) {
75 final String regex = "^[0-9]+\\.[0-9]+\\.[0-9]+(-SNAPSHOT)?$";
76 Stream<Path> entries = null;
78 if (baseOdlDirectory != null && baseOdlDirectory.length() > 0 && !baseOdlDirectory.endsWith("/")) {
79 baseOdlDirectory += "/";
81 entries = Files.list(new File(baseOdlDirectory + dir).toPath());
82 } catch (IOException e) {
85 if (entries == null) {
88 final Pattern pattern = Pattern.compile(regex);
90 Iterator<Path> it = entries.iterator();
93 while (it.hasNext()) {
96 if (f.isDirectory()) {
97 final Matcher matcher = pattern.matcher(f.getName().toString());
99 def = matcher.group(0);
108 public static String get() throws Exception {
109 StringBuilder sb = new StringBuilder();
112 RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
113 ThreadMXBean threads = ManagementFactory.getThreadMXBean();
114 MemoryMXBean mem = ManagementFactory.getMemoryMXBean();
115 ClassLoadingMXBean cl = ManagementFactory.getClassLoadingMXBean();
118 // print Karaf informations
121 sb.append("Karaf\n");
122 printValue(sb, "Karaf version", maxNameLen, System.getProperty("karaf.version"));
123 printValue(sb, "Karaf home", maxNameLen, System.getProperty("karaf.home"));
124 printValue(sb, "Karaf base", maxNameLen, System.getProperty("karaf.base"));
125 String osgi = getOsgiFramework();
127 printValue(sb, "OSGi Framework", maxNameLen, osgi);
131 printValue(sb, "Java Virtual Machine", maxNameLen, runtime.getVmName() + " version " + runtime.getVmVersion());
132 printValue(sb, "Version", maxNameLen, System.getProperty("java.version"));
133 printValue(sb, "Vendor", maxNameLen, runtime.getVmVendor());
134 printValue(sb, "Pid", maxNameLen, getPid());
135 printValue(sb, "Uptime", maxNameLen, printDuration(runtime.getUptime()));
137 Class<?> sunOS = Class.forName("com.sun.management.OperatingSystemMXBean");
138 printValue(sb, "Process CPU time", maxNameLen,
139 printDuration(getValueAsLong(sunOS, "getProcessCpuTime") / 1000000.0));
140 printValue(sb, "Process CPU load", maxNameLen, fmtDec.format(getValueAsDouble(sunOS, "getProcessCpuLoad")));
141 printValue(sb, "System CPU load", maxNameLen, fmtDec.format(getValueAsDouble(sunOS, "getSystemCpuLoad")));
142 } catch (Throwable t) {
145 Class<?> unixOS = Class.forName("com.sun.management.UnixOperatingSystemMXBean");
146 printValue(sb, "Open file descriptors", maxNameLen,
147 printLong(getValueAsLong(unixOS, "getOpenFileDescriptorCount")));
148 printValue(sb, "Max file descriptors", maxNameLen,
149 printLong(getValueAsLong(unixOS, "getMaxFileDescriptorCount")));
150 } catch (Throwable t) {
152 printValue(sb, "Total compile time", maxNameLen,
153 printDuration(ManagementFactory.getCompilationMXBean().getTotalCompilationTime()));
155 sb.append("Threads\n");
156 printValue(sb, "Live threads", maxNameLen, Integer.toString(threads.getThreadCount()));
157 printValue(sb, "Daemon threads", maxNameLen, Integer.toString(threads.getDaemonThreadCount()));
158 printValue(sb, "Peak", maxNameLen, Integer.toString(threads.getPeakThreadCount()));
159 printValue(sb, "Total started", maxNameLen, Long.toString(threads.getTotalStartedThreadCount()));
161 sb.append("Memory\n");
162 printValue(sb, "Current heap size", maxNameLen, printSizeInKb(mem.getHeapMemoryUsage().getUsed()));
163 printValue(sb, "Maximum heap size", maxNameLen, printSizeInKb(mem.getHeapMemoryUsage().getMax()));
164 printValue(sb, "Committed heap size", maxNameLen, printSizeInKb(mem.getHeapMemoryUsage().getCommitted()));
165 printValue(sb, "Pending objects", maxNameLen, Integer.toString(mem.getObjectPendingFinalizationCount()));
166 for (GarbageCollectorMXBean gc : ManagementFactory.getGarbageCollectorMXBeans()) {
167 String val = "Name = '" + gc.getName() + "', Collections = " + gc.getCollectionCount() + ", Time = "
168 + printDuration(gc.getCollectionTime());
169 printValue(sb, "Garbage collector", maxNameLen, val);
172 // if (showMemoryPools) {
173 // List<MemoryPoolMXBean> memoryPools = ManagementFactory.getMemoryPoolMXBeans();
174 // sb.append("Memory Pools\n");
175 // printValue(sb, "Total Memory Pools", maxNameLen, printLong(memoryPools.size()));
176 // String spaces4 = " ";
177 // for (MemoryPoolMXBean pool : memoryPools) {
178 // String name = pool.getName();
179 // MemoryType type = pool.getType();
180 // printValue(sb, spaces4 + "Pool (" + type + ")", maxNameLen, name);
182 // // PeakUsage/CurrentUsage
183 // MemoryUsage peakUsage = pool.getPeakUsage();
184 // MemoryUsage usage = pool.getUsage();
186 // if (usage != null && peakUsage != null) {
187 // long init = peakUsage.getInit();
188 // long used = peakUsage.getUsed();
189 // long committed = peakUsage.getCommitted();
190 // long max = peakUsage.getMax();
191 // sb.append(spaces4 + spaces4 + "Peak Usage\n");
192 // printValue(sb, spaces4 + spaces4 + spaces4 + "init", maxNameLen, printLong(init));
193 // printValue(sb, spaces4 + spaces4 + spaces4 + "used", maxNameLen, printLong(used));
194 // printValue(sb, spaces4 + spaces4 + spaces4 + "committed", maxNameLen, printLong(committed));
195 // printValue(sb, spaces4 + spaces4 + spaces4 + "max", maxNameLen, printLong(max));
197 // init = usage.getInit();
198 // used = usage.getUsed();
199 // committed = usage.getCommitted();
200 // max = usage.getMax();
201 // sb.append(spaces4 + spaces4 + "Current Usage\n");
202 // printValue(sb, spaces4 + spaces4 + spaces4 + "init", maxNameLen, printLong(init));
203 // printValue(sb, spaces4 + spaces4 + spaces4 + "used", maxNameLen, printLong(used));
204 // printValue(sb, spaces4 + spaces4 + spaces4 + "committed", maxNameLen, printLong(committed));
205 // printValue(sb, spaces4 + spaces4 + spaces4 + "max", maxNameLen, printLong(max));
210 sb.append("Classes\n");
211 printValue(sb, "Current classes loaded", maxNameLen, printLong(cl.getLoadedClassCount()));
212 printValue(sb, "Total classes loaded", maxNameLen, printLong(cl.getTotalLoadedClassCount()));
213 printValue(sb, "Total classes unloaded", maxNameLen, printLong(cl.getUnloadedClassCount()));
215 sb.append("Operating system\n");
216 printValue(sb, "Name", maxNameLen, os.getName() + " version " + os.getVersion());
217 printValue(sb, "Architecture", maxNameLen, os.getArch());
218 printValue(sb, "Processors", maxNameLen, Integer.toString(os.getAvailableProcessors()));
220 printValue(sb, "Total physical memory", maxNameLen,
221 printSizeInKb(getSunOsValueAsLong(os, "getTotalPhysicalMemorySize")));
222 printValue(sb, "Free physical memory", maxNameLen,
223 printSizeInKb(getSunOsValueAsLong(os, "getFreePhysicalMemorySize")));
224 printValue(sb, "Committed virtual memory", maxNameLen,
225 printSizeInKb(getSunOsValueAsLong(os, "getCommittedVirtualMemorySize")));
226 printValue(sb, "Total swap space", maxNameLen,
227 printSizeInKb(getSunOsValueAsLong(os, "getTotalSwapSpaceSize")));
228 printValue(sb, "Free swap space", maxNameLen,
229 printSizeInKb(getSunOsValueAsLong(os, "getFreeSwapSpaceSize")));
230 } catch (Throwable t) {
232 return sb.toString();
235 private static String getPid() {
236 // In Java 9 the new process API can be used:
237 // long pid = ProcessHandle.current().getPid();
238 String name = ManagementFactory.getRuntimeMXBean().getName();
239 String[] parts = name.split("@");
243 private static long getSunOsValueAsLong(OperatingSystemMXBean os, String name) throws Exception {
244 Method mth = os.getClass().getMethod(name);
245 return (Long) mth.invoke(os);
248 private static long getValueAsLong(Class<?> osImpl, String name) throws Exception {
249 if (osImpl.isInstance(os)) {
250 Method mth = osImpl.getMethod(name);
251 return (Long) mth.invoke(os);
256 private static double getValueAsDouble(Class<?> osImpl, String name) throws Exception {
257 if (osImpl.isInstance(os)) {
258 Method mth = osImpl.getMethod(name);
259 return (Double) mth.invoke(os);
264 private static String printLong(long i) {
265 return fmtI.format(i);
268 private static String printSizeInKb(double size) {
269 return fmtI.format((long) (size / 1024)) + " kbytes";
272 protected static String printDuration(double uptime) {
275 return fmtD.format(uptime) + " seconds";
279 long minutes = (long) uptime;
280 String s = fmtI.format(minutes) + (minutes > 1 ? " minutes" : " minute");
285 long hours = (long) uptime;
286 long minutes = (long) ((uptime - hours) * 60);
287 String s = fmtI.format(hours) + (hours > 1 ? " hours" : " hour");
289 s += " " + fmtI.format(minutes) + (minutes > 1 ? " minutes" : " minute");
294 long days = (long) uptime;
295 long hours = (long) ((uptime - days) * 24);
296 String s = fmtI.format(days) + (days > 1 ? " days" : " day");
298 s += " " + fmtI.format(hours) + (hours > 1 ? " hours" : " hour");
303 static void printSysValue(StringBuilder sb, String prop, int pad) {
304 printValue(sb, prop, pad, System.getProperty(prop));
307 static void printValue(StringBuilder sb, String name, int pad, String value) {
308 sb.append(" " + // SimpleAnsi.INTENSITY_BOLD +
309 name + // SimpleAnsi.INTENSITY_NORMAL +
310 spaces(pad - name.length()) + " " + value + "\n");
313 static String spaces(int nb) {
314 StringBuilder sb = new StringBuilder();
315 for (int i = 0; i < nb; i++) {
318 return sb.toString();
321 static String getOsgiFramework() {
323 Callable<String> call = new Callable<String>() {
325 public String call() throws Exception {
326 BundleContext context = FrameworkUtil.getBundle(getClass()).getBundleContext();
327 Bundle sysBundle = context.getBundle(0);
328 return sysBundle.getSymbolicName() + "-" + sysBundle.getVersion();
332 } catch (Throwable t) {
333 // We're not in OSGi, just safely return null