blob: 4a72719c0cfb42f017fba4585a3dba872f588f82 [file] [log] [blame]
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<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, 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>&nbsp;
<h2>
<b><font size=+1>1. Instrumenting Connection State</font></b></h2>
/**
<br>&nbsp;*&nbsp; Code Snippet to Instrument Connection Monitored Object
with
<br>&nbsp;*&nbsp; ConnectionState Monitored Attribute. Steps to follow
<br>&nbsp;*
<br>&nbsp;*&nbsp; Step 1: Define a Monitored Attribute (ConnectionStateMonitoredAttribute)
Class by extending
<br>&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
StringMonitoredAttributeBase
<br>&nbsp;*
<br>&nbsp;*&nbsp; Step 2: Create Connection Manager Monitored Object and
add that to
<br>&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Root Monitored Object.
<br>&nbsp;*
<br>&nbsp;*&nbsp; Step 3: Create Connection Monitored Object&nbsp; and
add it to Connection Manager Monitored Object
<br>&nbsp;*
<br>&nbsp;*&nbsp; Step 4: Instantiate Concrete Attribute (ConnectionStateMonitoredAttribute)
Class and add that to
<br>&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
the Connection MonitoredObject
<br>&nbsp;*
<br>&nbsp;*&nbsp; Step 5: Adds ConnectionMonitoredObject to ConnectionManagerMonitoredObject
<br>&nbsp;*
<br>&nbsp;*/
<p>/**
<br>&nbsp; *&nbsp; Step 1: Define a Monitored Attribute Class by extending
<br>&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
StringMonitoredAttributeBase
<br>&nbsp; */
<p>/**
<br>&nbsp; *&nbsp; ConnectionState gets the value on demand.
<br>&nbsp; */
<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>&nbsp;&nbsp;&nbsp; CorbaConnection connection;
<br>&nbsp;&nbsp;&nbsp; public ConnectionInUseMonitoredAttribute( String
name, String desc,
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CorbaConnection con )
<br>&nbsp;&nbsp;&nbsp; {
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super( name, desc );
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; connection = con;
<br>&nbsp;&nbsp;&nbsp; }
<p>&nbsp;&nbsp;&nbsp; public Object getValue( ) {
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Delegate the getValue
call to connection
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // so, there is no state
maintained in this attribute object itself
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // and also the locking
will be the responsibility of Connection
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Object. By doing this
we will avoid global locking and possibly
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // avoiding the bottleneck
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return connection.getState(
);
<br>&nbsp;&nbsp;&nbsp; }
<p>&nbsp;&nbsp;&nbsp; // IMPORTANT: In this case we don't have to implement
clearState() method
<br>&nbsp;&nbsp;&nbsp; // If there is a need to implement this method like
for POACounter, the
<br>&nbsp;&nbsp;&nbsp; // call again can be delegated to the Object which
maintains the real
<br>&nbsp;&nbsp;&nbsp; // state. clearState() is invoked whenever there
is a call to CORBAMBean.startMonitoring()
<br>}
<br>&nbsp;
<p>/**
<br>&nbsp;*&nbsp; Step 2: Create Connection Manager Monitored Object and
add that to
<br>&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Root
Monitored Object.
<br>&nbsp;*/
<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>&nbsp;
<p>&nbsp;&nbsp;&nbsp; private void instrumentConnectionManager( ) {
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; connectionManagerMonitoredObject
=
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
MonitoringFactories.getMonitoredObjectFactory().createMonitoredObject(
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
"ConnectionManagerMonitoredObject",
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
"Used to Monitor the stats on All IIOP Connections " );
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; orb.getRootMonitoredObject().addChild(connectionManagerMonitoredObject
);
<br>&nbsp;&nbsp;&nbsp; }
<br>&nbsp;
<p>/**
<br>&nbsp; *&nbsp; Step 3: Create Connection Monitored Object&nbsp; and
add it to Connection Manager Monitored Object
<br>&nbsp; *
<br>&nbsp; *&nbsp; Step 4: Instantiate Concrete Attribute (ConnectionStateMonitoredAttribute)
Class and add that to
<br>&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
the Connection MonitoredObject
<br>&nbsp; *
<br>&nbsp; *&nbsp; Step 5: Add ConnectionMonitoredObject to ConnectionManagerMonitoredObject
<br>&nbsp; */
<br>private void instrumentConnectionObject( CorbConnection connection
) {
<br>&nbsp;&nbsp;&nbsp; // Step 3
<br>&nbsp;&nbsp;&nbsp; MonitoredObject connectionMonitoredObject =
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MonitoringFactories.getMonitoredObjectFactory().createMonitoredObject(
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
connection.getName(),
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
"Used to Monitor the stats on one connection" );
<br>&nbsp;&nbsp;&nbsp; // Step 4
<br>&nbsp;&nbsp;&nbsp; ConnectionStateMonitoredAttribute connectionState
=
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new ConnectionStateMonitoredAttribute(
"Connection_State",
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
"Provides the state of the IIOP Connection ...",&nbsp; connection );
<br>&nbsp;&nbsp;&nbsp; connectionMonitoredObject.addAttribute( connectionState
);
<br>&nbsp;&nbsp;&nbsp; // Step 5
<br>&nbsp;&nbsp;&nbsp; connectionManagerMonitoredObject.addChild( connectionMonitoredObject
);
<br>}
<br>&nbsp;
<br>&nbsp;
<p><b><font size=+1>Code Snippet to Instrument A Statistic Type Monitored
Attribute</font></b>
<p>/**
<br>&nbsp; *&nbsp; Assuming ConnectionMonitoredObject is already added
to the MonitoredObject Hierarchy.
<br>&nbsp; *&nbsp; This example code shows how to instrument ConnectionMonitoredObject
with a new
<br>&nbsp; *&nbsp;&nbsp; StatisticMonitoredAttribute.
<br>&nbsp; *
<br>&nbsp; *&nbsp;&nbsp;&nbsp; IMPORTANT: StatisticsMonitoredAttribute
is mostly write mostly and read sparingly, i.e.,
<br>&nbsp; *&nbsp;&nbsp;&nbsp; the frequency of writes(Collecting samples)
is high.&nbsp; It is the responsibility of user to synchronize
<br>&nbsp; *&nbsp;&nbsp;&nbsp; the sample() method and the StatisticMonitoredAttribute
will synchronize clearState() and
<br>&nbsp; *&nbsp;&nbsp;&nbsp; getValue() using the mutex object sent.
<br>&nbsp; */
<br>private void instrumentStatsToConnectionObject( MonitoredObject connectionMonitoredObject&nbsp;
) {
<br>&nbsp;&nbsp;&nbsp;&nbsp; // Step 4
<br>&nbsp;&nbsp;&nbsp; StatisticsAccumulator connectRequestStatsAccumulator
=
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Microseconds is the unit
used for statistics measure
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new StatisticsAccumulator(
"Micro Seconds" );
<p>&nbsp;&nbsp;&nbsp; // Pass Name, Description, Statistic Accumulator
Instance, Mutex (The
<br>&nbsp;&nbsp;&nbsp; // Object on which we need to synchronize for stats
sample collection)
<br>&nbsp;&nbsp;&nbsp; StatisticMonitoredAttribute sm = new StatisticMonitoredAttribute(
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; connection.getName() + "Stats",
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "Connection Request Stats",
connectRequestStatsAccumulator, this );
<p>&nbsp;&nbsp;&nbsp; connectionMonitoredObject.addAttribute( sm );
<br>&nbsp;
<p>&nbsp;&nbsp;&nbsp; // Now, The user can accumulate the samples by calling
into
<br>&nbsp;&nbsp;&nbsp; // connectRequestStatsAccumulator.sample( &lt;value>
);
<br>&nbsp;&nbsp;&nbsp; // Finally When ASAdmin request for the value of
this Stats Monitored Attribute
<br>&nbsp;&nbsp;&nbsp; // by using standard getValue() call. It will return
a formatted Stats Value like
<br>&nbsp;&nbsp;&nbsp; //&nbsp; For Example
<br>&nbsp;&nbsp;&nbsp; //
<br>&nbsp;&nbsp;&nbsp; //&nbsp; Minimum Value = 200 Microseconds
<br>&nbsp;&nbsp;&nbsp; //&nbsp; Maximum Value = 928 Microseconds
<br>&nbsp;&nbsp;&nbsp; //&nbsp; Average Value = 523 Microseconds
<br>&nbsp;&nbsp;&nbsp; //&nbsp; Standard Deviation = 53.72 Microseconds
<br>&nbsp;&nbsp;&nbsp; //&nbsp; 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>&nbsp;&nbsp;&nbsp;&nbsp; public class Counter extends LongMonitoredAttributeBase
{
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private long counter;
<br>&nbsp;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Counter( String name, String
desc ) {
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
super(&nbsp;name, desc );
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
<br>&nbsp;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public synchronized
void increment( ) {
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
counter++;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public synchronized
Object getValue( ) {
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return new Long( counter );
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
<br>&nbsp;&nbsp;&nbsp; }
<br>&nbsp;
<p>2. Or Define a RequestCounter by extending LongMonitoredAttributeBase
again, but no special
<br>&nbsp;&nbsp;&nbsp; synchronization is done
<p>&nbsp;&nbsp;&nbsp; public class RequestCounter extends LongMonitoredAttributeBase
{
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private CorbaConnection
connection;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RequestCounter( String name,
String desc, CorbaConnection con ) {
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
super( name, desc );
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
connection = con;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Object getValue( )
{
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return connection.getRequestCount( );
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
<br>&nbsp;&nbsp;&nbsp; }
<p>&nbsp;&nbsp;&nbsp; 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>&nbsp;&nbsp;&nbsp;&nbsp; particularly if this object is accessed quite
often. In Alternative (2), the synchronization happens only in the Connection
object and no special sync
<br>&nbsp;&nbsp;&nbsp;&nbsp; is required in the RequestCounter object.
<br>&nbsp;
<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>&nbsp;
<p>@since JDK1.5 @serial exclude
</body>
</html>