<?xml version="1.0" encoding="UTF-8"?>
<!--
 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
 distributed with this work for additional information
 regarding copyright ownership.  The ASF licenses this file
 to you under the Apache License, Version 2.0 (the
 "License"); you may not use this file except in compliance
 with the License.  You may obtain a copy of the License at
 
 http://www.apache.org/licenses/LICENSE-2.0
 
 Unless required by applicable law or agreed to in writing,
 software distributed under the License is distributed on an
 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.   
-->
<chapter id="ref_guide_instrumentation">
    <title>
        Instrumentation
    </title>
        <indexterm zone="ref_guide_instrumentation">
        <primary>
            instrumentation
        </primary>
    </indexterm>
    <para>
	OpenJPA provides the ability to instrument various aspects of runtime 
    operation.  Instrumentation involves an instrumentation provider for base instrumentation
    capabilities and instruments for instrumenting various aspects of OpenJPA.  OpenJPA
    includes a default instrumentation provider for JMX Platform MBeans.  MBean-based instruments
    are provided for the data cache, query cache, and query SQL cache.  When enabled,
    JMX-based remote monitoring tools such as 
    <ulink url="http://download.oracle.com/javase/6/docs/technotes/tools/share/jconsole.html"> 
    <classname>JConsole</classname></ulink> can be used to monitor various
    metrics tracked by OpenJPA's caches by accessing MBeans registered under domain 
    <classname>org.apache.openjpa</classname>.  Additionally, custom applications can gather metrics by using the 
    JMX API to query OpenJPA's MBeans.  The <classname>openjpa-integration-jmx</classname> 
    integration module contains an example of how to access the cache MBeans within program code.
    </para>
    <section id="ref_guide_instrumentation_config">
        <title>
            Configuration
        </title>
        <indexterm zone="ref_guide_instrumentation_config">
            <primary>
                configuration
            </primary>
        </indexterm>
        <para>
        Instrumentation is enabled using the <link linkend="openjpa.Instrumentation"><literal>openjpa.Instrumentation</literal> </link>
        configuration property.  The base value is the instrumentation provider.  The
        alias "jmx" enables the JMX Platform MBean provider.  Instruments are specified 
        on the <literal>Instrument</literal> attribute of the provider.  Multiple instruments can be specified
        by enclosing the value in single quotes and specifying each instrument or instrument
        alias as a comma separated list.  For example:
        </para>
        <programlisting>
            &lt;!--  Enable caches and cache statistics --&gt;
            &lt;property name="openjpa.DataCache" value="true(EnableStatistics=true)"/&gt;
            &lt;property name="openjpa.QueryCache" value="true(EnableStatistics=true)"/&gt;
            &lt;property name="openjpa.jdbc.QuerySQLCache" value="true(EnableStatistics=true)"/&gt;

            &lt;!--  Enable jmx provider and instruments for Data, Query, and QuerySQL caches --&gt;
            &lt;property name="openjpa.Instrumentation" value="jmx(Instrument='DataCache,QueryCache,QuerySQLCache')"/&gt;
        </programlisting>
        <section id="ref_guide_instrumentation_config_jmx">
            <title>
                JMX Platform MBean Enablement
            </title>
            <indexterm zone="ref_guide_instrumentation_config">
                <primary>
                    configuration
                </primary>
                <secondary>
                    jmx
                </secondary>
            </indexterm>
            <para>
            The built-in JMX Platform MBean provider can be used to monitor OpenJPA
            runtime information out-of-band.  This provider is based upon the Platform MBean support included
            in the JDK.  The JDK provides options for enabling secure connectivity and authentication.
            These options require additional configuration options and may require encryption
            keys to be installed on the local and remote systems.  To enable simple, non-secure, non-authenticated
            monitoring of your application, specify the -Dcom.sun.management.jmxremote.authenticate=false and 
            -Dcom.sun.management.jmxremote.ssl=false directives on the java command line invocation.  To enable
            remote instrumentation on a specific port, specify which port to use on the directive 
            -Dcom.sun.management.jmxremote.port=&lt;port&gt;.
            For example:
            <programlisting>
            java -cp openjpa-all-2.2.0.jar:myApplication.jar -Dcom.sun.management.jmxremote.authenticate=false
            -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=8888 com.my.app.Main
            </programlisting>
            </para>
            <para>
            Additional information regarding the use and configuration of JMX Platform MBeans
            can be found in the 
            <ulink url="http://download.oracle.com/javase/6/docs/technotes/guides/jmx/overview/JMXoverviewTOC.html">
            <literal>Java Management Extensions (JMX) Technology Overview</literal></ulink>.
            </para>
        </section>
    </section>
    <section id="ref_guide_instrumentation_custom">
        <title>
            Custom Providers and Instruments
        </title>
        <indexterm zone="ref_guide_instrumentation_custom">
            <primary>
                configuration
            </primary>
        </indexterm>
        <para>
        OpenJPA includes built-in support for a JMX Platform MBean provider, but a custom instrumentation
        providers can be created by implementing the 
        <ulink url="../javadoc/org/apache/openjpa/lib/instrumentation/InstrumentationProvider.html">
        <classname>InstrumentationProvider</classname></ulink> interface or more simply by extending
        <ulink url="../javadoc/org/apache/openjpa/lib/instrumentation/AbstractInstrumentationProvider.html">
        <classname>AbstractInstrumentationProvider</classname></ulink>.  To use the custom instrumentation provider,
        include the class in your classpath and specify the class name as the base value on the 
        <link linkend="openjpa.Instrumentation"><literal>openjpa.Instrumentation</literal></link> configuration property.
        </para>
        <para>
        OpenJPA includes instruments for various caches, but you can also create your own instruments.  To
        create a custom instrument you need to implement the
        <ulink url="../javadoc/org/apache/openjpa/lib/instrumentation/Instrument.html">
        <classname>Instrument</classname></ulink> interface or more simply extend
        <ulink url="../javadoc/org/apache/openjpa/lib/instrumentation/AbstractInstrument.html">
        <classname>AbstractInstrument</classname></ulink>.  If you are building a Platform MBean JMX-based
        instrument this effort can be simplified by extending
        <ulink url="../javadoc/org/apache/openjpa/instrumentation/jmx/JMXInstrument.html">
        <classname>JMXInstrument</classname></ulink>.  If you create your own custom
        provider, class name aliases can be registered within the provider to simplify configuration.  For example,
        the instrument <classname>com.my.app.MySQLInstrument</classname> could be aliased as 
        <classname>MySQLInstrument</classname> within custom provider 
        <classname>com.my.app.InstrumentationProvider</classname>.
        </para>
        <para>
        OpenJPA provides the ability to plug in custom instruments and gives instruments direct access to the 
        configuration, but it is up to the creator of the instrument to add the internal monitoring.  This often
        requires modifying or extending base OpenJPA classes (such as the Broker) or using a byte-code weaving 
        tool such as AspectJ to produce aspect-based instruments.
        </para>
        <para>
        Here is an example of how a custom instrumentation provider could be enabled with an instrument class
        aliased by the provider as <classname>MySQLInstrument</classname>.
        </para>
        <programlisting>
            &lt;!--  Enable custom provider and instrument --&gt;
            &lt;property name="openjpa.Instrumentation" value="com.my.app.InstrumentationProvider(Instrument='MySQLInstrument')"/&gt;
        </programlisting>
    </section>
</chapter>
