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>&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
56with
57<br>&nbsp;*&nbsp; ConnectionState Monitored Attribute. Steps to follow
58<br>&nbsp;*
59<br>&nbsp;*&nbsp; Step 1: Define a Monitored Attribute (ConnectionStateMonitoredAttribute)
60Class by extending
61<br>&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
62StringMonitoredAttributeBase
63<br>&nbsp;*
64<br>&nbsp;*&nbsp; Step 2: Create Connection Manager Monitored Object and
65add that to
66<br>&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
67Root Monitored Object.
68<br>&nbsp;*
69<br>&nbsp;*&nbsp; Step 3: Create Connection Monitored Object&nbsp; and
70add it to Connection Manager Monitored Object
71<br>&nbsp;*
72<br>&nbsp;*&nbsp; Step 4: Instantiate Concrete Attribute (ConnectionStateMonitoredAttribute)
73Class and add that to
74<br>&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
75the 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;
83StringMonitoredAttributeBase
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
94name, 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
102call to connection
103<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // so, there is no state
104maintained in this attribute object itself
105<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // and also the locking
106will be the responsibility of Connection
107<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Object. By doing this
108we 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
114clearState() method
115<br>&nbsp;&nbsp;&nbsp; // If there is a need to implement this method like
116for POACounter, the
117<br>&nbsp;&nbsp;&nbsp; // call again can be delegated to the Object which
118maintains the real
119<br>&nbsp;&nbsp;&nbsp; // state. clearState() is invoked whenever there
120is a call to CORBAMBean.startMonitoring()
121<br>}
122<br>&nbsp;
123<p>/**
124<br>&nbsp;*&nbsp; Step 2: Create Connection Manager Monitored Object and
125add that to
126<br>&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Root
127Monitored 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;
138MonitoringFactories.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
149add it to Connection Manager Monitored Object
150<br>&nbsp; *
151<br>&nbsp; *&nbsp; Step 4: Instantiate Concrete Attribute (ConnectionStateMonitoredAttribute)
152Class and add that to
153<br>&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
154the 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;
164connection.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
183Attribute</font></b>
184<p>/**
185<br>&nbsp; *&nbsp; Assuming ConnectionMonitoredObject is already added
186to the MonitoredObject Hierarchy.
187<br>&nbsp; *&nbsp; This example code shows how to instrument ConnectionMonitoredObject
188with a new
189<br>&nbsp; *&nbsp;&nbsp; StatisticMonitoredAttribute.
190<br>&nbsp; *
191<br>&nbsp; *&nbsp;&nbsp;&nbsp; IMPORTANT: StatisticsMonitoredAttribute
192is mostly write mostly and read sparingly, i.e.,
193<br>&nbsp; *&nbsp;&nbsp;&nbsp; the frequency of writes(Collecting samples)
194is high.&nbsp; It is the responsibility of user to synchronize
195<br>&nbsp; *&nbsp;&nbsp;&nbsp; the sample() method and the StatisticMonitoredAttribute
196will 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
205used 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
209Instance, Mutex (The
210<br>&nbsp;&nbsp;&nbsp; // Object on which we need to synchronize for stats
211sample 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",
215connectRequestStatsAccumulator, 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
219into
220<br>&nbsp;&nbsp;&nbsp; // connectRequestStatsAccumulator.sample( &lt;value>
221);
222<br>&nbsp;&nbsp;&nbsp; // Finally When ASAdmin request for the value of
223this Stats Monitored Attribute
224<br>&nbsp;&nbsp;&nbsp; // by using standard getValue() call. It will return
225a 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
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>&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
248desc ) {
249<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
250super(&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
254void increment( ) {
255<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
256counter++;
257<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
258<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public synchronized
259Object getValue( ) {
260<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
261return 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
266again, 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
271connection;
272<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RequestCounter( String name,
273String desc, CorbaConnection con ) {
274<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
275super( name, desc );
276<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
277connection = 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;
282return 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
286be unneccesary extra synchronization happening for every method and it
287may become a bottle neck
288<br>&nbsp;&nbsp;&nbsp;&nbsp; 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>&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
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>&nbsp;
300<p>@since JDK1.5 @serial exclude
301</body>
302</html>
303