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 }