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      {
203        // Get platform-specific attribute "TotalPhysicalMemorySize"
204        return (Long) mbs.getAttribute(oname, "TotalPhysicalMemorySize");
205      }
206      else if (mbs.isInstanceOf(oname, "com.ibm.lang.management.OperatingSystemMXBean"))
207      {
208        // IBM JVM attribute is named differently
209        return (Long) mbs.getAttribute(oname, "TotalPhysicalMemory");
210      }
211    }
212    catch (Exception ignored)
213    {
214    }
215    return -1;
216   }
217
218   /**
219    * Returns a string representing the fully qualified domain name.
220    *
221    * @return A string representing the fully qualified domain name or the
222    * string "unknown" if an exception was thrown.
223    */
224   private static String getHostName() {
225     try {
226       return InetAddress.getLocalHost().getCanonicalHostName();
227     }
228     catch (Exception e) {
229       return "Unknown (" + e + ")";
230     }
231   }
232
233   /**
234    * Returns string representing operating system name,
235    * version and architecture.
236    *
237    * @return String representing the operating system information the JVM is
238    * running under.
239    */
240   private static String getOSInfo() {
241    return System.getProperty("os.name") + " " +
242           System.getProperty("os.version") + " " +
243           System.getProperty("os.arch");
244   }
245
246   /**
247    * Return string representing the architecture of the JVM we are running
248    * under.
249    *
250    * @return A string representing the architecture of the JVM we are running
251    * under or "unknown" if the architecture cannot be determined.
252    */
253   private static String getArch() {
254     String sunOsArchDataModel = System.getProperty("sun.arch.data.model");
255     if (sunOsArchDataModel != null
256         && !sunOsArchDataModel.toLowerCase().equals("unknown"))
257     {
258       return sunOsArchDataModel + "-bit";
259     }
260     return "unknown";
261   }
262
263   /**
264    * Write runtime information to error log.
265    */
266   public static void logInfo() {
267     String installDir = toCanonicalPath(DirectoryServer.getServerRoot());
268     if (installDir == null)
269     {
270       logger.info(NOTE_UNKNOWN_INSTALL_DIRECTORY);
271     }
272     else
273     {
274       logger.info(NOTE_INSTALL_DIRECTORY, installDir);
275     }
276     String instanceDir = toCanonicalPath(DirectoryServer.getInstanceRoot());
277     if (instanceDir == null)
278     {
279       logger.info(NOTE_UNKNOWN_INSTANCE_DIRECTORY);
280     }
281     else
282     {
283       logger.info(NOTE_INSTANCE_DIRECTORY, instanceDir);
284     }
285    logger.info(NOTE_JVM_INFO, System.getProperty("java.runtime.version"),
286                               System.getProperty("java.vendor"),
287                               getArch(),Runtime.getRuntime().maxMemory());
288    long physicalMemorySize = getPhysicalMemorySize();
289    if (physicalMemorySize != -1)
290    {
291      logger.info(NOTE_JVM_HOST, getHostName(), getOSInfo(),
292          physicalMemorySize, Runtime.getRuntime().availableProcessors());
293    }
294    else
295    {
296      logger.info(NOTE_JVM_HOST_WITH_UNKNOWN_PHYSICAL_MEM, getHostName(),
297          getOSInfo(), Runtime.getRuntime().availableProcessors());
298    }
299    logger.info(NOTE_JVM_ARGS, getInputArguments());
300   }
301 }