leif 2002/10/01 08:24:00
Modified: instrument/src/xdocs instrumentables.xml menu.xml
Added: instrument/src/xdocs abstract-instrumentable-howto.xml
instrumentable-howto.xml instruments.xml
overview.xml
Log:
Take a first pass at the Instrument documentation. Still needs more work.
Revision Changes Path
1.3 +49 -193
jakarta-avalon-excalibur/instrument/src/xdocs/instrumentables.xml
Index: instrumentables.xml
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/instrument/src/xdocs/instrumentables.xml,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- instrumentables.xml 26 Sep 2002 06:34:54 -0000 1.2
+++ instrumentables.xml 1 Oct 2002 15:24:00 -0000 1.3
@@ -2,204 +2,60 @@
<document>
<header>
- <title>Excalibur Instrument - Enable Instrumenting</title>
+ <title>Excalibur Instrument - Instrumentables</title>
<authors>
- <person name="Berin Loritsch" email="[EMAIL PROTECTED]"/>
+ <person name="Leif Mortenson" email="[EMAIL PROTECTED]"/>
</authors>
</header>
<body>
- <s1 title="Coding for Instrumentation">
+ <s1 title="Instrumentables">
<p>
- There are different types of instrumentation we need to use,
depending
- on our purposes. Excalibur Instrument has two basic types:
- <code>CounterInstrument</code> and <code>ValueInstrument</code>.
The
- <code>CounterInstrument</code> allows us to take samples that
represent
- a count of events. The <code>ValueInstrument</code> allows you to
take
- samples that represent the current value.
- </p>
- <p>
- Excalibur Instrument knows how to take the raw samples, and bring
them
- in line with more useable numbers. It is not uncommon to want an
average
- value, a maximum value, or a minimum value for each sample period.
You
- do not have to do anything in your code to explicitly do that.
- </p>
- <p>
- Instrumentation has been designed from the start with performance
in mind
- you can feel comfortable instrumenting your code without worrying
about
- how it will effect performance. When your code is running in an
environment
- where it has not been registered with an InstrumentationManager,
the Instrument
- code acts as a noop. In cases where the your code is registered
with an
- InstrumentationManager, the Instrument is still a noop unless the
instrument
- output is actually been monitored. This makes it possible to place
- Instrumentation throughout your code just as would be done with
debug logging
- information. When the Instrument data is required, it can be
requested at any
- time. Even from a live running system.
- </p>
- </s1>
- <s1 title="Getting Started">
- <p>
- The first thing that you will need to do to Instrument enable your
class
- is to modify your class to implement the
<code>Instrumentable</code> interface.
- There are currently three ways of acomplishing this, each of which
are described
- in detail below. 1) Extend <code>AbstractInstrumentable</code>, 2)
Extend
- <code>AbstractLogEnabledInstrumentable</code> and 3) Implement
- <code>Instrumentable</code>.
- </p>
- <s2 title="Extending AbstractInstrumentable">
- <p>
- The first option works well in cases where your code does not
already have a
- super class. You simply extend the
<code>AbstractInstrumentable</code> class
- create and register your Instruments in your class's
constructor and then
- use the Instruments at the appropriate locations in your code.
All of the
- details of telling your class how to register itself with an
- <code>InstrumentManager</code> are taken care of for you.
- </p>
- <source>
-<![CDATA[
-]]>
- </source>
- </s2>
-
- <p>
- You will need to import the relavant classes from the
avalon-instrument.jar
- file.
- </p>
- <source>
-<![CDATA[
-import org.apache.excalibur.instrument.CounterInstrument;
-import org.apache.excalibur.instrument.Instrumentable;
-import org.apache.excalibur.instrument.Instrument;
-import org.apache.excalibur.instrument.ValueInstrument;
-]]>
- </source>
- <p>
- Once you do that, you need to implement the
<code>Instrumentable</code>
- interface or extend one of the available utility classes:
- <code>AbstractInstrumentable</code> or
- <code>AbstractLogEnabledInstrumentable</code>.
- </p>
-
- <p>
- Once you do that, you need to implement the
<code>Instrumentable</code>
- interface, and set up your instrumentation points. The
InstrumentManager,
- or the parent Instrumentable will assign the name to your
Instrumentable.
- That way we can easily determine what the heirarchy is.
- </p>
- <source>
-<![CDATA[
-public class DefaultExampleInstrumentable
- implements Instrumentable
-{
- public static final String INSTRUMENT_VALUE_NAME = "value";
- public static final String INSTRUMENT_COUNTER_NAME = "counter";
-
- /** Instrumentable Name assigned to this Instrumentable */
- private String m_instrumentableName;
-
- /** Instrument used to profile values */
- private ValueInstrument m_valueInstrument = new ValueInstrument(
INSTRUMENT_VALUE_NAME );
-
- /** Instrument used to profile a count of actions. */
- private CounterInstrument m_counterInstrument = new CounterInstrument(
INSTRUMENT_COUNTER_VALUE );
-
- /*---------------------------------------------------------------
- * Constructors
- *-------------------------------------------------------------*/
- public DefaultExampleInstrumentable()
- {}
-
- // Skip a bunch of other stuff....
-
- /*---------------------------------------------------------------
- * Instrumentable Methods
- *-------------------------------------------------------------*/
- /**
- * Sets the name for the Instrumentable. The Instrumentable Name is used
- * to uniquely identify the Instrumentable during the configuration of
- * the InstrumentManager and to gain access to an InstrumentableDescriptor
- * through the InstrumentManager. The value should be a string which does
- * not contain spaces or periods.
- * <p>
- * This value may be set by a parent Instrumentable, or by the
- * InstrumentManager using the value of the 'instrumentable' attribute in
- * the configuration of the component.
- *
- * @param name The name used to identify a Instrumentable.
- */
- public void setInstrumentableName( String name )
- {
- m_instrumentableName = name;
- }
-
- /**
- * Gets the name of the Instrumentable.
- *
- * @return The name used to identify a Instrumentable.
- */
- public String getInstrumentableName()
- {
- return m_instrumentableName;
- }
-
- /**
- * Obtain a reference to all the Instruments that the Instrumentable object
- * wishes to expose. All sampling is done directly through the
- * Instruments as opposed to the Instrumentable interface.
- *
- * @return An array of the Instruments available for profiling. Should
- * never be null. If there are no Instruments, then
- * EMPTY_INSTRUMENT_ARRAY can be returned. This should never be
- * the case though unless there are child Instrumentables with
- * Instruments.
- */
- public Instrument[] getInstruments()
- {
- return new Instrument[]
- {
- m_valueInstrument,
- m_counterInstrument
- };
- }
-
- /**
- * Any Object which implements Instrumentable can also make use of other
- * Instrumentable child objects. This method is used to tell the
- * InstrumentManager about them.
- *
- * @return An array of child Instrumentables. This method should never
- * return null. If there are no child Instrumentables, then
- * EMPTY_INSTRUMENTABLE_ARRAY can be returned.
- */
- public Instrumentable[] getChildInstrumentables()
- {
- // This instrumentable does not have any children.
- return Instrumentable.EMPTY_INSTRUMENTABLE_ARRAY;
- }
-}
-]]>
- </source>
- </s1>
- <s1 title="Using Instruments">
- <p>
- Lastly, you need to use your instrumentables. Excalibur Instrument
will
- skip the sampling and processing of values if no Manager or Client
is
- attached to them.
- </p>
- <source>
-<![CDATA[
-/**
- * Method that uses the instrumentables we have set up so far
- */
-Object lookup(String name)
-{
- // Do critical stuff
- m_valueInstrument.setValue( m_dictionary.size() );
- m_counterInstrument.increment();
-
- return m_dictionary.get( name );
-}
-]]>
- </source>
+ The Instrumentable interface is required to be able to register a
component with
+ an InstrumentManager. The interface makes it possible for the
InstrumentManager
+ to query the component about what Instruments and child
Instrumentables is making
+ available.
+ </p>
+ <p>
+ The interface provides four methods. The first two,
setInstrumentableName and
+ getInstrumentableName are used to get and set the name of the
Instrumentable.
+ This name is similar to a category name in logger frameworks. The
name is
+ required by the InstrumentManager to be able to provide clients
with a way to
+ request and access instrumentation output. The name should not
include any
+ periods as they are used as separators in a hierarchy of
Instrumentables and
+ their Instruments. The name of top level Instrumentable is usually
set by the
+ object which creates the component. Usually this is a container.
If the
+ creating object is not aware of the Instrument API then it is
possible that
+ setInstrumentableName will never be called. Components should be
able to
+ function properly under this condition. In the case of child
Instrumentables,
+ it is the responsibility of the parent to call
setInstrumentableName.
+ </p>
+ <p>
+ The third and fourth methods, getInstruments and
getChildInstrumentables, are
+ each called once by an InstrumentManager to query the
Instrumentable for a list
+ of the Instruments and child Instrumentables that is making
available.
+ </p>
+ <p>
+ Please see the <link
href="instrumentable-howto.html">Instrumentable How-To</link>
+ for an example.
+ </p>
+ <p>
+ Implementing the Instrumentable interface directly requires a
little bit of work,
+ but is necessary in cases where the parent class can not be
controlled. In most
+ situations, it is possible to extend one of the two helper classes
provided with
+ the API, AbstractInstrumentable and
AbstractLogEnabledInstrumentable. Either
+ of these classes provide methods to add Instruments and Child
Instrumentables to
+ the lists to be published. All of the above methods are handled
behind the scenes.
+ The second helper class is available for classes also wish to
extend the
+ AbstractLogEnabled class provided with Framework. (If this class
is used, then
+ Instrument requires that the avalon-framework.jar file be included
in the
+ classpath.)
+ </p>
+ <p>
+ Please see the
+ <link
href="abstract-instrumentable-howto.html">AbstractInstrumentable How-To</link>
+ for an example. An example of the AbstractLogEnabledInstrumentable
helper class is
+ not included as its usage is identical to AbstractInstrumentable.
+ </p>
</s1>
</body>
</document>
1.4 +16 -5 jakarta-avalon-excalibur/instrument/src/xdocs/menu.xml
Index: menu.xml
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/instrument/src/xdocs/menu.xml,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- menu.xml 26 Sep 2002 06:34:54 -0000 1.3
+++ menu.xml 1 Oct 2002 15:24:00 -0000 1.4
@@ -2,17 +2,28 @@
<project href="http://jakarta.apache.org/avalon/excalibur/instrument/"
name="Excalibur Instrument">
<title>Excalibur Instrument</title>
<body>
+ <menu name="About">
+ <item name="About Instrument" href="index.html"/>
+ <item name="Excalibur Home"
href="http://jakarta.apache.org/avalon/excalibur/index.html"/>
+ <item name="Download"
href="http://jakarta.apache.org/builds/jakarta-avalon-excalibur/release"/>
+ <item name="API Docs" href="api/"/>
+ </menu>
+ <menu name="Essentials">
+ <item name="Overview" href="overview.html"/>
+ <item name="Instrumentables" href="instrumentables.html"/>
+ <item name="Instruments" href="instruments.html"/>
+ </menu>
<menu name="Related">
+ <item name="Instrument Manager" href="../instrument-manager/"/>
+ <item name="Instrument Client" href="../instrument-client/"/>
<menu name="Containers">
<item href="../component/" name="Excalibur Component Manager"/>
<item href="../fortress/" name="Excalibur Fortress"/>
</menu>
</menu>
- <menu name="About">
- <item name="Overview" href="index.html"/>
- <item name="Enabling Instrumentation" href="instrumentables.html"/>
- <item name="Download"
href="http://jakarta.apache.org/builds/jakarta-avalon-excalibur/release/???"/>
- <item name="API Docs" href="api/"/>
+ <menu name="How To">
+ <item name="Implement Instrumentable" href="instrumentable-howto.html"/>
+ <item name="Extend AbstractInstrumentable"
href="abstract-instrumentable-howto.html"/>
</menu>
</body>
</project>
1.1
jakarta-avalon-excalibur/instrument/src/xdocs/abstract-instrumentable-howto.xml
Index: abstract-instrumentable-howto.xml
===================================================================
<?xml version="1.0"?>
<document>
<header>
<title>Excalibur Instrument - AbstractInstrumentable How-To</title>
<authors>
<person name="Leif Mortenson" email="[EMAIL PROTECTED]"/>
</authors>
</header>
<body>
<s1 title="AbstractInstrumentable How-Tos">
<p>
To do.
</p>
</s1>
</body>
</document>
1.1
jakarta-avalon-excalibur/instrument/src/xdocs/instrumentable-howto.xml
Index: instrumentable-howto.xml
===================================================================
<?xml version="1.0"?>
<document>
<header>
<title>Excalibur Instrument - Instrumentable How-To</title>
<authors>
<person name="Leif Mortenson" email="[EMAIL PROTECTED]"/>
</authors>
</header>
<body>
<s1 title="Instrumentable How-Tos">
<p>
To do.
</p>
</s1>
</body>
</document>
1.1 jakarta-avalon-excalibur/instrument/src/xdocs/instruments.xml
Index: instruments.xml
===================================================================
<?xml version="1.0"?>
<document>
<header>
<title>Excalibur Instrument - Instruments</title>
<authors>
<person name="Leif Mortenson" email="[EMAIL PROTECTED]"/>
</authors>
</header>
<body>
<s1 title="Instruments">
<p>
Instruments are the actual hooks used by a component to make
profiling or
instrumentation information available to the outside world.
Instruments are
created by a component during their initialization phase and then
referenced
throughout the life of the component. The Instruments should be
created whether
the component is registered with an InstrumentManager or not. This
removes the
necessity for the component to do anything special if not registered.
</p>
<p>
The Instruments themselves are designed to be extremely lightweight.
In cases
where an InstrumentManager is not present, or where it is present
but output is
not currently being collected, the Instrument effectively becomes a
noop.
</p>
<p>
There are currently two types of Instruments available for use by
components.
So far they have proven to be enough to profile any type of
quantitative
information.
</p>
<p>
The first is the CounterInstrument. Counters are used to, well,
count the number
of times that something happens. They can be used to keep track of
the number of
times a method is called, a resource is accessed, etc. The
CounterInstrument
provides two methods. The first, increment(), which ups the counter
by 1. And
the second, instrument( count ), which accepts any positive integer.
The later
method can be used in cases where increment would normally have to
be called a
large number of times. For example, the number of iterations in a
sort algorithm.
</p>
<p>
The second type of Instrument is the ValueInstrument.
ValueInstruments are used
to track quantities over time. Examples are the size of a pool, the
current
memory usage of the JVM, etc. ValueInstruments provide a single
method,
setValue( value ).
</p>
</s1>
</body>
</document>
1.1 jakarta-avalon-excalibur/instrument/src/xdocs/overview.xml
Index: overview.xml
===================================================================
<?xml version="1.0"?>
<document>
<header>
<title>Excalibur Instrument - Overview</title>
<authors>
<person name="Leif Mortenson" email="[EMAIL PROTECTED]"/>
</authors>
</header>
<body>
<s1 title="Why Instrument Was Created">
<p>
Instrument was created out of a desire to provide a standard API for
adding
profiling or instrumentation hooks into an application or class. As
any
application grows in complexity the ability to understand the
interactions
and resource usages of its individual components becomes
increasingly difficult.
</p>
<p>
Logging tools have helped by making it possible to maintain debug
and informational
log messages throughout the code. This output can be enabled or
disabled at will
and then used to help understand the flow of an application.
</p>
<p>
However, while logging is indispensable in many areas, it is not
very useful at
tracking quantitative information over time. There was a need to be
able to
collect information over time to be able to monitor quantities like
memory usage,
pool sizes, counts, and durations over time.
</p>
</s1>
<s1 title="When To Use Instrument">
<p>
Instrument is an API for enabling the collection of qualitative
information from a
component. The API itself has no dependencies on the Avalon
framework and can thus
be used to instrument any application.
</p>
<p>
Instrumenting an application should be thought of in the same way as
adding support
for logging. Just like logging, instrumentation can be very useful
in all phases
of an applications life. During development, information collected
can be
invaluable to help track down bottlenecks, leaks, or simply in
understanding the
flow of a system. Once an application has been released, the
instrument output
can be used to monitor the resources consumed by the application as
well as the
loads that are placed on it over time.
</p>
</s1>
<s1 title="Portability">
<p>
The Instrument API has been carefully designed in such a way as to
remove any
limitations on where components making use of the API can be used.
Most logger
APIs require that a logger be configured before components making
use of their
APIs will function correctly. Failing to configure the component
with a logger
will using result in NullPointerExceptions or similar problems.
</p>
<p>
Instrumentation takes a different approach by providing an opaque
API which makes
it possible for a component providing instrumentation output to
function the same
whether the output is being collected or not. Output is provided to
the outside
world by making use of Instrument instances within the component.
The component
will work identically even if run in an environment which is
completely unaware
of the Instrument API. This should remove all portability fears.
</p>
</s1>
<s1 title="Performance">
<p>
Another concern with any tool like this is performance. Many users
ask, "How will
instrumenting my component affect its performance." The answer is
that the
Instrument API was designed from the beginning with performance in
mind. When a
component implementing the Instrumentable interface is instantiated,
it must be
registered with an InstrumentManager. Upon registration, the
component is queried
for a list of any Instruments or child Instrumentables that it would
like to
publish. If the component is never registered, or until the time
that the
registered Instument output is actually needed, the Instruments them
selves are
effectively noops in the code. For this reason, other than in the
case of an
extremely tight loop, instruments can be added to code without any
fear of a
negative impact on their performance.
</p>
<p>
When an InstrumentManager receives a request for output from a
particular
Instrument, there will be a slight performance hit caused by the
actual collection
of the output. However, the collection of data points has been
designed to avoid
affecting performance as much as possible.
</p>
</s1>
<s1 title="Core Concepts">
<p>
When working with the Instrument API, there are two main classes
that you need to
be aware of.
</p>
<p>
The first is the Instrumentable interface. This interface must be
implemented by
any class wishing to be registered with an InstrumentManager and
then publish
Instrument output. The interface provides methods used by an
InstrumentManager
to query the component for its name, Instruments, as well as any
child
Instrumentable objects. See the
<link href="instrumentables.html">Instrumentables</link> section for
more
information.
</p>
<p>
The second is the Instrument interface. It should not be necessary
to implement
this interface yourself. The Instrument API provides to two
implementations which
have so far covered all requred types of output. The first is the
CounterInstrument which is used to count the number of times an
event takes place.
The second is the ValueInstrument which is useful for tracking
changes in a value
over time. Examples of the later are memory allocation, pool sizes
and durations.
See the <link href="instruments.html">Instruments</link> section for
more
information.
</p>
<p>
The Instrument API also provides InstrumentManager and
InstrumentManageable
interfaces. The InstrumentManager interface must be implemented by
any class
which wishes to act as an InstrumentManager. In most cases the
DefaultInstrumentManager can be used. It is provided by the
<link href="../instrument-manager/">Instrument Manager</link>
project.
</p>
<p>
The InstrumentManageable interface should be implemented by any
component which
needs to be able to have access to the InstrumentManager. In most
cases, only
elements of a container need to implement this interface.
</p>
<p>
In order to make use of the Instrumentation added to components,
they must be
registered with an Instrument Manager. If an Instrument Manager
aware container
is used, this will be automatic. Currently, both the
<link href="../component/">Excalibur Component Manager</link> and
<link href="../fortress/">Excalibur Fortress</link> know how to
manage and register
Instrumentable components.
</p>
<p>
Once an application is running with an active, users can connect to
the
InstrumentManager and request instrumentation output from any
registered
Instrument in the application. The most common method of connecting
to an
InstrumentManager is to make use of the
<link href="../instrument-client/">Instrument Client</link>. The
Instrument
Client provides a Swing based GUI that makes it easy to monitor
several Instruments
at once. For other options read over the documentation of the
<link href="../instrument-manager/">Instrument Manager</link>.
</p>
</s1>
</body>
</document>
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>