########################################################################
# JBoss, Home of Professional Open Source
# Copyright 20109, Red Hat and individual contributors
# by the @authors tag. See the copyright.txt in the distribution for a
# full listing of individual contributors.
#
# This is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation; either version 2.1 of
# the License, or (at your option) any later version.
#
# This software is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this software; if not, write to the Free
# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
# 02110-1301 USA, or see the FSF site: http://www.fsf.org.
#
# @authors Andrew Dinn
#
# Transaction Statistics Display via a Dynamic MBean
#
# A variant of the JVMMBeanStats script which counts requests made via
# interface javax.transaction.Transaction and makes the stats available
# via a JMX Dynamic MBean. Note that this is only counting calls to the
# transaction interface methods. Counting the number of successful
# begins, commits, rollbacks etc woudl require injecting rules into
# the implementation classes at strategic locations where success or
# failure of a transaction can be confirmed.
#
# to use ths script to trace execution of JBossTS
#
#  -- set the directory in which byteman has been installed
#  BYTEMAN_HOME= ...
#
#   -- identify the samples helper jar
#   SAMPLE_JAR=${BYTEMAN_HOME}/sample/lib/byteman-sample.jar
#
#   -- identify this script
#   SCRIPT={BYTEMAN_HOME}/sample/scripts/TXMBeanStats.txt
#
#   -- set the javaagent command line option and start JBoss AS
#   export JAVA_OPTS="${JAVA_OPTS} -javaagent:${BYTEMAN_JAR}=script:${SCRIPT},sys:${SAMPLE_JAR)"
#   ${JBOSS_HOME}/bin/run.sh
#
# alternatively to load the script dynamically
#
#   -- start JBoss AS with the Byteman agent listener
#   export JAVA_OPTS="${JAVA_OPTS} -javaagent:${BYTEMAN_JAR}=listener:true"
#  ${JBOSS_HOME}/run.sh
#
#   -- install the helper library into the system classpath
#  ${BYTEMAN_HOME}/bin/bmsubmit.sh -s $SAMPLE_JAR
#
#   -- install the script
#  ${BYTEMAN_HOME}/bin/bmsubmit.sh -l $SCRIPT

########################################################################
#
# All rules in this script use class JMXHelper which provides support
# for sampling and displaying statistics in an MBean. The helper adds a
# thread in the background when it is activated i.e. when any of the rules
# which employs the helper is first triggered. The thread is shut down
# when the helper is deactivated i.e. once all rules using the helper
# have been uninstalled. At regular intervals the helper thread samples
# counters updated by the rules and posts new stats to the MBean.
# The helper will, by default, install its MBeans in the platform
# MBeanServer. You can override this behavior by setting the JVM
# system property "org.jboss.byteman.jmx.mbeanserver" to a valid
# JMX domain name. If an MBeanServer exists with that as its default
# domain, it will be used, otherwise, an MBeanServer will be created
# with that domain name as its default. If the system property is
# set to "*platform*", then the platform MBeanServer will be used.
#
# The script attaches a rule to the helper method keyInfo() to define the
# counters to be sampled by the background thread. The object returned
# by this rule contains a set of string keys identifying the counters.
# It also provides each counter with a corresponding desciption
# and counter type. The type is either: CUMULATIVE meaning that the
# display tracks the counter total across successive samples; RATE,
# meaning that the display tracks the rate of change in the counter
# value per second across the last N samples; or MEAN, meaning
# that the display tracks the mean value of the counter across
# the last N samples. n.b. in the last case the sample counts
# are weighted by the exact length of the sample interval.
#
# The script also attaches a rule to helper method samplePeriod. The value
# 5000 returned by this method is used as the sampling period measured in
#  milliseconds. If this rule were omitted then the method would returns
# the default value 10,000.
#
# Thirdly, the script attaches a rule to helper method sampleSetSize. The value
# 3 returned by this method is used to determine how many sample readings to
# combine when computing the rate of change of a counter or the average value
# of the counter across each sample period.
#
# The remaining rules are used to update the values of the counters displayed
# in the mbean. They are injected into JBossTS methods at locations where
# a statistically significant event occurs and their action, fired when
# that event needs to be counted, is to incremment the relevant counter.
#

# ensure all rules employ the JMX helper class.

HELPER org.jboss.byteman.sample.helper.JMXHelper

# this rule is triggered when the periodic helper thread starts
# it returns a KeyInfo object identifying the stats counters
# updated by rules in this rule set

