| type=page |
| status=published |
| title=Adding Monitoring Capabilities |
| next=adding-configuration-data.html |
| prev=extending-asadmin.html |
| ~~~~~~ |
| |
| = Adding Monitoring Capabilities |
| |
| [[GSACG00005]][[ghmos]] |
| |
| [[adding-monitoring-capabilities]] |
| == Adding Monitoring Capabilities |
| |
| Monitoring is the process of reviewing the statistics of a system to |
| improve performance or solve problems. By monitoring the state of |
| components and services that are deployed in the {productName}, |
| system administrators can identify performance bottlenecks, predict |
| failures, perform root cause analysis, and ensure that everything is |
| functioning as expected. Monitoring data can also be useful in |
| performance tuning and capacity planning. |
| |
| An add-on component typically generates statistics that the {productName} can gather at run time. Adding monitoring capabilities enables an |
| add-on component to provide statistics to {productName} in the same |
| way as components that are supplied in {productName} distributions. |
| As a result, system administrators can use the same administrative |
| interfaces to monitor statistics from any installed {productName} |
| component, regardless of the origin of the component. |
| |
| The following topics are addressed here: |
| |
| * link:#ghopc[Defining Statistics That Are to Be Monitored] |
| * link:#ghplw[Updating the Monitorable Object Tree] |
| * link:#ghrma[Dotted Names and REST URLs for an Add-On Component's Statistics] |
| * link:#ghptj[Example of Adding Monitoring Capabilities] |
| |
| [[ghopc]][[GSACG00116]][[defining-statistics-that-are-to-be-monitored]] |
| |
| === Defining Statistics That Are to Be Monitored |
| |
| At runtime, your add-on component might perform operations that affect |
| the behavior and performance of your system. For example, your component |
| might start a thread of control, receive a request from a service, or |
| request a connection from a connection pool. Monitoring the statistics |
| that are related to these operations helps a system administrator |
| maintain the system. |
| |
| To provide statistics to {productName}, your component must define |
| events for the operations that generate these statistics. At runtime, |
| your component must send these events when performing the operations for |
| which the events are defined. For example, to enable the number of |
| received requests to be monitored, a component must send a "request |
| received" event each time that the component receives a request. |
| |
| A statistic can correspond to single event or to multiple events. |
| |
| * Counter statistics typically correspond to a single event. For |
| example, to calculate the number of received requests, only one event is |
| required, for example, a "request received" event. Every time that a |
| "request received" event is sent, the number of received requests is |
| increased by 1. |
| * Timer statistics typically correspond to multiple events. For example, |
| to calculate the time to process a request, two requests, for example, a |
| "request received" event and a "request completed" event. |
| |
| Defining statistics that are to be monitored involves the following |
| tasks: |
| |
| * link:#gkadk[Defining an Event Provider] |
| * link:#ghprg[Sending an Event] |
| |
| [[gkadk]][[GSACG00220]][[defining-an-event-provider]] |
| |
| ==== Defining an Event Provider |
| |
| An event provider defines the types of events for the operations that |
| generate statistics for an add-on component. |
| |
| {productName} enables you to define an event provider in the |
| following ways: |
| |
| * By writing a Java Class. Define an event provider this way if you have |
| access to the source code of the component for which you are defining an |
| event provider. |
| * By writing an XML fragment. Define an event provider this way if you |
| do not have access to the source code of the component for which you are |
| defining and event provider. |
| |
| [[ghovq]][[GSACG00164]][[defining-an-event-provider-by-writing-a-java-class]] |
| |
| ===== Defining an Event Provider by Writing a Java Class |
| |
| To define an event provider, write a Java language class that defines |
| the types of events for the component. Your class is not required to |
| extend any specific class or implement any interfaces. |
| |
| To identify your class as an event provider, annotate the declaration of |
| the class with the |
| `org.glassfish.external.probe.provider.annotations.ProbeProvider` |
| annotation. |
| |
| To create a name space for event providers and to uniquely identify an |
| event provider to the monitoring infrastructure of {productName}, set |
| the elements of the `@ProbeProvider` annotation as follows: |
| |
| `moduleProviderName`:: |
| Your choice of text to identify the application to which the event |
| provider belongs. The value of the `moduleProviderName` element is not |
| required to be unique. |
| For example, for event providers from {productName}, `moduleProviderName` is `glassfish`. |
| `moduleName`:: |
| Your choice of name for the module for which the event provider is |
| defined. A module provides significant functionality of an |
| application. The value of the `moduleName` element is not required to |
| be unique. |
| In {productName}, examples of module names are `web-container`, |
| `ejb-container`, `transaction`, and `webservices`. |
| `probeProviderName`:: |
| Your choice of name to identify the event provider. To uniquely |
| identify the event provider, ensure that `probeProviderName` is unique |
| for all event providers in the same module. |
| In {productName}, examples of event-provider names are `jsp`, |
| `servlet`, and `web-module`. |
| |
| [[ghosi]][[GSACG00011]][[defining-event-types-in-an-event-provider-class]] |
| |
| Defining Event Types in an Event Provider Class |
| |
| To define event types in an event provider class, write one method for |
| each type of event that is related to the component. The requirements |
| for each method are as follows: |
| |
| * The return value of the callback methods must be void. |
| * The method body must be empty. You instantiate the event provider |
| class in the class that invokes the method to send the event. |
| For more information, see link:#ghprg[Sending an Event]. |
| * To enable the event to be used as an Oracle Solaris DTrace probe, each |
| parameter in the method signature must be a Java language primitive, |
| such as `Integer`, `boolean`, or `String`. |
| |
| Annotate the declaration of each method with the |
| `org.glassfish.external.probe.provider.annotations.Probe` annotation. |
| |
| By default, the type of the event is the method name. If you overload a |
| method in your class, you must uniquely identify the event type for each |
| form of the method. To uniquely identify the event type, set the `name` |
| element of the `@Probe` annotation to the name of the event type. |
| |
| [NOTE] |
| ==== |
| You are not required to uniquely identify the event type for methods that are not overloaded. |
| ==== |
| |
| |
| [[ghoul]][[GSACG00012]][[specifying-event-parameters]] |
| |
| Specifying Event Parameters |
| |
| To enable methods in an event listener to select a subset of values, |
| annotate each parameter in the method signature with the |
| `org.glassfish.external.probe.provider.annotations.ProbeParam` |
| annotation. Set the `value` element of the `@ProbeParam` annotation to |
| the name of the parameter. |
| |
| [[ghpmm]][[GSACG00013]][[example-of-defining-an-event-provider-by-writing-a-java-class]] |
| |
| Example of Defining an Event Provider by Writing a Java Class |
| |
| [[GSACG00041]][[ghprw]] |
| Example 5-1 Defining an Event Provider by Writing a Java Class |
| |
| This example shows the definition of the `TxManager` class. This class |
| defines events for the start and end of transactions that are performed |
| by a transaction manager. |
| |
| The methods in this class are as follows: |
| |
| `onTxBegin`:: |
| This method sends an event to indicate the start of a transaction. The |
| name of the event type that is associated with this method is `begin`. |
| A parameter that is named `txId` is passed to the method. |
| `onCompletion`:: |
| This method sends an event to indicate the end of a transaction. The |
| name of the event type that is associated with this method is `end`. A |
| parameter that is named `outcome` is passed to the method. |
| |
| [source,java] |
| ---- |
| import org.glassfish.external.probe.provider.annotations.Probe; |
| import org.glassfish.external.probe.provider.annotations.ProbeParam; |
| import org.glassfish.external.probe.provider.annotations.ProbeProvider; |
| @ProbeProvider(moduleProviderName="examplecomponent", |
| moduleName="transaction", probeProviderName="manager") |
| public class TxManager { |
| |
| @Probe("begin") |
| public void onTxBegin( |
| @ProbeParam("{txId}") String txId |
| ){} |
| |
| @Probe ("end") |
| public void onCompletion( |
| @ProbeParam("{outcome}") boolean outcome |
| ){} |
| } |
| ---- |
| |
| [[gkaec]][[GSACG00165]][[defining-an-event-provider-by-writing-an-xml-fragment]] |
| |
| ===== Defining an Event Provider by Writing an XML Fragment |
| |
| To define an event provider, write an extensible markup language (XML) |
| fragment that contains a single `probe-provider` element. |
| |
| To create a name space for event providers and to uniquely identify an |
| event provider to the monitoring infrastructure of {productName}, set |
| the attributes of the `probe-provider` element as follows: |
| |
| `moduleProviderName`:: |
| Your choice of text to identify the application to which the event |
| provider belongs. The value of the `moduleProviderName` attribute is |
| not required to be unique. |
| For example, for event providers from {productName}, `moduleProviderName` is `glassfish`. |
| `moduleName`:: |
| Your choice of name for the module for which the event provider is |
| defined. A module provides significant functionality of an |
| application. The value of the `moduleName` attribute is not required |
| to be unique. |
| In {productName}, examples of module names are `web-container`, |
| `ejb-container`, `transaction`, and `webservices`. |
| `probeProviderName`:: |
| Your choice of name to identify the event provider. To uniquely |
| identify the event provider, ensure that `probeProviderName` is unique |
| for all event providers in the same module. |
| In {productName}, examples of event—provider names are `jsp`, |
| `servlet`, and `web-module`. |
| |
| Within the `probe-provider` element, add one `probe` element for each |
| event type that you are defining. To identify the event type, set the |
| name attribute of the `probe` element to the type. |
| |
| To define the characteristics of each event type, add the following |
| elements within the `probe` element: |
| |
| `class`:: |
| This element contains the fully qualified Java class name of the |
| component that generates the statistics for which you are defining |
| events. |
| `method`:: |
| This element contains the name of the method that is invoked to |
| generate the statistic. |
| `signature`:: |
| This element contains the following information about the signature if |
| the method: |
| + |
| [source] |
| ---- |
| return-type (paramater-type-list) |
| ---- |
| `return-type`;; |
| The return type of the method. |
| `paramater-type-list`;; |
| A comma-separated list of the types of the parameters in the method |
| signature. |
| `probe-param`:: |
| The attributes of this element identify the type and the name of a |
| parameter in the method signature. One `probe-param` element is |
| required for each parameter in the method signature. The `probe-param` |
| element does not contain any data. |
| The attributes of the `probe-param` element are as follows: |
| `type`;; |
| Specifies the type of the parameter. |
| `name`;; |
| Specifies the name of the parameter. |
| `return-param`:: |
| The `type` attribute of this element specifies the return type of the |
| method. The `return-param` element does not contain any data. |
| |
| [[GSACG00042]][[gkajj]] |
| Example 5-2 Defining an Event Provider by Writing an XML Fragment |
| |
| This example defines an event provider for the `glassfish:web:jsp` |
| component. The Java class of this component is |
| `com.sun.enterprise.web.jsp.JspProbeEmitterImpl`. The event provider |
| defines one event of type `jspLoadedEvent`. The signature of the method |
| that is associated with this event is as follows: |
| |
| [source,java] |
| ---- |
| void jspLoaded(String jsp, String hostName) |
| ---- |
| [source,xml] |
| ---- |
| <probe-provider moduleProviderName="glassfish" moduleName="web" probeProviderName="jsp"> |
| <probe name="jspLoadedEvent"> |
| <class>com.sun.enterprise.web.jsp.JspProbeEmitterImpl</class> |
| <method>jspLoaded</method> |
| <signature>void (String,String)</signature> |
| <probe-param type="String" name="jsp"/> |
| <probe-param type="String" name="hostName"/> |
| <return-param type="void" /> |
| </probe> |
| </probe-provider> |
| ---- |
| |
| [[gkaie]][[GSACG00166]][[packaging-a-components-event-providers]] |
| |
| ===== Packaging a Component's Event Providers |
| |
| Packaging a component's event providers enables the monitoring |
| infrastructure of {productName} to discover the event providers automatically. |
| |
| To package a component's event providers, add an entry to the |
| component's `META-INF/MANIFEST.MF` file that identifies all of the |
| component's event providers. The format of the entry depends on how the |
| event providers are defined: |
| |
| * If the event providers are defined as Java classes, the entry is a |
| list of the event providers' class names as follows: |
| + |
| [source] |
| ---- |
| probe-provider-class-names : class-list |
| ---- |
| + |
| The `class-list` is a comma-separated list of the fully qualified Java |
| class names of the component's event providers. |
| * If the event providers are defined as XML fragments, the entry is a |
| list of the paths to the files that contain the XML fragments as follows: |
| + |
| [source] |
| ---- |
| probe-provider-xml-file-names : path-list |
| ---- |
| + |
| The `path-list` is a comma-separated list of the paths to the XML files |
| relative to the root of the archive in the JAR file. |
| |
| [[GSACG00043]][[gkaii]] |
| Example 5-3 Manifest Entry for Event Providers That Are Defined as Java Classes |
| |
| This example shows the entry in the `META-INF/MANIFEST.MF` file of a |
| component whose event provider is the |
| `org.glassfish.pluggability.monitoring.ModuleProbeProvider` class. |
| |
| [source] |
| ---- |
| probe-provider-class-names : org.glassfish.pluggability.monitoring.ModuleProbeProvider |
| ---- |
| |
| [[ghprg]][[GSACG00221]][[sending-an-event]] |
| |
| ==== Sending an Event |
| |
| At runtime, your add-on component might perform an operation that |
| generates statistics. To provide statistics about the operation to |
| {productName}, your component must send an event of the correct type |
| when performing the operation. |
| |
| To send an event, instantiate your event provider class and invoke the |
| method of the event provider class for the type of the event. |
| Instantiate the class and invoke the method in the class that represents |
| your add-on component. Ensure that the method is invoked when your |
| component performs the operation for which the event was defined. One |
| way to meet this requirement is to invoke the method for sending the |
| event in the body of the method for performing the operation. |
| |
| [[GSACG00044]][[ghpus]] |
| Example 5-4 Sending an Event |
| |
| This example shows the code for instantiating the `TxManager` class and |
| invoking the `onTxBegin` method to send an event of type `begin`. This |
| event indicates that a component is about to begin a transaction. |
| |
| The `TxManager` class is instantiated in the constructor of the |
| `TransactionManagerImpl` class. To ensure that the event is sent at the |
| correct time, the `onTxBegin` method is invoked in the body of the |
| `begin` method, which starts a transaction. |
| |
| The declaration of the `onTxBegin` method in the event provider |
| interface is shown in link:#ghprw[Example 5-1]. |
| |
| [source,java] |
| ---- |
| ... |
| public class TransactionManagerImpl { |
| ... |
| public TransactionManagerImpl() { |
| TxManager txProvider = new TxManager(); |
| ... |
| } |
| ... |
| public void begin() { |
| String txId = createTransactionId(); |
| .... |
| txProvider.onTxBegin(txId); //emit |
| } |
| ... |
| } |
| ---- |
| |
| [[ghplw]][[GSACG00117]][[updating-the-monitorable-object-tree]] |
| |
| === Updating the Monitorable Object Tree |
| |
| A monitorable object is a component, subcomponent, or service that can |
| be monitored. {productName} uses a tree structure to track |
| monitorable objects. |
| |
| Because the tree is dynamic, the tree changes as components of the |
| {productName} instance are added, modified, or removed. Objects are |
| also added to or removed from the tree in response to configuration |
| changes. For example, if monitoring for a component is turned off, the |
| component's monitorable object is removed from the tree. |
| |
| To enable system administrators to access statistics for all components |
| in the same way, you must provide statistics for an add-on component by |
| updating the monitorable object tree. Statistics for the add-on |
| component are then available through the {productName} administrative |
| commands link:reference-manual/get.html#GSRFM00139[`get`], olink:GSRFM00145[`list`], and |
| link:reference-manual/set.html#GSRFM00226[`set`]. These commands locate an object in the tree |
| through the object's dotted name. |
| |
| For more information about the tree structure of monitorable objects, |
| see "link:administration-guide/monitoring.html#GSADG00727[How the Monitoring Tree Structure Works]" in |
| {productName} Administration Guide. |
| |
| To make an add-on component a monitorable object, you must add the |
| add-on component to the monitorable object tree. |
| |
| To update the statistics for an add-on component, you must add the |
| statistics to the monitorable object tree, and create event listeners to |
| gather statistics from events that represent these statistics. At |
| runtime, these listeners must update monitorable objects with statistics |
| that these events contain. The events are sent by event provider |
| classes. For information about how to create event provider classes and |
| send events, see link:#ghopc[Defining Statistics That Are to Be |
| Monitored]. |
| |
| Updating the monitorable object tree involves the following tasks: |
| |
| * link:#ghpni[Creating Event Listeners] |
| * link:#ghptp[Representing a Component's Statistics in an Event Listener Class] |
| * link:#ghpml[Subscribing to Events From Event Provider Classes] |
| * link:#ghppo[Registering an Event Listener] |
| |
| [[ghpni]][[GSACG00222]][[creating-event-listeners]] |
| |
| ==== Creating Event Listeners |
| |
| An event listener gathers statistics from events that an event provider |
| sends. To enable an add-on component to gather statistics from events, |
| create listeners to receive events from the event provider. The listener |
| can receive events from the add-on component in which the listener is |
| created and from other components. |
| |
| To create an event listener, write a Java class to represent the |
| listener. The listener can be any Java object. |
| |
| An event listener also represents a component's statistics. To enable |
| the Application Server Management Extensions (AMX) to expose the |
| statistics to client applications, annotate the declaration of the class |
| with the `org.glassfish.gmbal.ManagedObject` annotation. |
| |
| Ensure that the class that you write meets these requirements: |
| |
| * The return value of all callback methods in the listener must be void. |
| * Because the methods of your event provider class may be entered by |
| multiple threads, the listener must be thread safe. However,{productName} provides utility classes to perform some common operations such |
| as `count`, `avg`, and `sum`. |
| * The listener must have the same restrictions as a Jakarta EE application. For example, the listener |
| cannot open server sockets, or create threads. |
| |
| A listener is called in the same thread as the event method. As a |
| result, the listener can use thread locals. If the monitored system |
| allows access to thread locals, the listener can access thread locals of |
| the monitored system. |
| |
| |
| [NOTE] |
| ==== |
| A listener that is not registered to listen for events is never called |
| by the framework. Therefore, unregistered listeners do not consume any |
| computing resources, such as memory or processor cycles. |
| ==== |
| |
| [[ghptp]][[GSACG00223]][[representing-a-components-statistics-in-an-event-listener-class]] |
| |
| ==== Representing a Component's Statistics in an Event Listener Class |
| |
| Represent each statistic as the property of a JavaBeans specification |
| getter method of your listener class. Methods in the listener class for |
| processing events can then access the property through the getter |
| method. For more information, see link:#ghpml[Subscribing to Events From |
| Event Provider Classes]. |
| |
| To enable AMX to expose the statistic to client applications, annotate |
| the declaration of the getter method with the |
| `org.glassfish.gmbal.ManagedAttribute` annotation. Set the `id` element |
| of the `@ManagedAttribute` annotation to the property name all in |
| lowercase. |
| |
| The data type of the property that represents a statistic must be a |
| class that provides methods for computing the statistic from event data. |
| |
| The `org.glassfish.external.statistics.impl` package provides the |
| following classes to gather and compute statistics data: |
| |
| `AverageRangeStatisticImpl`:: |
| Provides standard measurements of the lowest and highest values that |
| an attribute has held and the current value of the attribute. |
| `BoundaryStatisticImpl`:: |
| Provides standard measurements of the upper and lower limits of the |
| value of an attribute. |
| `BoundedRangeStatisticImpl`:: |
| Aggregates the attributes of `RangeStatisticImpl` and |
| `BoundaryStatisticImpl` and provides standard measurements of a range |
| that has fixed limits. |
| `CountStatisticImpl`:: |
| Provides standard count measurements. |
| `RangeStatisticImpl`:: |
| Provides standard measurements of the lowest and highest values that |
| an attribute has held and the current value of the attribute. |
| `StatisticImpl`:: |
| Provides performance data. |
| `StringStatisticImpl`:: |
| Provides a string equivalent of a counter statistic. |
| `TimeStatisticImpl`:: |
| Provides standard timing measurements. |
| |
| [[GSACG00045]][[ghpsc]] |
| Example 5-5 Representing a Component's Statistics in an Event Listener |
| Class |
| |
| This example shows the code for representing the `txcount` statistic in |
| the `TxListener` class. |
| |
| [source,java] |
| ---- |
| ... |
| import org.glassfish.external.statistics.CountStatistic; |
| import org.glassfish.external.statistics.impl.CountStatisticImpl; |
| ... |
| import org.glassfish.gmbal.ManagedAttribute; |
| import org.glassfish.gmbal.ManagedObject; |
| |
| ... |
| @ManagedObject |
| public class TxListener { |
| |
| private CountStatisticImpl txCount = new CountStatisticImpl("TxCount", |
| "count", "Number of completed transactions"); |
| ... |
| @ManagedAttribute(id="txcount") |
| public CountStatistic getTxCount(){ |
| return txCount; |
| } |
| } |
| ---- |
| |
| [[ghpml]][[GSACG00224]][[subscribing-to-events-from-event-provider-classes]] |
| |
| ==== Subscribing to Events From Event Provider Classes |
| |
| To receive events from event provider classes, a listener must subscribe |
| to the events. Subscribing to events also specifies the provider and the |
| type of events that the listener will receive. |
| |
| To subscribe to events from event provider classes, write one method in |
| your listener class to process each type of event. To specify the |
| provider and the type of event, annotate the method with the |
| `org.glassfish.external.probe.provider.annotations.ProbeListener` |
| annotation. In the `@ProbeListener` annotation, specify the provider and |
| the type as follows: |
| |
| [source] |
| ---- |
| "module-providername:module-name:probe-provider-name:event-type" |
| ---- |
| |
| module-providername:: |
| The application to which the event provider belongs. This parameter |
| must be the value of the `moduleProviderName` element or attribute in |
| the definition of the event provider. See link:#ghovq[Defining an |
| Event Provider by Writing a Java Class] and link:#gkaec[Defining an |
| Event Provider by Writing an XML Fragment]. |
| module-name:: |
| The module for which the event provider is defined. This parameter |
| must match be the value of the `moduleName` element or attribute in |
| the definition of the event provider. See link:#ghovq[Defining an |
| Event Provider by Writing a Java Class] and link:#gkaec[Defining an |
| Event Provider by Writing an XML Fragment]. |
| probe-provider-name:: |
| The name of the event provider. This parameter must match be the value |
| of the `probeProviderName` element or attribute in the definition of |
| the event provider. See link:#ghovq[Defining an Event Provider by |
| Writing a Java Class] and link:#gkaec[Defining an Event Provider by |
| Writing an XML Fragment]. |
| event-type:: |
| The type of the event. This type is defined in the event provider |
| class. For more information, see link:#ghosi[Defining Event Types in |
| an Event Provider Class]. |
| |
| Annotate each parameter in the method signature with the `@ProbeParam` |
| annotation. Set the `value` element of the `@ProbeParam` annotation to |
| the name of the parameter. |
| |
| In the method body, provide the code to update monitoring statistics in |
| response to the event. |
| |
| [[GSACG00046]][[ghpwu]] |
| Example 5-6 Subscribing to Events From Event Provider Classes |
| |
| This example shows the code for subscribing to events of type `begin` |
| from the `tx` component. The provider of the component is `TxManager`. |
| The body of the `begin` method contains code to increase the transaction |
| count txcount by 1 each time that an event is received. |
| |
| The definition of the `begin` event type is shown in link:#ghprw[Example 5-1]. |
| |
| The code for sending `begin` events is shown in link:#ghpus[Example 5-4]. |
| |
| The instantiation of the `txCount` object is shown in |
| link:#ghpsc[Example 5-5]. |
| |
| [source,java] |
| ---- |
| ... |
| import org.glassfish.external.probe.provider.annotations.ProbeListener; |
| import org.glassfish.external.probe.provider.annotations.ProbeParam; |
| import org.glassfish.gmbal.ManagedObject; |
| ... |
| @ManagedObject |
| public class TxListener { |
| ...; @ProbeListner("examplecomponent:transaction:manager:begin") |
| public void begin( |
| @ProbeParam("{txId}") |
| String txId) { |
| txCount.increment(); |
| } |
| } |
| ---- |
| |
| [[ghpsp]][[GSACG00167]][[listening-for-changes-to-values-that-are-not-part-of-the-target-method-definition]] |
| |
| ===== Listening for Changes to Values That are Not Part of the Target Method Definition |
| |
| Event listeners can express their interest in certain predefined values |
| that are not part of the target method definition. For example, |
| $\{gf.appname}, $\{gf.modulename} etc. are some of the computed params |
| that are available to the clients, these values are computed/evaluated |
| only on demand and provided by the event infrastructure. |
| |
| [[ghpsw]][[GSACG00168]][[getting-information-about-a-event-provider]] |
| |
| ===== Getting Information About a Event Provider |
| |
| `ProbeProviderInfo` contains details about individual event types in an |
| event provider class. |
| |
| [source,java] |
| ---- |
| public interface ProbeProviderInfo { |
| |
| public String getModuleName(); |
| |
| public String getProviderName(); |
| |
| public String getApplicationName(); |
| |
| public String getProbeName(); |
| |
| public String[] getParamterNames(); |
| |
| public Class getParamterTypes(); |
| |
| } |
| ---- |
| |
| [[ghpmt]][[GSACG00225]][[listening-for-events-from-classes-that-are-not-event-providers]] |
| |
| ==== Listening for Events From Classes That Are Not Event Providers |
| |
| gfProbes infrastructure allows clients to monitor glassfish even in the |
| absence of provider classes. This is done by allowing clients to receive |
| callbacks when a java methods are entered / exited. Note that while this |
| approach allows a client to monitor legacy code, it may not always be |
| possible to receive "high-level" events. |
| |
| For example, while it is easy to monitor (through gfProbes) when |
| TransactionManagerImpl.begin() entered / exited, the client cannot |
| determine the transaction ID in this case. |
| |
| [source,java] |
| ---- |
| public class TxMonitor { |
| @MethodEntry("tx:com.sun.tx.TxMgrImpl::onTxBegin") |
| public void onTx(String tId) { |
| count++; |
| } |
| } |
| ---- |
| |
| [[ghpql]][[GSACG00169]][[monitoring-method-entry]] |
| |
| ===== Monitoring Method Entry |
| |
| The @MethodEntry annotation must be used by the client to receive |
| callback when the target method is entered. The client method argument |
| types and count must match the target methods parameter types/count. |
| |
| [[ghppg]][[GSACG00170]][[monitoring-method-exit]] |
| |
| ===== Monitoring Method Exit |
| |
| The @MethodExit annotation must be used by the client to receive |
| callback when the target method is exited. The client method argument |
| types and count must match the target methods parameter types/count. The |
| first parameter in the client method should match the return type of the |
| target method (only if the target method has a non void return type) |
| |
| [[ghplj]][[GSACG00171]][[monitoring-exceptions]] |
| |
| ===== Monitoring Exceptions |
| |
| The @OnException annotation must be used by the client to receive |
| callback when the target method exits because of an exception. The |
| client method argument types and count must match the target methods |
| parameter types/count. (This restriction might be removed later). The |
| first parameter in the client method should be of type Throwable |
| |
| [[ghppo]][[GSACG00226]][[registering-an-event-listener]] |
| |
| ==== Registering an Event Listener |
| |
| Registering an event listener enables the listener to receive callbacks |
| from the {productName} event infrastructure. The listener can then |
| collect data from events and update monitorable objects in the object |
| tree. These monitorable objects form the basis for monitoring |
| statistics. |
| |
| Registering an event listener also makes a component and its statistics |
| monitorable objects by adding statistics for the component to the |
| monitorable object tree. |
| |
| At runtime, the {productName} event infrastructure registers |
| listeners for an event provider when the event provider is started and |
| unregisters them when the event provider is shut down. As a result, |
| listeners have no dependencies on other components. |
| |
| To register a listener, invoke the static |
| `org.glassfish.external.probe.provider.StatsProviderManager.register` |
| method in the class that represents your add-on component. In the method |
| invocation, pass the following information as parameters: |
| |
| * The name of the configuration element with which all statistics in the |
| event listener are to be associated. System administrators use this |
| element for enabling or disabling monitoring for the event listener. |
| * The node in the monitorable object tree under which the event listener |
| is to be registered. To specify the node, pass one of the following |
| constants of the |
| `org.glassfish.external.probe.provider.PluginPointPluginPoint` |
| enumeration: |
| |
| ** To register the listener under the `server/applications` node, pass |
| the `APPLICATIONS` constant. |
| |
| ** To register the listener under the `server` node, pass the `SERVER` |
| constant. |
| * The path through the monitorable object tree from the node under which |
| the event listener is registered down to the statistics in the event |
| listener. The nodes in this path are separated by the slash (`/`) |
| character. |
| * The listener object that you are registering. |
| |
| [[GSACG00047]][[ghpuu]] |
| Example 5-7 Registering an Event Listener |
| |
| This example shows the code for registering the event listener |
| `TxListener` for the add-on component that is represented by the class |
| `TransactionManagerImpl`. The statistics that are defined in this |
| listener are associated with the `web-container` configuration element. |
| The listener is registered under the `server/applications` node. The |
| path from this node to the statistics in the event listener is |
| `tx/txapp`. |
| |
| Code for the constructor of the `TxListener` class is beyond the scope |
| of this example. |
| |
| [source,java] |
| ---- |
| ... |
| import org.glassfish.external.probe.provider.StatsProviderManager; |
| import org.glassfish.external.probe.provider.PluginPoint |
| ... |
| public class TransactionManagerImpl { |
| ... |
| StatsProviderManager.register("web-container", PluginPoint.APPLICATIONS, |
| "tx/txapp", new TxListener()); |
| ... |
| } |
| ---- |
| |
| [[ghrma]][[GSACG00118]][[dotted-names-and-rest-urls-for-an-add-on-components-statistics]] |
| |
| === Dotted Names and REST URLs for an Add-On Component's Statistics |
| |
| The {productName} administrative subcommands link:reference-manual/get.html#GSRFM00139[`get`], |
| link:reference-manual/list.html#GSRFM00145[`list`], and olink:GSRFM00226[`set`] locate a statistic |
| through the dotted name of the statistic. The dotted name of a statistic |
| for an add-on component is determined from the registration of the event |
| listener that defines the statistic as follows: |
| |
| [source] |
| ---- |
| listener-parent-node.path-to-statistic.statistic-name |
| ---- |
| |
| listener-parent-node:: |
| The node in the monitorable object tree under which the event listener |
| that defines the statistic is registered. This node is passed in the |
| invocation of the `register` method that registers the event listener. |
| For more information, see link:#ghppo[Registering an Event Listener]. |
| path-to-statistic:: |
| The path through the monitorable object tree from the node under which |
| the event listener is registered down to the statistic in the event |
| listener in which each slash is replaced with a period. This path is |
| passed in the invocation of the `register` method that registers the |
| event listener. For more information, see link:#ghppo[Registering an |
| Event Listener]. |
| statistic-name:: |
| The name of the statistic. This name is the value of the `id` element |
| of the `@ManagedAttribute` annotation on the property that represents |
| the statistic. For more information, see link:#ghptp[Representing a |
| Component's Statistics in an Event Listener Class]. |
| |
| For example, the dotted name of the `txcount` statistic that is defined |
| in link:#ghpsc[Example 5-5] and registered in link:#ghpuu[Example 5-7] |
| is as follows: |
| |
| [source] |
| ---- |
| server.applications.tx.txapp.txcount |
| ---- |
| |
| The formats of the URL to a REST resource that represents a statistic is as follows: |
| |
| [source] |
| ---- |
| http://host:port/monitoring/domain/path |
| ---- |
| |
| host:: |
| The host where the DAS is running. |
| port:: |
| The HTTP port or HTTPS port for administration. |
| path:: |
| The path to the statistic. The path is the dotted name of the |
| attribute in which each dot (`.`) is replaced with a slash (`/`). |
| |
| For example, the URL the REST resource for the `txcount` statistic that |
| is defined in link:#ghpsc[Example 5-5] and registered in |
| link:#ghpuu[Example 5-7] is as follows: |
| |
| [source] |
| ---- |
| http://localhost:4848/monitoring/domain/server/applications/tx/txapp/txcount |
| ---- |
| |
| In this example, the DAS is running on the local host and the HTTP port |
| for administration is 4848. |
| |
| [[ghmox]][[GSACG00119]][[adding-a-type-to-the-monitor-command]] |
| |
| === Adding a Type to the `monitor` Command |
| |
| To add a type to the `monitor` command, implement the `MonitorContract` interface. |
| |
| An implementation of the `MonitorContract` interface is an HK2 service |
| that provides monitoring data to the `monitor` command. |
| |
| [[ghptj]][[GSACG00120]][[example-of-adding-monitoring-capabilities]] |
| |
| === Example of Adding Monitoring Capabilities |
| |
| This example shows a component that monitors the number of requests that |
| a container receives. The following table provides a cross-reference to |
| the listing of each class or interface in the example. |
| |
| [width="100%",cols="<50%,<50%",options="header",] |
| |=== |
| |Class or Interface |Listing |
| |`ModuleProbeProvider` |link:#ghpna[Example 5-8] |
| |`ModuleBootStrap` |link:#ghpmu[Example 5-9] |
| |`ModuleStatsTelemetry` |link:#ghpvw[Example 5-10] |
| |`Module` |link:#ghpuc[Example 5-11] |
| |`ModuleMBean` |link:#ghpwx[Example 5-12] |
| |=== |
| |
| |
| [[GSACG00048]][[ghpna]] |
| Example 5-8 Event Provider Class |
| |
| This example illustrates how to define an event provider as explained in |
| link:#ghovq[Defining an Event Provider by Writing a Java Class]. |
| |
| The example shows the definition of the `ModuleProbeProvider` class. |
| The event provider sends events when the request count is increased by 1 or |
| decreased by 1. |
| |
| This class defines the following methods: |
| |
| * `moduleCountIncrementEvent` |
| * `moduleCountDecrementEvent` |
| |
| The name of each method is also the name of the event type that is |
| associated with the method. |
| |
| A parameter that is named `count` is passed to each method. |
| |
| [source,java] |
| ---- |
| package org.glassfish.pluggability.monitoring; |
| |
| import org.glassfish.external.probe.provider.annotations.Probe; |
| import org.glassfish.external.probe.provider.annotations.ProbeParam; |
| import org.glassfish.external.probe.provider.annotations.ProbeProvider; |
| |
| /** |
| * Monitoring count events |
| * Provider interface for module specific probe events. |
| */ |
| @ProbeProvider(moduleProviderName = "glassfish", moduleName = "mybeanmodule", |
| probeProviderName = "mybean") |
| public class ModuleProbeProvider { |
| |
| /** |
| * Emits probe event whenever the count is incremented |
| */ |
| @Probe(name = "moduleCountIncrementEvent") |
| public void moduleCountIncrementEvent( |
| @ProbeParam("count") Integer count) { |
| } |
| |
| /** |
| * Emits probe event whenever the count is decremented |
| */ |
| @Probe(name = "moduleCountDecrementEvent") |
| public void moduleCountDecrementEvent( |
| @ProbeParam("count") Integer count) { |
| } |
| } |
| ---- |
| |
| |
| [[GSACG00049]][[ghpmu]] |
| |
| Example 5-9 Bootstrap Class |
| |
| This example illustrates how to register an event listener as explained |
| in link:#ghppo[Registering an Event Listener]. The example shows the |
| code for registering an instance of the listener class |
| `ModuleStatsTelemetry`. This instance is added as a child of the |
| `server/applications` node of the tree. |
| |
| [source,java] |
| ---- |
| package org.glassfish.pluggability.monitoring; |
| |
| import org.jvnet.hk2.component.PostConstruct; |
| import org.jvnet.hk2.annotations.Service; |
| import org.jvnet.hk2.annotations.Scoped; |
| import org.jvnet.hk2.component.Singleton; |
| import org.glassfish.external.probe.provider.StatsProviderManager; |
| import org.glassfish.external.probe.provider.PluginPoint; |
| |
| /** |
| * Monitoring Count Example |
| * Bootstrap object for registering probe provider and listener |
| */ |
| @Service |
| @Scoped(Singleton.class) |
| public class ModuleBootStrap implements PostConstruct { |
| |
| @Override |
| public void postConstruct() { |
| try { |
| StatsProviderManager.register("web-container", |
| PluginPoint.APPLICATIONS, "myapp", new ModuleStatsTelemetry()); |
| } catch (Exception e) { |
| System.out.println("Caught exception in postconstruct"); |
| e.printStackTrace(); |
| } |
| } |
| } |
| ---- |
| |
| [[GSACG00050]][[ghpvw]] |
| Example 5-10 Listener Class |
| |
| This example shows how to perform the following tasks: |
| |
| * link:#ghpni[Creating Event Listeners]. The example shows the code of |
| the `ModuleStatsTelemetry` listener class. |
| * link:#ghptp[Representing a Component's Statistics in an Event Listener |
| Class]. The example shows the code for representing the |
| `countmbeancount` statistic. |
| * link:#ghpml[Subscribing to Events From Event Provider Classes]. The |
| example shows the code for subscribing to the following types of events |
| from the `count` component: |
| ** `moduleCountIncrementEvent` |
| ** `moduleCountDecrementEvent` |
| |
| [source,java] |
| ---- |
| package org.glassfish.pluggability.monitoring; |
| |
| import org.glassfish.external.statistics.CountStatistic; |
| import org.glassfish.external.statistics.impl.CountStatisticImpl; |
| import org.glassfish.external.probe.provider.annotations.ProbeListener; |
| import org.glassfish.external.probe.provider.annotations.ProbeParam; |
| import org.glassfish.gmbal.ManagedAttribute; |
| import org.glassfish.gmbal.ManagedObject; |
| |
| /** |
| * Monitoring counter example |
| * Telemtry object which listens to probe events and updates |
| * the monitoring stats |
| */ |
| @ManagedObject |
| public class ModuleStatsTelemetry { |
| |
| private CountStatisticImpl countMBeanCount = new CountStatisticImpl( |
| "CountMBeanCount", "count", "Number of MBeans"); |
| |
| @ManagedAttribute(id = "countmbeancount") |
| public CountStatistic getCountMBeanCount() { |
| return countMBeanCount; |
| } |
| |
| @ProbeListener("count:example:countapp:moduleCountIncrementEvent") |
| public void moduleCountIncrementEvent( |
| @ProbeParam("count") Integer count) { |
| countMBeanCount.increment(); |
| } |
| |
| @ProbeListener("count:example:countapp:moduleCountDecrementEvent") |
| public void moduleCountDecrementEvent( |
| @ProbeParam("count") Integer count) { |
| countMBeanCount.decrement(); |
| } |
| } |
| ---- |
| |
| [[GSACG00051]][[ghpuc]] |
| Example 5-11 MBean Interface |
| |
| This example defines the interface for a simple standard MBean that has |
| methods to increase and decrease a counter by 1. |
| |
| [source,java] |
| ---- |
| package com.example.count.monitoring; |
| |
| /** |
| * Monitoring counter example |
| * ModuleMBean interface |
| */ |
| public interface ModuleMBean { |
| public Integer getCount() ; |
| public void incrementCount() ; |
| public void decrementCount() ; |
| } |
| ---- |
| |
| [[GSACG00052]][[ghpwx]] |
| Example 5-12 MBean Implementation |
| |
| This example illustrates how to send an event as explained in link:#ghprg[Sending an Event]. |
| The example shows code for sending events as follows: |
| |
| * The `moduleCountIncrementEvent` method is invoked in the body of the `incrementCount` method. |
| * The `moduleCountDecrementEvent` method is invoked in the body of the `decrementCount` method. |
| |
| The methods `incrementCount` and `decrementCount` are invoked by an |
| entity that is beyond the scope of this example, for example, JConsole. |
| |
| [source,java] |
| ---- |
| package org.glassfish.pluggability.monitoring; |
| |
| /** |
| * Monitoring counter example |
| * ModuleMBean implementation |
| */ |
| public class Module implements ModuleMBean { |
| |
| private int k = 0; |
| private ModuleProbeProvider mpp = null; |
| |
| @Override |
| public Integer getCount() { |
| return k; |
| } |
| |
| @Override |
| public void incrementCount() { |
| k++; |
| if (mpp != null) { |
| mpp.moduleCountIncrementEvent(k); |
| } |
| } |
| |
| @Override |
| public void decrementCount() { |
| k--; |
| if (mpp != null) { |
| mpp.moduleCountDecrementEvent(k); |
| } |
| } |
| |
| void setProbeProvider(ModuleProbeProvider mpp) { |
| this.mpp = mpp; |
| } |
| } |
| ---- |