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 import static org.opends.server.loggers.debug.DebugLogger.*;
030 import org.opends.server.loggers.debug.DebugTracer;
031 import org.opends.server.types.DebugLogLevel;
032
033 import org.opends.server.admin.std.server.MonitorProviderCfg;
034 import org.opends.server.api.AttributeSyntax;
035 import org.opends.server.api.MonitorProvider;
036 import org.opends.server.config.ConfigException;
037 import org.opends.server.core.DirectoryServer;
038 import org.opends.server.protocols.asn1.ASN1OctetString;
039 import org.opends.server.types.Attribute;
040 import org.opends.server.types.AttributeType;
041 import org.opends.server.types.AttributeValue;
042 import org.opends.server.types.InitializationException;
043 import org.opends.server.backends.jeb.RootContainer;
044
045 import com.sleepycat.je.DatabaseException;
046 import com.sleepycat.je.EnvironmentStats;
047 import com.sleepycat.je.JEVersion;
048 import com.sleepycat.je.LockStats;
049 import com.sleepycat.je.StatsConfig;
050 import com.sleepycat.je.TransactionStats;
051
052 import java.util.ArrayList;
053 import java.util.LinkedHashSet;
054 import java.lang.reflect.Method;
055
056 /**
057 * A monitor provider for a Berkeley DB JE environment.
058 * It uses reflection on the environment statistics object
059 * so that we don't need to keep a list of all the stats.
060 */
061 public class DatabaseEnvironmentMonitor
062 extends MonitorProvider<MonitorProviderCfg>
063 {
064 /**
065 * The tracer object for the debug logger.
066 */
067 private static final DebugTracer TRACER = getTracer();
068
069
070
071 /**
072 * The name of this monitor instance.
073 */
074 private String name;
075
076 /**
077 * The root container to be monitored.
078 */
079 private RootContainer rootContainer;
080
081 /**
082 * Creates a new database environment monitor.
083 * @param name The monitor instance name.
084 * @param rootContainer A root container handle for the database to be
085 * monitored.
086 */
087 public DatabaseEnvironmentMonitor(String name, RootContainer rootContainer)
088 {
089 super(name + " Monitor Provider");
090
091
092 this.name = name;
093 this.rootContainer = rootContainer;
094 }
095
096
097
098 /**
099 * {@inheritDoc}
100 */
101 public void initializeMonitorProvider(MonitorProviderCfg configuration)
102 throws ConfigException, InitializationException
103 {
104 }
105
106 /**
107 * Retrieves the name of this monitor provider. It should be unique among all
108 * monitor providers, including all instances of the same monitor provider.
109 *
110 * @return The name of this monitor provider.
111 */
112 public String getMonitorInstanceName()
113 {
114 return name;
115 }
116
117 /**
118 * Retrieves the length of time in milliseconds that should elapse between
119 * calls to the <CODE>updateMonitorData()</CODE> method. A negative or zero
120 * return value indicates that the <CODE>updateMonitorData()</CODE> method
121 * should not be periodically invoked.
122 *
123 * @return The length of time in milliseconds that should elapse between
124 * calls to the <CODE>updateMonitorData()</CODE> method.
125 */
126 public long getUpdateInterval()
127 {
128 return 0;
129 }
130
131 /**
132 * Performs any processing periodic processing that may be desired to update
133 * the information associated with this monitor. Note that best-effort
134 * attempts will be made to ensure that calls to this method come
135 * <CODE>getUpdateInterval()</CODE> milliseconds apart, but no guarantees will
136 * be made.
137 */
138 public void updateMonitorData()
139 {
140 }
141
142 /**
143 * Creates monitor attribute values for a given JE statistics object,
144 * using reflection to call all the getter methods of the statistics object.
145 * The attribute type names of the created attribute values are derived from
146 * the names of the getter methods.
147 * @param monitorAttrs The monitor attribute values are inserted into this
148 * attribute list.
149 * @param stats The JE statistics object.
150 * @param attrPrefix A common prefix for the attribute type names of the
151 * monitor attribute values, to distinguish the attributes of one
152 * type of statistical object from another, and to avoid attribute name
153 * collisions.
154 */
155 private void addAttributesForStatsObject(ArrayList<Attribute> monitorAttrs,
156 Object stats, String attrPrefix)
157 {
158 Class c = stats.getClass();
159 Method[] methods = c.getMethods();
160
161 // Iterate through all the statistic class methods.
162 for (Method method : methods)
163 {
164 // Invoke all the getters returning integer values.
165 if (method.getName().startsWith("get"))
166 {
167 Class<?> returnType = method.getReturnType();
168 if (returnType.equals(int.class) || returnType.equals(long.class))
169 {
170 AttributeSyntax integerSyntax =
171 DirectoryServer.getDefaultIntegerSyntax();
172
173 // Remove the 'get' from the method name and add the prefix.
174 String attrName = attrPrefix + method.getName().substring(3);
175
176 try
177 {
178 // Read the statistic.
179 Object statValue = method.invoke(stats);
180
181 // Create an attribute from the statistic.
182 AttributeType attrType =
183 DirectoryServer.getDefaultAttributeType(attrName,
184 integerSyntax);
185 ASN1OctetString valueString =
186 new ASN1OctetString(String.valueOf(statValue));
187 LinkedHashSet<AttributeValue> values =
188 new LinkedHashSet<AttributeValue>();
189 values.add(new AttributeValue(valueString, valueString));
190 monitorAttrs.add(new Attribute(attrType, attrName, values));
191
192 } catch (Exception e)
193 {
194 if (debugEnabled())
195 {
196 TRACER.debugCaught(DebugLogLevel.ERROR, e);
197 }
198 }
199 }
200 }
201 }
202 }
203
204 /**
205 * Retrieves a set of attributes containing monitor data that should be
206 * returned to the client if the corresponding monitor entry is requested.
207 *
208 * @return A set of attributes containing monitor data that should be
209 * returned to the client if the corresponding monitor entry is
210 * requested.
211 */
212 public ArrayList<Attribute> getMonitorData()
213 {
214 EnvironmentStats environmentStats = null;
215 LockStats lockStats = null;
216 TransactionStats transactionStats = null;
217 StatsConfig statsConfig = new StatsConfig();
218
219 try
220 {
221 environmentStats = rootContainer.getEnvironmentStats(statsConfig);
222 lockStats = rootContainer.getEnvironmentLockStats(statsConfig);
223 transactionStats =
224 rootContainer.getEnvironmentTransactionStats(statsConfig);
225 } catch (DatabaseException e)
226 {
227 if (debugEnabled())
228 {
229 TRACER.debugCaught(DebugLogLevel.ERROR, e);
230 }
231 return null;
232 }
233
234 ArrayList<Attribute> monitorAttrs = new ArrayList<Attribute>();
235
236 String jeVersion = JEVersion.CURRENT_VERSION.getVersionString();
237 AttributeType versionType =
238 DirectoryServer.getDefaultAttributeType("JEVersion");
239 LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>();
240 values.add(new AttributeValue(versionType, jeVersion));
241 monitorAttrs.add(new Attribute(versionType, "JEVersion", values));
242
243 addAttributesForStatsObject(monitorAttrs, environmentStats, "Environment");
244 addAttributesForStatsObject(monitorAttrs, lockStats, "Lock");
245 addAttributesForStatsObject(monitorAttrs, transactionStats, "Transaction");
246
247 return monitorAttrs;
248 }
249 }