package.html revision 608:7e06bf1dcb09
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 9Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. 10DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 11 12This code is free software; you can redistribute it and/or modify it 13under the terms of the GNU General Public License version 2 only, as 14published by the Free Software Foundation. Oracle designates this 15particular file as subject to the "Classpath" exception as provided 16by Oracle in the LICENSE file that accompanied this code. 17 18This code is distributed in the hope that it will be useful, but WITHOUT 19ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 20FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 21version 2 for more details (a copy is included in the LICENSE file that 22accompanied this code). 23 24You should have received a copy of the GNU General Public License version 252 along with this work; if not, write to the Free Software Foundation, 26Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 27 28Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 29or visit www.oracle.com if you need additional information or have any 30questions. 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 36for JMX based Management and Monitoring. The 37<br>framework is very generic and easy to use and acts as facade to retrieve 38the information from the running CORBA system. 39<p>This framework helps in building a nice Hierarchical Structure of Monitored 40Objects that contains Monitored Attributes. 41<br>com.sun.corba.se.spi.orb.ORB has an API to get the RootMonitoredObject 42and 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> 46This example shows on how to instrument CorbaConnectionImpl 's attributes. 47It 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 56with 57<br> * ConnectionState Monitored Attribute. Steps to follow 58<br> * 59<br> * Step 1: Define a Monitored Attribute (ConnectionStateMonitoredAttribute) 60Class by extending 61<br> * 62StringMonitoredAttributeBase 63<br> * 64<br> * Step 2: Create Connection Manager Monitored Object and 65add that to 66<br> * 67Root Monitored Object. 68<br> * 69<br> * Step 3: Create Connection Monitored Object and 70add it to Connection Manager Monitored Object 71<br> * 72<br> * Step 4: Instantiate Concrete Attribute (ConnectionStateMonitoredAttribute) 73Class and add that to 74<br> * 75the 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> * 83StringMonitoredAttributeBase 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 94name, 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 102call to connection 103<br> // so, there is no state 104maintained in this attribute object itself 105<br> // and also the locking 106will be the responsibility of Connection 107<br> // Object. By doing this 108we 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 114clearState() method 115<br> // If there is a need to implement this method like 116for POACounter, the 117<br> // call again can be delegated to the Object which 118maintains the real 119<br> // state. clearState() is invoked whenever there 120is a call to CORBAMBean.startMonitoring() 121<br>} 122<br> 123<p>/** 124<br> * Step 2: Create Connection Manager Monitored Object and 125add that to 126<br> * Root 127Monitored 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> 138MonitoringFactories.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 149add it to Connection Manager Monitored Object 150<br> * 151<br> * Step 4: Instantiate Concrete Attribute (ConnectionStateMonitoredAttribute) 152Class and add that to 153<br> * 154the 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> 164connection.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 183Attribute</font></b> 184<p>/** 185<br> * Assuming ConnectionMonitoredObject is already added 186to the MonitoredObject Hierarchy. 187<br> * This example code shows how to instrument ConnectionMonitoredObject 188with a new 189<br> * StatisticMonitoredAttribute. 190<br> * 191<br> * IMPORTANT: StatisticsMonitoredAttribute 192is mostly write mostly and read sparingly, i.e., 193<br> * the frequency of writes(Collecting samples) 194is high. It is the responsibility of user to synchronize 195<br> * the sample() method and the StatisticMonitoredAttribute 196will 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 205used for statistics measure 206<br> new StatisticsAccumulator( 207"Micro Seconds" ); 208<p> // Pass Name, Description, Statistic Accumulator 209Instance, Mutex (The 210<br> // Object on which we need to synchronize for stats 211sample collection) 212<br> StatisticMonitoredAttribute sm = new StatisticMonitoredAttribute( 213<br> connection.getName() + "Stats", 214<br> "Connection Request Stats", 215connectRequestStatsAccumulator, this ); 216<p> connectionMonitoredObject.addAttribute( sm ); 217<br> 218<p> // Now, The user can accumulate the samples by calling 219into 220<br> // connectRequestStatsAccumulator.sample( <value> 221); 222<br> // Finally When ASAdmin request for the value of 223this Stats Monitored Attribute 224<br> // by using standard getValue() call. It will return 225a 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 236for monitoring doesn't impact performance. Please look at the following 237don'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 241this 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 248desc ) { 249<br> 250super( name, desc ); 251<br> } 252<br> 253<br> public synchronized 254void increment( ) { 255<br> 256counter++; 257<br> } 258<p> public synchronized 259Object getValue( ) { 260<br> 261return new Long( counter ); 262<br> } 263<br> } 264<br> 265<p>2. Or Define a RequestCounter by extending LongMonitoredAttributeBase 266again, but no special 267<br> synchronization is done 268<p> public class RequestCounter extends LongMonitoredAttributeBase 269{ 270<br> private CorbaConnection 271connection; 272<br> RequestCounter( String name, 273String desc, CorbaConnection con ) { 274<br> 275super( name, desc ); 276<br> 277connection = con; 278<br> } 279<p> public Object getValue( ) 280{ 281<br> 282return connection.getRequestCount( ); 283<br> } 284<br> } 285<p> The problem with Alternative (1) is that there may 286be unneccesary extra synchronization happening for every method and it 287may become a bottle neck 288<br> particularly if this object is accessed quite 289often. In Alternative (2), the synchronization happens only in the Connection 290object 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 294type:</font></b> 295<br>The clearState() and getValue() call will be synchronized using the 296mutex passed by the external object, but sample() method in StatisticsAccumulator 297<br>is not synchronized. It is the responsibility of user to synchronize 298to 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> 303