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 2006-2010 Sun Microsystems, Inc.
025 *      Portions Copyright 2012-2015 ForgeRock AS.
026 */
027package org.opends.server.monitors;
028
029import static org.opends.server.util.ServerConstants.*;
030
031import java.lang.management.ManagementFactory;
032import java.lang.management.RuntimeMXBean;
033import java.net.InetAddress;
034import java.util.ArrayList;
035import java.util.Arrays;
036import java.util.Collection;
037import java.util.Collections;
038import java.util.List;
039
040import javax.net.ssl.SSLContext;
041import javax.net.ssl.SSLParameters;
042
043import org.forgerock.i18n.slf4j.LocalizedLogger;
044import org.forgerock.opendj.config.server.ConfigException;
045import org.opends.server.admin.std.server.SystemInfoMonitorProviderCfg;
046import org.opends.server.api.MonitorProvider;
047import org.opends.server.core.DirectoryServer;
048import org.opends.server.types.Attribute;
049import org.opends.server.types.AttributeBuilder;
050import org.opends.server.types.AttributeType;
051import org.opends.server.types.Attributes;
052import org.opends.server.types.InitializationException;
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 */
059public class SystemInfoMonitorProvider
060       extends MonitorProvider<SystemInfoMonitorProviderCfg>
061{
062  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
063
064  @Override
065  public void initializeMonitorProvider(
066                   SystemInfoMonitorProviderCfg configuration)
067         throws ConfigException, InitializationException
068  {
069    // No initialization is required.
070  }
071
072  @Override
073  public String getMonitorInstanceName()
074  {
075    return "System Information";
076  }
077
078  @Override
079  public List<Attribute> getMonitorData()
080  {
081    ArrayList<Attribute> attrs = new ArrayList<>(13);
082
083    attrs.add(createAttribute("javaVersion",
084                              System.getProperty("java.version")));
085    attrs.add(createAttribute("javaVendor", System.getProperty("java.vendor")));
086    attrs.add(createAttribute("jvmVersion",
087                              System.getProperty("java.vm.version")));
088    attrs.add(createAttribute("jvmVendor",
089                              System.getProperty("java.vm.vendor")));
090    attrs.add(createAttribute("javaHome",
091                              System.getProperty("java.home")));
092    attrs.add(createAttribute("classPath",
093                              System.getProperty("java.class.path")));
094    attrs.add(createAttribute("workingDirectory",
095                              System.getProperty("user.dir")));
096
097    String osInfo = System.getProperty("os.name") + " " +
098                    System.getProperty("os.version") + " " +
099                    System.getProperty("os.arch");
100    attrs.add(createAttribute("operatingSystem", osInfo));
101    String sunOsArchDataModel = System.getProperty("sun.arch.data.model");
102    if (sunOsArchDataModel != null)
103    {
104      String jvmArch = sunOsArchDataModel;
105      if (! sunOsArchDataModel.toLowerCase().equals("unknown"))
106      {
107        jvmArch += "-bit";
108      }
109      attrs.add(createAttribute("jvmArchitecture", jvmArch));
110    }
111    else
112    {
113      attrs.add(createAttribute("jvmArchitecture","unknown"));
114    }
115
116    try
117    {
118      attrs.add(createAttribute("systemName",
119                     InetAddress.getLocalHost().getCanonicalHostName()));
120    }
121    catch (Exception e)
122    {
123      logger.traceException(e);
124    }
125
126
127    Runtime runtime = Runtime.getRuntime();
128    attrs.add(createAttribute("availableCPUs",
129                              String.valueOf(runtime.availableProcessors())));
130    attrs.add(createAttribute("maxMemory",
131                              String.valueOf(runtime.maxMemory())));
132    attrs.add(createAttribute("usedMemory",
133                              String.valueOf(runtime.totalMemory())));
134    attrs.add(createAttribute("freeUsedMemory",
135                              String.valueOf(runtime.freeMemory())));
136    String installPath = DirectoryServer.getServerRoot();
137    if (installPath != null)
138    {
139      attrs.add(createAttribute("installPath", installPath));
140    }
141    String instancePath = DirectoryServer.getInstanceRoot();
142    if (instancePath != null)
143    {
144      attrs.add(createAttribute("instancePath", instancePath));
145    }
146
147    // Get the JVM input arguments.
148    RuntimeMXBean rtBean = ManagementFactory.getRuntimeMXBean();
149    List<String> jvmArguments = rtBean.getInputArguments();
150    if (jvmArguments != null && ! jvmArguments.isEmpty())
151    {
152      StringBuilder argList = new StringBuilder();
153      for (String jvmArg : jvmArguments)
154      {
155        if (argList.length() > 0)
156        {
157          argList.append(" ");
158        }
159
160        argList.append("\"");
161        argList.append(jvmArg);
162        argList.append("\"");
163      }
164
165      attrs.add(createAttribute("jvmArguments", argList.toString()));
166    }
167
168    // Get the list of supported SSL protocols and ciphers.
169    Collection<String> supportedTlsProtocols;
170    Collection<String> supportedTlsCiphers;
171    try
172    {
173      final SSLContext context = SSLContext.getDefault();
174      final SSLParameters parameters = context.getSupportedSSLParameters();
175      supportedTlsProtocols = Arrays.asList(parameters.getProtocols());
176      supportedTlsCiphers = Arrays.asList(parameters.getCipherSuites());
177    }
178    catch (Exception e)
179    {
180      // A default SSL context should always be available.
181      supportedTlsProtocols = Collections.emptyList();
182      supportedTlsCiphers = Collections.emptyList();
183    }
184
185    addAttribute(attrs, ATTR_SUPPORTED_TLS_PROTOCOLS, supportedTlsProtocols);
186    addAttribute(attrs, ATTR_SUPPORTED_TLS_CIPHERS, supportedTlsCiphers);
187
188    return attrs;
189  }
190
191  private void addAttribute(ArrayList<Attribute> attrs, String attrName, Collection<String> values)
192  {
193    AttributeType attrType = DirectoryServer.getDefaultAttributeType(attrName);
194    AttributeBuilder builder = new AttributeBuilder(attrType);
195    builder.addAllStrings(values);
196    attrs.add(builder.toAttribute());
197  }
198
199  /**
200   * Constructs an attribute using the provided information.  It will have the
201   * default syntax.
202   *
203   * @param  name   The name to use for the attribute.
204   * @param  value  The value to use for the attribute.
205   *
206   * @return  The attribute created from the provided information.
207   */
208  private Attribute createAttribute(String name, String value)
209  {
210    AttributeType attrType = DirectoryServer.getDefaultAttributeType(name);
211    return Attributes.create(attrType, value);
212  }
213}
214