aboutsummaryrefslogtreecommitdiff
path: root/src/share/classes/com/sun/corba/se/spi/monitoring/package.html
blob: 4a72719c0cfb42f017fba4585a3dba872f588f82 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
<!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>