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]>