001/*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License").  You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2008-2009 Sun Microsystems, Inc.
025 *      Copyright 2013-2015 ForgeRock AS
026 */
027package org.opends.server.util;
028
029import java.io.File;
030import org.forgerock.i18n.slf4j.LocalizedLogger;
031import java.lang.management.ManagementFactory;
032import java.lang.management.RuntimeMXBean;
033import java.net.InetAddress;
034import java.util.List;
035
036import javax.management.MBeanServer;
037import javax.management.ObjectName;
038
039import org.opends.server.core.DirectoryServer;
040
041import static org.opends.messages.CoreMessages.*;
042import static org.opends.messages.RuntimeMessages.*;
043import static org.opends.server.util.DynamicConstants.*;
044
045 /**
046  * This class is used to gather and display information from the runtime
047  * environment.
048  */
049 public class RuntimeInformation {
050
051  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
052
053
054
055   private static boolean is64Bit;
056
057   static {
058     String arch = System.getProperty("sun.arch.data.model");
059     if (arch != null) {
060       try {
061         is64Bit = Integer.parseInt(arch) == 64;
062       } catch (NumberFormatException ex) {
063         //Default to 32 bit.
064       }
065     }
066   }
067
068   /**
069    * Returns whether the architecture of the JVM we are running under is 64-bit
070    * or not.
071    *
072    * @return <CODE>true</CODE> if the JVM architecture we running under is
073    * 64-bit and <CODE>false</CODE> otherwise.
074    */
075   public static boolean is64Bit() {
076     return is64Bit;
077   }
078
079   /**
080    * Returns a string representing the JVM input arguments as determined by the
081    * MX runtime bean. The individual arguments are separated by commas.
082    *
083    * @return  A string representation of the JVM input arguments.
084    */
085   private static String getInputArguments() {
086     int count=0;
087     RuntimeMXBean rtBean = ManagementFactory.getRuntimeMXBean();
088     StringBuilder argList = new StringBuilder();
089     List<String> jvmArguments = rtBean.getInputArguments();
090     if (jvmArguments != null && !jvmArguments.isEmpty()) {
091       for (String jvmArg : jvmArguments) {
092         if (argList.length() > 0)  {
093           argList.append(" ");
094         }
095         argList.append("\"");
096         argList.append(jvmArg);
097         argList.append("\"");
098         count++;
099         if (count < jvmArguments.size())  {
100           argList.append(",");
101         }
102       }
103     }
104     return argList.toString();
105   }
106
107   /**
108    * Writes runtime information to a print stream.
109    */
110   public static void printInfo() {
111     System.out.println(NOTE_VERSION.get(DirectoryServer.getVersionString()));
112     System.out.println(NOTE_BUILD_ID.get(BUILD_ID));
113     System.out.println(
114             NOTE_JAVA_VERSION.get(System.getProperty("java.version")));
115     System.out.println(
116             NOTE_JAVA_VENDOR.get(System.getProperty("java.vendor")));
117     System.out.println(
118             NOTE_JVM_VERSION.get(System.getProperty("java.vm.version")));
119     System.out.println(
120             NOTE_JVM_VENDOR.get(System.getProperty("java.vm.vendor")));
121     System.out.println(
122             NOTE_JAVA_HOME.get(System.getProperty("java.home")));
123     System.out.println(
124             NOTE_JAVA_CLASSPATH.get(System.getProperty("java.class.path")));
125     System.out.println(
126             NOTE_CURRENT_DIRECTORY.get(System.getProperty("user.dir")));
127     String installDir = toCanonicalPath(DirectoryServer.getServerRoot());
128     if (installDir == null)
129     {
130       System.out.println(NOTE_UNKNOWN_INSTALL_DIRECTORY.get());
131     }
132     else
133     {
134       System.out.println(NOTE_INSTALL_DIRECTORY.get(installDir));
135     }
136     String instanceDir = toCanonicalPath(DirectoryServer.getInstanceRoot());
137     if (instanceDir == null)
138     {
139       System.out.println(NOTE_UNKNOWN_INSTANCE_DIRECTORY.get());
140     }
141     else
142     {
143       System.out.println(NOTE_INSTANCE_DIRECTORY.get(instanceDir));
144     }
145     System.out.println(
146             NOTE_OPERATING_SYSTEM.get(System.getProperty("os.name") + " " +
147                     System.getProperty("os.version") + " " +
148                     System.getProperty("os.arch")));
149     String sunOsArchDataModel = System.getProperty("sun.arch.data.model");
150     if (sunOsArchDataModel != null) {
151       if (! sunOsArchDataModel.toLowerCase().equals("unknown")) {
152         System.out.println(NOTE_JVM_ARCH.get(sunOsArchDataModel + "-bit"));
153       }
154     }
155     else{
156       System.out.println(NOTE_JVM_ARCH.get("unknown"));
157     }
158     try {
159       System.out.println(NOTE_SYSTEM_NAME.get(InetAddress.getLocalHost().
160               getCanonicalHostName()));
161     }
162     catch (Exception e) {
163       System.out.println(NOTE_SYSTEM_NAME.get("Unknown (" + e + ")"));
164     }
165     System.out.println(NOTE_AVAILABLE_PROCESSORS.get(Runtime.getRuntime().
166             availableProcessors()));
167     System.out.println(NOTE_MAX_MEMORY.get(Runtime.getRuntime().maxMemory()));
168     System.out.println(
169             NOTE_TOTAL_MEMORY.get(Runtime.getRuntime().totalMemory()));
170     System.out.println(
171             NOTE_FREE_MEMORY.get(Runtime.getRuntime().freeMemory()));
172   }
173
174  private static String toCanonicalPath(String path)
175  {
176    try
177    {
178      return new File(path).getCanonicalPath();
179    }
180    catch (Exception ignored)
181    {
182      return path;
183    }
184  }
185
186   /**
187     * Returns the physical memory size, in bytes, of the hardware we are
188     * running on.
189     *
190     * @return Bytes of physical memory of the hardware we are running on.
191     */
192  private static long getPhysicalMemorySize()
193  {
194    MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
195    try
196    {
197      // Assuming the RuntimeMXBean has been registered in mbs
198      ObjectName oname = new ObjectName(
199          ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME);
200      // Check if this MXBean contains Sun's extension
201      if (mbs.isInstanceOf(oname, "com.sun.management.OperatingSystemMXBean")) {
202          // Get platform-specific attribute "TotalPhysicalMemorySize"
203          return (Long) mbs.getAttribute(oname, "TotalPhysicalMemorySize");
204      }
205    }
206    catch (Exception ignored)
207    {
208    }
209    return -1;
210   }
211
212   /**
213    * Returns a string representing the fully qualified domain name.
214    *
215    * @return A string representing the fully qualified domain name or the
216    * string "unknown" if an exception was thrown.
217    */
218   private static String getHostName() {
219     try {
220       return InetAddress.getLocalHost().getCanonicalHostName();
221     }
222     catch (Exception e) {
223       return "Unknown (" + e + ")";
224     }
225   }
226
227   /**
228    * Returns string representing operating system name,
229    * version and architecture.
230    *
231    * @return String representing the operating system information the JVM is
232    * running under.
233    */
234   private static String getOSInfo() {
235    return System.getProperty("os.name") + " " +
236           System.getProperty("os.version") + " " +
237           System.getProperty("os.arch");
238   }
239
240   /**
241    * Return string representing the architecture of the JVM we are running
242    * under.
243    *
244    * @return A string representing the architecture of the JVM we are running
245    * under or "unknown" if the architecture cannot be determined.
246    */
247   private static String getArch() {
248     String sunOsArchDataModel = System.getProperty("sun.arch.data.model");
249     if (sunOsArchDataModel != null
250         && !sunOsArchDataModel.toLowerCase().equals("unknown"))
251     {
252       return sunOsArchDataModel + "-bit";
253     }
254     return "unknown";
255   }
256
257   /**
258    * Write runtime information to error log.
259    */
260   public static void logInfo() {
261     String installDir = toCanonicalPath(DirectoryServer.getServerRoot());
262     if (installDir == null)
263     {
264       logger.info(NOTE_UNKNOWN_INSTALL_DIRECTORY);
265     }
266     else
267     {
268       logger.info(NOTE_INSTALL_DIRECTORY, installDir);
269     }
270     String instanceDir = toCanonicalPath(DirectoryServer.getInstanceRoot());
271     if (instanceDir == null)
272     {
273       logger.info(NOTE_UNKNOWN_INSTANCE_DIRECTORY);
274     }
275     else
276     {
277       logger.info(NOTE_INSTANCE_DIRECTORY, instanceDir);
278     }
279    logger.info(NOTE_JVM_INFO, System.getProperty("java.runtime.version"),
280                               System.getProperty("java.vendor"),
281                               getArch(),Runtime.getRuntime().maxMemory());
282    long physicalMemorySize = getPhysicalMemorySize();
283    if (physicalMemorySize != -1)
284    {
285      logger.info(NOTE_JVM_HOST, getHostName(), getOSInfo(),
286          physicalMemorySize, Runtime.getRuntime().availableProcessors());
287    }
288    else
289    {
290      logger.info(NOTE_JVM_HOST_WITH_UNKNOWN_PHYSICAL_MEM, getHostName(),
291          getOSInfo(), Runtime.getRuntime().availableProcessors());
292    }
293    logger.info(NOTE_JVM_ARGS, getInputArguments());
294   }
295 }