| <!doctype html> |
| <html> |
| <head> |
| <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> |
| <meta name="GENERATOR" content="Mozilla/4.79C-CCK-MCD [en] (X11; U; SunOS 5.8 sun4u) [Netscape]"> |
| <title>package</title> |
| <!-- |
| |
| Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. |
| DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| |
| This code is free software; you can redistribute it and/or modify it |
| under the terms of the GNU General Public License version 2 only, as |
| published by the Free Software Foundation. Oracle designates this |
| particular file as subject to the "Classpath" exception as provided |
| by Oracle in the LICENSE file that accompanied this code. |
| |
| This code is distributed in the hope that it will be useful, but WITHOUT |
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| version 2 for more details (a copy is included in the LICENSE file that |
| accompanied this code). |
| |
| You should have received a copy of the GNU General Public License version |
| 2 along with this work; if not, write to the Free Software Foundation, |
| Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| |
| Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| or visit www.oracle.com if you need additional information or have any |
| questions. |
| --> |
| </head> |
| <body bgcolor="#FFFFFF"> |
| <b><font size=+1>General Information</font></b> |
| <p>Monitoring Framework SPI's is used internally by the ORB to instrument |
| for JMX based Management and Monitoring. The |
| <br>framework is very generic and easy to use and acts as facade to retrieve |
| the information from the running CORBA system. |
| <p>This framework helps in building a nice Hierarchical Structure of Monitored |
| Objects that contains Monitored Attributes. |
| <br>com.sun.corba.se.spi.orb.ORB has an API to get the RootMonitoredObject |
| and then User can traverse through the tree to |
| <br>either instrument or retrieve the information for Monitoring. |
| <h1> |
| <b><font size=+1>Code Snippet to Instrument Connection Monitored Object</font></b></h1> |
| This example shows on how to instrument CorbaConnectionImpl 's attributes. |
| It exposes two |
| <br>attributes, namely |
| <p>1. Connection State |
| <br>2. Response time statistics to Appeserver Admin Console or CLI |
| <br> |
| <h2> |
| <b><font size=+1>1. Instrumenting Connection State</font></b></h2> |
| /** |
| <br> * Code Snippet to Instrument Connection Monitored Object |
| with |
| <br> * ConnectionState Monitored Attribute. Steps to follow |
| <br> * |
| <br> * Step 1: Define a Monitored Attribute (ConnectionStateMonitoredAttribute) |
| Class by extending |
| <br> * |
| StringMonitoredAttributeBase |
| <br> * |
| <br> * Step 2: Create Connection Manager Monitored Object and |
| add that to |
| <br> * |
| Root Monitored Object. |
| <br> * |
| <br> * Step 3: Create Connection Monitored Object and |
| add it to Connection Manager Monitored Object |
| <br> * |
| <br> * Step 4: Instantiate Concrete Attribute (ConnectionStateMonitoredAttribute) |
| Class and add that to |
| <br> * |
| the Connection MonitoredObject |
| <br> * |
| <br> * Step 5: Adds ConnectionMonitoredObject to ConnectionManagerMonitoredObject |
| <br> * |
| <br> */ |
| <p>/** |
| <br> * Step 1: Define a Monitored Attribute Class by extending |
| <br> * |
| StringMonitoredAttributeBase |
| <br> */ |
| <p>/** |
| <br> * ConnectionState gets the value on demand. |
| <br> */ |
| <br>#import com.sun.corba.se.spi.monitoring.LongMonitoredAttributeBase |
| <br>#import com.sun.corba.se.spi.transport.CorbaConnection; |
| <p>public class ConnectionStateMonitoredAttribute extends StringMonitoredAttributeBase |
| <br>{ |
| <br> CorbaConnection connection; |
| <br> public ConnectionInUseMonitoredAttribute( String |
| name, String desc, |
| <br> CorbaConnection con ) |
| <br> { |
| <br> super( name, desc ); |
| <br> connection = con; |
| <br> } |
| <p> public Object getValue( ) { |
| <br> // Delegate the getValue |
| call to connection |
| <br> // so, there is no state |
| maintained in this attribute object itself |
| <br> // and also the locking |
| will be the responsibility of Connection |
| <br> // Object. By doing this |
| we will avoid global locking and possibly |
| <br> // avoiding the bottleneck |
| <br> return connection.getState( |
| ); |
| <br> } |
| <p> // IMPORTANT: In this case we don't have to implement |
| clearState() method |
| <br> // If there is a need to implement this method like |
| for POACounter, the |
| <br> // call again can be delegated to the Object which |
| maintains the real |
| <br> // state. clearState() is invoked whenever there |
| is a call to CORBAMBean.startMonitoring() |
| <br>} |
| <br> |
| <p>/** |
| <br> * Step 2: Create Connection Manager Monitored Object and |
| add that to |
| <br> * Root |
| Monitored Object. |
| <br> */ |
| <br>import com.sun.corba.se.spi.monitoring.MonitoringFactories; |
| <br>import com.sun.corba.se.spi.monitoring.MonitoredObject; |
| <p>private static MonitoredObject connectionManagerMonitoredObject; |
| <br>private static MonitoredObject connectionMonitoredObject; |
| <br> |
| <p> private void instrumentConnectionManager( ) { |
| <br> connectionManagerMonitoredObject |
| = |
| <br> |
| MonitoringFactories.getMonitoredObjectFactory().createMonitoredObject( |
| <br> |
| "ConnectionManagerMonitoredObject", |
| <br> |
| "Used to Monitor the stats on All IIOP Connections " ); |
| <br> orb.getRootMonitoredObject().addChild(connectionManagerMonitoredObject |
| ); |
| <br> } |
| <br> |
| <p>/** |
| <br> * Step 3: Create Connection Monitored Object and |
| add it to Connection Manager Monitored Object |
| <br> * |
| <br> * Step 4: Instantiate Concrete Attribute (ConnectionStateMonitoredAttribute) |
| Class and add that to |
| <br> * |
| the Connection MonitoredObject |
| <br> * |
| <br> * Step 5: Add ConnectionMonitoredObject to ConnectionManagerMonitoredObject |
| <br> */ |
| <br>private void instrumentConnectionObject( CorbConnection connection |
| ) { |
| <br> // Step 3 |
| <br> MonitoredObject connectionMonitoredObject = |
| <br> MonitoringFactories.getMonitoredObjectFactory().createMonitoredObject( |
| <br> |
| connection.getName(), |
| <br> |
| "Used to Monitor the stats on one connection" ); |
| <br> // Step 4 |
| <br> ConnectionStateMonitoredAttribute connectionState |
| = |
| <br> new ConnectionStateMonitoredAttribute( |
| "Connection_State", |
| <br> |
| "Provides the state of the IIOP Connection ...", connection ); |
| <br> connectionMonitoredObject.addAttribute( connectionState |
| ); |
| <br> // Step 5 |
| <br> connectionManagerMonitoredObject.addChild( connectionMonitoredObject |
| ); |
| <br>} |
| <br> |
| <br> |
| <p><b><font size=+1>Code Snippet to Instrument A Statistic Type Monitored |
| Attribute</font></b> |
| <p>/** |
| <br> * Assuming ConnectionMonitoredObject is already added |
| to the MonitoredObject Hierarchy. |
| <br> * This example code shows how to instrument ConnectionMonitoredObject |
| with a new |
| <br> * StatisticMonitoredAttribute. |
| <br> * |
| <br> * IMPORTANT: StatisticsMonitoredAttribute |
| is mostly write mostly and read sparingly, i.e., |
| <br> * the frequency of writes(Collecting samples) |
| is high. It is the responsibility of user to synchronize |
| <br> * the sample() method and the StatisticMonitoredAttribute |
| will synchronize clearState() and |
| <br> * getValue() using the mutex object sent. |
| <br> */ |
| <br>private void instrumentStatsToConnectionObject( MonitoredObject connectionMonitoredObject |
| ) { |
| <br> // Step 4 |
| <br> StatisticsAccumulator connectRequestStatsAccumulator |
| = |
| <br> // Microseconds is the unit |
| used for statistics measure |
| <br> new StatisticsAccumulator( |
| "Micro Seconds" ); |
| <p> // Pass Name, Description, Statistic Accumulator |
| Instance, Mutex (The |
| <br> // Object on which we need to synchronize for stats |
| sample collection) |
| <br> StatisticMonitoredAttribute sm = new StatisticMonitoredAttribute( |
| <br> connection.getName() + "Stats", |
| <br> "Connection Request Stats", |
| connectRequestStatsAccumulator, this ); |
| <p> connectionMonitoredObject.addAttribute( sm ); |
| <br> |
| <p> // Now, The user can accumulate the samples by calling |
| into |
| <br> // connectRequestStatsAccumulator.sample( <value> |
| ); |
| <br> // Finally When ASAdmin request for the value of |
| this Stats Monitored Attribute |
| <br> // by using standard getValue() call. It will return |
| a formatted Stats Value like |
| <br> // For Example |
| <br> // |
| <br> // Minimum Value = 200 Microseconds |
| <br> // Maximum Value = 928 Microseconds |
| <br> // Average Value = 523 Microseconds |
| <br> // Standard Deviation = 53.72 Microseconds |
| <br> // Sample Collected = 435 |
| <p>} |
| <p><b><font size=+1>Caution On Global Locking (Synchronization):</font></b> |
| <p>It's important to make sure that collecting Stats and other state information |
| for monitoring doesn't impact performance. Please look at the following |
| don'ts |
| <br>to understand better. |
| <p><u>Do not add a special mutex for synchronizing MonitoredObject:</u> |
| <br>Let's take an example of exposing a counter that counts Requests on |
| this connection and 2 possible ways of doing this |
| <br>1. Define Counter by extending LongMonitoredAttributeBase |
| <br> public class Counter extends LongMonitoredAttributeBase |
| { |
| <br> private long counter; |
| <br> |
| <br> Counter( String name, String |
| desc ) { |
| <br> |
| super( name, desc ); |
| <br> } |
| <br> |
| <br> public synchronized |
| void increment( ) { |
| <br> |
| counter++; |
| <br> } |
| <p> public synchronized |
| Object getValue( ) { |
| <br> |
| return new Long( counter ); |
| <br> } |
| <br> } |
| <br> |
| <p>2. Or Define a RequestCounter by extending LongMonitoredAttributeBase |
| again, but no special |
| <br> synchronization is done |
| <p> public class RequestCounter extends LongMonitoredAttributeBase |
| { |
| <br> private CorbaConnection |
| connection; |
| <br> RequestCounter( String name, |
| String desc, CorbaConnection con ) { |
| <br> |
| super( name, desc ); |
| <br> |
| connection = con; |
| <br> } |
| <p> public Object getValue( ) |
| { |
| <br> |
| return connection.getRequestCount( ); |
| <br> } |
| <br> } |
| <p> The problem with Alternative (1) is that there may |
| be unneccesary extra synchronization happening for every method and it |
| may become a bottle neck |
| <br> particularly if this object is accessed quite |
| often. In Alternative (2), the synchronization happens only in the Connection |
| object and no special sync |
| <br> is required in the RequestCounter object. |
| <br> |
| <p><b><font size=+1>Important Thing To Know On StatisticMonitoredAttribute |
| type:</font></b> |
| <br>The clearState() and getValue() call will be synchronized using the |
| mutex passed by the external object, but sample() method in StatisticsAccumulator |
| <br>is not synchronized. It is the responsibility of user to synchronize |
| to make sure that the samples collected (The mutex passed into the StatisticsAccumulator must be the one used to synchronize calls to sample() ). |
| <br> |
| <p>@since JDK1.5 @serial exclude |
| </body> |
| </html> |