RULE return key info
CLASS JMXHelper
METHOD keyInfo()
BIND keyInfo : KeyInfo = new KeyInfo("JBossTS Statistics in a Dynamic MBean")
IF TRUE
DO keyInfo.addKey("TX begin", KeyInfo.KEY_TYPE_CUMULATIVE, "TX begin total");
   keyInfo.addKey("TX commit", KeyInfo.KEY_TYPE_CUMULATIVE, "TX commit total");
   keyInfo.addKey("TX rollback", KeyInfo.KEY_TYPE_CUMULATIVE, "TX rollback total");
   keyInfo.addKey("TX setRollbackOnly", KeyInfo.KEY_TYPE_CUMULATIVE, "TX setRollbackOnly total");
   keyInfo.addKey("TX enlistResource", KeyInfo.KEY_TYPE_CUMULATIVE, "TX enlistResource total");
   keyInfo.addKey("TX delistResource", KeyInfo.KEY_TYPE_CUMULATIVE, "TX delistResource total");
   keyInfo.addKey("TX registerSynchronization", KeyInfo.KEY_TYPE_CUMULATIVE, "TX registerSynchronization total");
   keyInfo.addKey("TX begin", KeyInfo.KEY_TYPE_RATE, "TX begin request/second");
   keyInfo.addKey("TX commit", KeyInfo.KEY_TYPE_RATE, "TX commit request/second");
   keyInfo.addKey("TX rollback", KeyInfo.KEY_TYPE_RATE, "TX rollback request/second");
   keyInfo.addKey("TX setRollbackOnly", KeyInfo.KEY_TYPE_RATE, "TX setRollbackOnly request/second");
   keyInfo.addKey("TX enlistResource", KeyInfo.KEY_TYPE_RATE, "TX enlistResource request/second");
   keyInfo.addKey("TX delistResource", KeyInfo.KEY_TYPE_RATE, "TX delistResource request/second");
   keyInfo.addKey("TX registerSynchronization", KeyInfo.KEY_TYPE_RATE, "TX registerSynchronization request/second");
   keyInfo.addKey("TX begin", KeyInfo.KEY_TYPE_MEAN, "TX begin average");
   keyInfo.addKey("TX commit", KeyInfo.KEY_TYPE_MEAN, "TX commit average");
   keyInfo.addKey("TX rollback", KeyInfo.KEY_TYPE_MEAN, "TX rollback average");
   keyInfo.addKey("TX setRollbackOnly", KeyInfo.KEY_TYPE_MEAN, "TX setRollbackOnly average");
   keyInfo.addKey("TX enlistResource", KeyInfo.KEY_TYPE_MEAN, "TX enlistResource average");
   keyInfo.addKey("TX delistResource", KeyInfo.KEY_TYPE_MEAN, "TX delistResource average");
   keyInfo.addKey("TX registerSynchronization", KeyInfo.KEY_TYPE_MEAN, "TX registerSynchronization average");
   RETURN keyInfo
ENDRULE

# This rule is triggered when the periodic helper thread starts
# it returns a boolean which determines whether the helper thread
# creates a JMX Connector Server, allowing the MBean stats to be
# fetched by a remote client using RMI. The default implemenation of
# the trigger method returns false. If you want to be able to fetch
# the MBean stats form a remote client uncomment this rule so  that
# it injects code returning true.
# RULE configure rmi server
# CLASS JMXHelper
# METHOD rmiServerRequired()
# IF TRUE
# DO RETURN TRUE
# ENDRULE

# This rule is triggered when the periodic helper thread starts
# but only if the previous rule has requested that an rmi server
# be installed. it returns a host address used when creating the
# server socket. the trigger method returns "localhost" as the
# default host. if you want to use a  different host then uncommment
# this rule and insert a suitable address
# RULE configure rmi host
# CLASS JMXHelper
# METHOD rmiHost()
# IF TRUE
# DO RETURN "<replace me with a hostname or address>"
# ENDRULE

# This rule is triggered when the periodic helper thread starts
# but only if the previous rule has requested that an rmi server
# be installed. it returns a port used when creating the
# server socket. the trigger method returns 9999 as the
# default host. if you want to use a  different host then uncommment
# this rule and edit the port number
# RULE configure rmi host
# CLASS JMXHelper
# METHOD rmiHost()
# IF TRUE
# DO RETURN <replace me with a port number>
# ENDRULE

# this rule is triggered when a JBoss JTA Transaction instance is created

RULE count begin request
CLASS com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple
METHOD <init>
IF TRUE
DO incrementCounter("TX begin")
ENDRULE

# this rule is triggered when a call is made to Transaction.<init>

RULE count begin request
CLASS com.arjuna.ats.internal.jta.transaction.jts.TransactionImple
METHOD <init>
IF TRUE
DO incrementCounter("TX begin")
ENDRULE

# this rule is triggered when a JBoss JTS Transaction instance is created

RULE count commit request
INTERFACE javax.transaction.Transaction
METHOD commit()
IF TRUE
DO incrementCounter("TX commit")
ENDRULE

# this rule is triggered when a call is made to Transaction.rollback

RULE count rollback request
INTERFACE javax.transaction.Transaction
METHOD rollback()
IF TRUE
DO incrementCounter("TX rollback")
ENDRULE

# this rule is triggered when a call is made to Transaction.setRollbackOnly

RULE count setRollbackOnly request
INTERFACE javax.transaction.Transaction
METHOD setRollbackOnly()
IF TRUE
DO incrementCounter("TX setRollbackOnly")
ENDRULE

# this rule is triggered when a call is made to Transaction.enlistResource

RULE count enlistResource request
INTERFACE javax.transaction.Transaction
METHOD enlistResource()
IF TRUE
DO incrementCounter("TX enlistResource")
ENDRULE

# this rule is triggered when a call is made to Transaction.delistResource

RULE count delistResource request
INTERFACE javax.transaction.Transaction
METHOD delistResource()
IF TRUE
DO incrementCounter("TX delistResource")
ENDRULE

# this rule is triggered when a call is made to Transaction.registerSynchronization

RULE count registerSynchronization request
INTERFACE javax.transaction.Transaction
METHOD registerSynchronization()
IF TRUE
DO incrementCounter("TX registerSynchronization")
ENDRULE
