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