1 <!doctype html public "-//w3c//dtd html 4.0 transitional//en"> 2 <html> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> 5 <meta name="GENERATOR" content="Mozilla/4.79C-CCK-MCD [en] (X11; U; SunOS 5.8 sun4u) [Netscape]"> 6 <title>package</title> 7 <!-- 8 9 Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. 10 DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 11 12 This code is free software; you can redistribute it and/or modify it 13 under the terms of the GNU General Public License version 2 only, as 14 published by the Free Software Foundation. Oracle designates this 15 particular file as subject to the "Classpath" exception as provided 16 by Oracle in the LICENSE file that accompanied this code. 17 18 This code is distributed in the hope that it will be useful, but WITHOUT 19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 21 version 2 for more details (a copy is included in the LICENSE file that 22 accompanied this code). 23 24 You should have received a copy of the GNU General Public License version 25 2 along with this work; if not, write to the Free Software Foundation, 26 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 27 28 Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 29 or visit www.oracle.com if you need additional information or have any 30 questions. 31 --> 32 </head> 33 <body bgcolor="#FFFFFF"> 34 <b><font size=+1>General Information</font></b> 35 <p>Monitoring Framework SPI's is used internally by the ORB to instrument 36 for JMX based Management and Monitoring. The 37 <br>framework is very generic and easy to use and acts as facade to retrieve 38 the information from the running CORBA system. 39 <p>This framework helps in building a nice Hierarchical Structure of Monitored 40 Objects that contains Monitored Attributes. 41 <br>com.sun.corba.se.spi.orb.ORB has an API to get the RootMonitoredObject 42 and then User can traverse through the tree to 43 <br>either instrument or retrieve the information for Monitoring. 44 <h1> 45 <b><font size=+1>Code Snippet to Instrument Connection Monitored Object</font></b></h1> 46 This example shows on how to instrument CorbaConnectionImpl 's attributes. 47 It exposes two 48 <br>attributes, namely 49 <p>1. Connection State 50 <br>2. Response time statistics to Appeserver Admin Console or CLI 51 <br> 52 <h2> 53 <b><font size=+1>1. Instrumenting Connection State</font></b></h2> 54 /** 55 <br> * Code Snippet to Instrument Connection Monitored Object 56 with 57 <br> * ConnectionState Monitored Attribute. Steps to follow 58 <br> * 59 <br> * Step 1: Define a Monitored Attribute (ConnectionStateMonitoredAttribute) 60 Class by extending 61 <br> * 62 StringMonitoredAttributeBase 63 <br> * 64 <br> * Step 2: Create Connection Manager Monitored Object and 65 add that to 66 <br> * 67 Root Monitored Object. 68 <br> * 69 <br> * Step 3: Create Connection Monitored Object and 70 add it to Connection Manager Monitored Object 71 <br> * 72 <br> * Step 4: Instantiate Concrete Attribute (ConnectionStateMonitoredAttribute) 73 Class and add that to 74 <br> * 75 the Connection MonitoredObject 76 <br> * 77 <br> * Step 5: Adds ConnectionMonitoredObject to ConnectionManagerMonitoredObject 78 <br> * 79 <br> */ 80 <p>/** 81 <br> * Step 1: Define a Monitored Attribute Class by extending 82 <br> * 83 StringMonitoredAttributeBase 84 <br> */ 85 <p>/** 86 <br> * ConnectionState gets the value on demand. 87 <br> */ 88 <br>#import com.sun.corba.se.spi.monitoring.LongMonitoredAttributeBase 89 <br>#import com.sun.corba.se.spi.transport.CorbaConnection; 90 <p>public class ConnectionStateMonitoredAttribute extends StringMonitoredAttributeBase 91 <br>{ 92 <br> CorbaConnection connection; 93 <br> public ConnectionInUseMonitoredAttribute( String 94 name, String desc, 95 <br> CorbaConnection con ) 96 <br> { 97 <br> super( name, desc ); 98 <br> connection = con; 99 <br> } 100 <p> public Object getValue( ) { 101 <br> // Delegate the getValue 102 call to connection 103 <br> // so, there is no state 104 maintained in this attribute object itself 105 <br> // and also the locking 106 will be the responsibility of Connection 107 <br> // Object. By doing this 108 we will avoid global locking and possibly 109 <br> // avoiding the bottleneck 110 <br> return connection.getState( 111 ); 112 <br> } 113 <p> // IMPORTANT: In this case we don't have to implement 114 clearState() method 115 <br> // If there is a need to implement this method like 116 for POACounter, the 117 <br> // call again can be delegated to the Object which 118 maintains the real 119 <br> // state. clearState() is invoked whenever there 120 is a call to CORBAMBean.startMonitoring() 121 <br>} 122 <br> 123 <p>/** 124 <br> * Step 2: Create Connection Manager Monitored Object and 125 add that to 126 <br> * Root 127 Monitored Object. 128 <br> */ 129 <br>import com.sun.corba.se.spi.monitoring.MonitoringFactories; 130 <br>import com.sun.corba.se.spi.monitoring.MonitoredObject; 131 <p>private static MonitoredObject connectionManagerMonitoredObject; 132 <br>private static MonitoredObject connectionMonitoredObject; 133 <br> 134 <p> private void instrumentConnectionManager( ) { 135 <br> connectionManagerMonitoredObject 136 = 137 <br> 138 MonitoringFactories.getMonitoredObjectFactory().createMonitoredObject( 139 <br> 140 "ConnectionManagerMonitoredObject", 141 <br> 142 "Used to Monitor the stats on All IIOP Connections " ); 143 <br> orb.getRootMonitoredObject().addChild(connectionManagerMonitoredObject 144 ); 145 <br> } 146 <br> 147 <p>/** 148 <br> * Step 3: Create Connection Monitored Object and 149 add it to Connection Manager Monitored Object 150 <br> * 151 <br> * Step 4: Instantiate Concrete Attribute (ConnectionStateMonitoredAttribute) 152 Class and add that to 153 <br> * 154 the Connection MonitoredObject 155 <br> * 156 <br> * Step 5: Add ConnectionMonitoredObject to ConnectionManagerMonitoredObject 157 <br> */ 158 <br>private void instrumentConnectionObject( CorbConnection connection 159 ) { 160 <br> // Step 3 161 <br> MonitoredObject connectionMonitoredObject = 162 <br> MonitoringFactories.getMonitoredObjectFactory().createMonitoredObject( 163 <br> 164 connection.getName(), 165 <br> 166 "Used to Monitor the stats on one connection" ); 167 <br> // Step 4 168 <br> ConnectionStateMonitoredAttribute connectionState 169 = 170 <br> new ConnectionStateMonitoredAttribute( 171 "Connection_State", 172 <br> 173 "Provides the state of the IIOP Connection ...", connection ); 174 <br> connectionMonitoredObject.addAttribute( connectionState 175 ); 176 <br> // Step 5 177 <br> connectionManagerMonitoredObject.addChild( connectionMonitoredObject 178 ); 179 <br>} 180 <br> 181 <br> 182 <p><b><font size=+1>Code Snippet to Instrument A Statistic Type Monitored 183 Attribute</font></b> 184 <p>/** 185 <br> * Assuming ConnectionMonitoredObject is already added 186 to the MonitoredObject Hierarchy. 187 <br> * This example code shows how to instrument ConnectionMonitoredObject 188 with a new 189 <br> * StatisticMonitoredAttribute. 190 <br> * 191 <br> * IMPORTANT: StatisticsMonitoredAttribute 192 is mostly write mostly and read sparingly, i.e., 193 <br> * the frequency of writes(Collecting samples) 194 is high. It is the responsibility of user to synchronize 195 <br> * the sample() method and the StatisticMonitoredAttribute 196 will synchronize clearState() and 197 <br> * getValue() using the mutex object sent. 198 <br> */ 199 <br>private void instrumentStatsToConnectionObject( MonitoredObject connectionMonitoredObject 200 ) { 201 <br> // Step 4 202 <br> StatisticsAccumulator connectRequestStatsAccumulator 203 = 204 <br> // Microseconds is the unit 205 used for statistics measure 206 <br> new StatisticsAccumulator( 207 "Micro Seconds" ); 208 <p> // Pass Name, Description, Statistic Accumulator 209 Instance, Mutex (The 210 <br> // Object on which we need to synchronize for stats 211 sample collection) 212 <br> StatisticMonitoredAttribute sm = new StatisticMonitoredAttribute( 213 <br> connection.getName() + "Stats", 214 <br> "Connection Request Stats", 215 connectRequestStatsAccumulator, this ); 216 <p> connectionMonitoredObject.addAttribute( sm ); 217 <br> 218 <p> // Now, The user can accumulate the samples by calling 219 into 220 <br> // connectRequestStatsAccumulator.sample( <value> 221 ); 222 <br> // Finally When ASAdmin request for the value of 223 this Stats Monitored Attribute 224 <br> // by using standard getValue() call. It will return 225 a formatted Stats Value like 226 <br> // For Example 227 <br> // 228 <br> // Minimum Value = 200 Microseconds 229 <br> // Maximum Value = 928 Microseconds 230 <br> // Average Value = 523 Microseconds 231 <br> // Standard Deviation = 53.72 Microseconds 232 <br> // Sample Collected = 435 233 <p>} 234 <p><b><font size=+1>Caution On Global Locking (Synchronization):</font></b> 235 <p>It's important to make sure that collecting Stats and other state information 236 for monitoring doesn't impact performance. Please look at the following 237 don'ts 238 <br>to understand better. 239 <p><u>Do not add a special mutex for synchronizing MonitoredObject:</u> 240 <br>Let's take an example of exposing a counter that counts Requests on 241 this connection and 2 possible ways of doing this 242 <br>1. Define Counter by extending LongMonitoredAttributeBase 243 <br> public class Counter extends LongMonitoredAttributeBase 244 { 245 <br> private long counter; 246 <br> 247 <br> Counter( String name, String 248 desc ) { 249 <br> 250 super( name, desc ); 251 <br> } 252 <br> 253 <br> public synchronized 254 void increment( ) { 255 <br> 256 counter++; 257 <br> } 258 <p> public synchronized 259 Object getValue( ) { 260 <br> 261 return new Long( counter ); 262 <br> } 263 <br> } 264 <br> 265 <p>2. Or Define a RequestCounter by extending LongMonitoredAttributeBase 266 again, but no special 267 <br> synchronization is done 268 <p> public class RequestCounter extends LongMonitoredAttributeBase 269 { 270 <br> private CorbaConnection 271 connection; 272 <br> RequestCounter( String name, 273 String desc, CorbaConnection con ) { 274 <br> 275 super( name, desc ); 276 <br> 277 connection = con; 278 <br> } 279 <p> public Object getValue( ) 280 { 281 <br> 282 return connection.getRequestCount( ); 283 <br> } 284 <br> } 285 <p> The problem with Alternative (1) is that there may 286 be unneccesary extra synchronization happening for every method and it 287 may become a bottle neck 288 <br> particularly if this object is accessed quite 289 often. In Alternative (2), the synchronization happens only in the Connection 290 object and no special sync 291 <br> is required in the RequestCounter object. 292 <br> 293 <p><b><font size=+1>Important Thing To Know On StatisticMonitoredAttribute 294 type:</font></b> 295 <br>The clearState() and getValue() call will be synchronized using the 296 mutex passed by the external object, but sample() method in StatisticsAccumulator 297 <br>is not synchronized. It is the responsibility of user to synchronize 298 to make sure that the samples collected (The mutex passed into the StatisticsAccumulator must be the one used to synchronize calls to sample() ). 299 <br> 300 <p>@since JDK1.5 @serial exclude 301 </body> 302 </html>