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