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>&nbsp;
  52 <h2>
  53 <b><font size=+1>1. Instrumenting Connection State</font></b></h2>
  54 /**
  55 <br>&nbsp;*&nbsp; Code Snippet to Instrument Connection Monitored Object
  56 with
  57 <br>&nbsp;*&nbsp; ConnectionState Monitored Attribute. Steps to follow
  58 <br>&nbsp;*
  59 <br>&nbsp;*&nbsp; Step 1: Define a Monitored Attribute (ConnectionStateMonitoredAttribute)
  60 Class by extending
  61 <br>&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  62 StringMonitoredAttributeBase
  63 <br>&nbsp;*
  64 <br>&nbsp;*&nbsp; Step 2: Create Connection Manager Monitored Object and
  65 add that to
  66 <br>&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  67 Root Monitored Object.
  68 <br>&nbsp;*
  69 <br>&nbsp;*&nbsp; Step 3: Create Connection Monitored Object&nbsp; and
  70 add it to Connection Manager Monitored Object
  71 <br>&nbsp;*
  72 <br>&nbsp;*&nbsp; Step 4: Instantiate Concrete Attribute (ConnectionStateMonitoredAttribute)
  73 Class and add that to
  74 <br>&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  75 the Connection MonitoredObject
  76 <br>&nbsp;*
  77 <br>&nbsp;*&nbsp; Step 5: Adds ConnectionMonitoredObject to ConnectionManagerMonitoredObject
  78 <br>&nbsp;*
  79 <br>&nbsp;*/
  80 <p>/**
  81 <br>&nbsp; *&nbsp; Step 1: Define a Monitored Attribute Class by extending
  82 <br>&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  83 StringMonitoredAttributeBase
  84 <br>&nbsp; */
  85 <p>/**
  86 <br>&nbsp; *&nbsp; ConnectionState gets the value on demand.
  87 <br>&nbsp; */
  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>&nbsp;&nbsp;&nbsp; CorbaConnection connection;
  93 <br>&nbsp;&nbsp;&nbsp; public ConnectionInUseMonitoredAttribute( String
  94 name, String desc,
  95 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CorbaConnection con )
  96 <br>&nbsp;&nbsp;&nbsp; {
  97 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super( name, desc );
  98 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; connection = con;
  99 <br>&nbsp;&nbsp;&nbsp; }
 100 <p>&nbsp;&nbsp;&nbsp; public Object getValue( ) {
 101 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Delegate the getValue
 102 call to connection
 103 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // so, there is no state
 104 maintained in this attribute object itself
 105 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // and also the locking
 106 will be the responsibility of Connection
 107 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Object. By doing this
 108 we will avoid global locking and possibly
 109 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // avoiding the bottleneck
 110 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return connection.getState(
 111 );
 112 <br>&nbsp;&nbsp;&nbsp; }
 113 <p>&nbsp;&nbsp;&nbsp; // IMPORTANT: In this case we don't have to implement
 114 clearState() method
 115 <br>&nbsp;&nbsp;&nbsp; // If there is a need to implement this method like
 116 for POACounter, the
 117 <br>&nbsp;&nbsp;&nbsp; // call again can be delegated to the Object which
 118 maintains the real
 119 <br>&nbsp;&nbsp;&nbsp; // state. clearState() is invoked whenever there
 120 is a call to CORBAMBean.startMonitoring()
 121 <br>}
 122 <br>&nbsp;
 123 <p>/**
 124 <br>&nbsp;*&nbsp; Step 2: Create Connection Manager Monitored Object and
 125 add that to
 126 <br>&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Root
 127 Monitored Object.
 128 <br>&nbsp;*/
 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>&nbsp;
 134 <p>&nbsp;&nbsp;&nbsp; private void instrumentConnectionManager( ) {
 135 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; connectionManagerMonitoredObject
 136 =
 137 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 138 MonitoringFactories.getMonitoredObjectFactory().createMonitoredObject(
 139 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 140 "ConnectionManagerMonitoredObject",
 141 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 142 "Used to Monitor the stats on All IIOP Connections " );
 143 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; orb.getRootMonitoredObject().addChild(connectionManagerMonitoredObject
 144 );
 145 <br>&nbsp;&nbsp;&nbsp; }
 146 <br>&nbsp;
 147 <p>/**
 148 <br>&nbsp; *&nbsp; Step 3: Create Connection Monitored Object&nbsp; and
 149 add it to Connection Manager Monitored Object
 150 <br>&nbsp; *
 151 <br>&nbsp; *&nbsp; Step 4: Instantiate Concrete Attribute (ConnectionStateMonitoredAttribute)
 152 Class and add that to
 153 <br>&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 154 the Connection MonitoredObject
 155 <br>&nbsp; *
 156 <br>&nbsp; *&nbsp; Step 5: Add ConnectionMonitoredObject to ConnectionManagerMonitoredObject
 157 <br>&nbsp; */
 158 <br>private void instrumentConnectionObject( CorbConnection connection
 159 ) {
 160 <br>&nbsp;&nbsp;&nbsp; // Step 3
 161 <br>&nbsp;&nbsp;&nbsp; MonitoredObject connectionMonitoredObject =
 162 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MonitoringFactories.getMonitoredObjectFactory().createMonitoredObject(
 163 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 164 connection.getName(),
 165 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 166 "Used to Monitor the stats on one connection" );
 167 <br>&nbsp;&nbsp;&nbsp; // Step 4
 168 <br>&nbsp;&nbsp;&nbsp; ConnectionStateMonitoredAttribute connectionState
 169 =
 170 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new ConnectionStateMonitoredAttribute(
 171 "Connection_State",
 172 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 173 "Provides the state of the IIOP Connection ...",&nbsp; connection );
 174 <br>&nbsp;&nbsp;&nbsp; connectionMonitoredObject.addAttribute( connectionState
 175 );
 176 <br>&nbsp;&nbsp;&nbsp; // Step 5
 177 <br>&nbsp;&nbsp;&nbsp; connectionManagerMonitoredObject.addChild( connectionMonitoredObject
 178 );
 179 <br>}
 180 <br>&nbsp;
 181 <br>&nbsp;
 182 <p><b><font size=+1>Code Snippet to Instrument A Statistic Type Monitored
 183 Attribute</font></b>
 184 <p>/**
 185 <br>&nbsp; *&nbsp; Assuming ConnectionMonitoredObject is already added
 186 to the MonitoredObject Hierarchy.
 187 <br>&nbsp; *&nbsp; This example code shows how to instrument ConnectionMonitoredObject
 188 with a new
 189 <br>&nbsp; *&nbsp;&nbsp; StatisticMonitoredAttribute.
 190 <br>&nbsp; *
 191 <br>&nbsp; *&nbsp;&nbsp;&nbsp; IMPORTANT: StatisticsMonitoredAttribute
 192 is mostly write mostly and read sparingly, i.e.,
 193 <br>&nbsp; *&nbsp;&nbsp;&nbsp; the frequency of writes(Collecting samples)
 194 is high.&nbsp; It is the responsibility of user to synchronize
 195 <br>&nbsp; *&nbsp;&nbsp;&nbsp; the sample() method and the StatisticMonitoredAttribute
 196 will synchronize clearState() and
 197 <br>&nbsp; *&nbsp;&nbsp;&nbsp; getValue() using the mutex object sent.
 198 <br>&nbsp; */
 199 <br>private void instrumentStatsToConnectionObject( MonitoredObject connectionMonitoredObject&nbsp;
 200 ) {
 201 <br>&nbsp;&nbsp;&nbsp;&nbsp; // Step 4
 202 <br>&nbsp;&nbsp;&nbsp; StatisticsAccumulator connectRequestStatsAccumulator
 203 =
 204 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Microseconds is the unit
 205 used for statistics measure
 206 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new StatisticsAccumulator(
 207 "Micro Seconds" );
 208 <p>&nbsp;&nbsp;&nbsp; // Pass Name, Description, Statistic Accumulator
 209 Instance, Mutex (The
 210 <br>&nbsp;&nbsp;&nbsp; // Object on which we need to synchronize for stats
 211 sample collection)
 212 <br>&nbsp;&nbsp;&nbsp; StatisticMonitoredAttribute sm = new StatisticMonitoredAttribute(
 213 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; connection.getName() + "Stats",
 214 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "Connection Request Stats",
 215 connectRequestStatsAccumulator, this );
 216 <p>&nbsp;&nbsp;&nbsp; connectionMonitoredObject.addAttribute( sm );
 217 <br>&nbsp;
 218 <p>&nbsp;&nbsp;&nbsp; // Now, The user can accumulate the samples by calling
 219 into
 220 <br>&nbsp;&nbsp;&nbsp; // connectRequestStatsAccumulator.sample( &lt;value>
 221 );
 222 <br>&nbsp;&nbsp;&nbsp; // Finally When ASAdmin request for the value of
 223 this Stats Monitored Attribute
 224 <br>&nbsp;&nbsp;&nbsp; // by using standard getValue() call. It will return
 225 a formatted Stats Value like
 226 <br>&nbsp;&nbsp;&nbsp; //&nbsp; For Example
 227 <br>&nbsp;&nbsp;&nbsp; //
 228 <br>&nbsp;&nbsp;&nbsp; //&nbsp; Minimum Value = 200 Microseconds
 229 <br>&nbsp;&nbsp;&nbsp; //&nbsp; Maximum Value = 928 Microseconds
 230 <br>&nbsp;&nbsp;&nbsp; //&nbsp; Average Value = 523 Microseconds
 231 <br>&nbsp;&nbsp;&nbsp; //&nbsp; Standard Deviation = 53.72 Microseconds
 232 <br>&nbsp;&nbsp;&nbsp; //&nbsp; 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>&nbsp;&nbsp;&nbsp;&nbsp; public class Counter extends LongMonitoredAttributeBase
 244 {
 245 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private long counter;
 246 <br>&nbsp;
 247 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Counter( String name, String
 248 desc ) {
 249 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 250 super(&nbsp;name, desc );
 251 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
 252 <br>&nbsp;
 253 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public synchronized
 254 void increment( ) {
 255 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 256 counter++;
 257 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
 258 <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public synchronized
 259 Object getValue( ) {
 260 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 261 return new Long( counter );
 262 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
 263 <br>&nbsp;&nbsp;&nbsp; }
 264 <br>&nbsp;
 265 <p>2. Or Define a RequestCounter by extending LongMonitoredAttributeBase
 266 again, but no special
 267 <br>&nbsp;&nbsp;&nbsp; synchronization is done
 268 <p>&nbsp;&nbsp;&nbsp; public class RequestCounter extends LongMonitoredAttributeBase
 269 {
 270 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private CorbaConnection
 271 connection;
 272 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RequestCounter( String name,
 273 String desc, CorbaConnection con ) {
 274 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 275 super( name, desc );
 276 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 277 connection = con;
 278 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
 279 <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Object getValue( )
 280 {
 281 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 282 return connection.getRequestCount( );
 283 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
 284 <br>&nbsp;&nbsp;&nbsp; }
 285 <p>&nbsp;&nbsp;&nbsp; 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>&nbsp;&nbsp;&nbsp;&nbsp; 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>&nbsp;&nbsp;&nbsp;&nbsp; is required in the RequestCounter object.
 292 <br>&nbsp;
 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>&nbsp;
 300 <p>@since JDK1.5 @serial exclude
 301 </body>
 302 </html>