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
010     * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011     * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012     * See the License for the specific language governing permissions
013     * and limitations under the License.
014     *
015     * When distributing Covered Code, include this CDDL HEADER in each
016     * file and include the License file at
017     * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
018     * add the following below this CDDL HEADER, with the fields enclosed
019     * by brackets "[]" replaced with your own identifying information:
020     *      Portions Copyright [yyyy] [name of copyright owner]
021     *
022     * CDDL HEADER END
023     *
024     *
025     *      Copyright 2006-2008 Sun Microsystems, Inc.
026     */
027    package org.opends.server.monitors;
028    
029    
030    
031    import java.lang.management.ManagementFactory;
032    import java.lang.management.RuntimeMXBean;
033    import java.net.InetAddress;
034    import java.util.ArrayList;
035    import java.util.LinkedHashSet;
036    import java.util.List;
037    
038    import org.opends.server.admin.std.server.SystemInfoMonitorProviderCfg;
039    import org.opends.server.api.MonitorProvider;
040    import org.opends.server.config.ConfigException;
041    import org.opends.server.core.DirectoryServer;
042    import org.opends.server.loggers.debug.DebugTracer;
043    import org.opends.server.protocols.asn1.ASN1OctetString;
044    import org.opends.server.types.Attribute;
045    import org.opends.server.types.AttributeType;
046    import org.opends.server.types.AttributeValue;
047    import org.opends.server.types.DebugLogLevel;
048    import org.opends.server.types.InitializationException;
049    
050    import static org.opends.server.loggers.debug.DebugLogger.*;
051    
052    
053    
054    /**
055     * This class defines a Directory Server monitor provider that can be used to
056     * collect information about the system and the JVM on which the Directory
057     * Server is running.
058     */
059    public class SystemInfoMonitorProvider
060           extends MonitorProvider<SystemInfoMonitorProviderCfg>
061    {
062      /**
063       * The tracer object for the debug logger.
064       */
065      private static final DebugTracer TRACER = getTracer();
066    
067    
068    
069      /**
070       * Initializes this monitor provider.
071       */
072      public SystemInfoMonitorProvider()
073      {
074        super("System Info Monitor Provider");
075    
076        // No initialization should be performed here.
077      }
078    
079    
080    
081      /**
082       * {@inheritDoc}
083       */
084      public void initializeMonitorProvider(
085                       SystemInfoMonitorProviderCfg configuration)
086             throws ConfigException, InitializationException
087      {
088        // No initialization is required.
089      }
090    
091    
092    
093      /**
094       * Retrieves the name of this monitor provider.  It should be unique among all
095       * monitor providers, including all instances of the same monitor provider.
096       *
097       * @return  The name of this monitor provider.
098       */
099      public String getMonitorInstanceName()
100      {
101        return "System Information";
102      }
103    
104    
105    
106      /**
107       * Retrieves the length of time in milliseconds that should elapse between
108       * calls to the <CODE>updateMonitorData()</CODE> method.  A negative or zero
109       * return value indicates that the <CODE>updateMonitorData()</CODE> method
110       * should not be periodically invoked.
111       *
112       * @return  The length of time in milliseconds that should elapse between
113       *          calls to the <CODE>updateMonitorData()</CODE> method.
114       */
115      public long getUpdateInterval()
116      {
117        // This monitor does not need to run periodically.
118        return 0;
119      }
120    
121    
122    
123      /**
124       * Performs any processing periodic processing that may be desired to update
125       * the information associated with this monitor.  Note that best-effort
126       * attempts will be made to ensure that calls to this method come
127       * <CODE>getUpdateInterval()</CODE> milliseconds apart, but no guarantees will
128       * be made.
129       */
130      public void updateMonitorData()
131      {
132        // This monitor does not need to run periodically.
133        return;
134      }
135    
136    
137    
138      /**
139       * Retrieves a set of attributes containing monitor data that should be
140       * returned to the client if the corresponding monitor entry is requested.
141       *
142       * @return  A set of attributes containing monitor data that should be
143       *          returned to the client if the corresponding monitor entry is
144       *          requested.
145       */
146      public ArrayList<Attribute> getMonitorData()
147      {
148        ArrayList<Attribute> attrs = new ArrayList<Attribute>(13);
149    
150        attrs.add(createAttribute("javaVersion",
151                                  System.getProperty("java.version")));
152        attrs.add(createAttribute("javaVendor", System.getProperty("java.vendor")));
153        attrs.add(createAttribute("jvmVersion",
154                                  System.getProperty("java.vm.version")));
155        attrs.add(createAttribute("jvmVendor",
156                                  System.getProperty("java.vm.vendor")));
157        attrs.add(createAttribute("javaHome",
158                                  System.getProperty("java.home")));
159        attrs.add(createAttribute("classPath",
160                                  System.getProperty("java.class.path")));
161        attrs.add(createAttribute("workingDirectory",
162                                  System.getProperty("user.dir")));
163    
164        String osInfo = System.getProperty("os.name") + " " +
165                        System.getProperty("os.version") + " " +
166                        System.getProperty("os.arch");
167        attrs.add(createAttribute("operatingSystem", osInfo));
168        String sunOsArchDataModel = System.getProperty("sun.arch.data.model");
169        if (sunOsArchDataModel != null)
170        {
171          String jvmArch = sunOsArchDataModel;
172          if (! sunOsArchDataModel.toLowerCase().equals("unknown"))
173          {
174            jvmArch += "-bit";
175          }
176          attrs.add(createAttribute("jvmArchitecture", jvmArch));
177        }
178        else
179        {
180          attrs.add(createAttribute("jvmArchitecture","unknown"));
181        }
182    
183        try
184        {
185          attrs.add(createAttribute("systemName",
186                         InetAddress.getLocalHost().getCanonicalHostName()));
187        }
188        catch (Exception e)
189        {
190          if (debugEnabled())
191          {
192            TRACER.debugCaught(DebugLogLevel.ERROR, e);
193          }
194        }
195    
196    
197        Runtime runtime = Runtime.getRuntime();
198        attrs.add(createAttribute("availableCPUs",
199                                  String.valueOf(runtime.availableProcessors())));
200        attrs.add(createAttribute("maxMemory",
201                                  String.valueOf(runtime.maxMemory())));
202        attrs.add(createAttribute("usedMemory",
203                                  String.valueOf(runtime.totalMemory())));
204        attrs.add(createAttribute("freeUsedMemory",
205                                  String.valueOf(runtime.freeMemory())));
206    
207    
208        // Get the JVM input arguments.
209        RuntimeMXBean rtBean = ManagementFactory.getRuntimeMXBean();
210        List<String> jvmArguments = rtBean.getInputArguments();
211        if ((jvmArguments != null) && (! jvmArguments.isEmpty()))
212        {
213          StringBuilder argList = new StringBuilder();
214          for (String jvmArg : jvmArguments)
215          {
216            if (argList.length() > 0)
217            {
218              argList.append(" ");
219            }
220    
221            argList.append("\"");
222            argList.append(jvmArg);
223            argList.append("\"");
224          }
225    
226          attrs.add(createAttribute("jvmArguments", argList.toString()));
227        }
228    
229    
230        return attrs;
231      }
232    
233    
234    
235      /**
236       * Constructs an attribute using the provided information.  It will have the
237       * default syntax.
238       *
239       * @param  name   The name to use for the attribute.
240       * @param  value  The value to use for the attribute.
241       *
242       * @return  The attribute created from the provided information.
243       */
244      private Attribute createAttribute(String name, String value)
245      {
246        AttributeType attrType = DirectoryServer.getDefaultAttributeType(name);
247    
248        ASN1OctetString encodedValue = new ASN1OctetString(value);
249        LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(1);
250    
251        try
252        {
253          values.add(new AttributeValue(encodedValue,
254                                        attrType.normalize(encodedValue)));
255        }
256        catch (Exception e)
257        {
258          if (debugEnabled())
259          {
260            TRACER.debugCaught(DebugLogLevel.ERROR, e);
261          }
262    
263          values.add(new AttributeValue(encodedValue, encodedValue));
264        }
265    
266        return new Attribute(attrType, name, values);
267      }
268    }
269