This document expalins the detail configuration of beSee. The ChainingPreProcessor is the main element (chain centric) of beSee. The ChainedPreProcessors are elements you can declare in the configuration to reach your instrumentation requirements. Some of them targets global behavoir - like the CFlowPreProcessor - and other allows fine grained instrumentation - like AllMethodsPreProcessor .

Important note: unless specified, all properties and configuration directive should be written in a single line. The html rendering of this document can lead to misunderstanding. To make properties file more readable you can use the standard multiline syntax by using a "\" at the end of the line that goes on on the next line.

confDirective = this is a multi line value\
	of the configuration directive confDirective\
	that is written with 3 lines.		 

  1. Basic PreProcessor - the troubleshooting instrumentation
  2. Chaining PreProcessor - the chain centric instrumentation
  3. Chained PreProcessor - plug n play intrumentation
    1. Stdout PreProcessor - what's going on here
    2. Trace PreProcessor - show you all
    3. AllMethods PreProcessor - do what you want
    4. CFlow PreProcessor - track the flow depth

Basic PreProcessor


The Basic PreProcessor can be used to understand better how the BEA Class PreProcessor technology works and interacts with your deployed applications. This PreProcessor prints out on the server stdout a message when the PreProcessor is loaded and initialized and each time the bytecode of a class being loaded goes thru it.

It does not modify the class.


  • Starts your WebLogic server with the -Dweblogic.classloader.preprocessor=... option (see table below).

Configuration What Sample
WebLogic startup script add -Dweblogic.classloader.preprocessor= com.gnilux.besee.preprocessor.BasicPreProcessor java option

Chaining PreProcessor


The Chaining PreProcessor handles any number of PreProcessor and registers them in a chain. During the loading of a class, it applies every Chained PreProcessor matching some criteria (className like ..., className not like ..., method like ...).

Its behavior is configured thru a file and the configuration can be modified at runtime using JMX.

It provides the implementation for "this chained PreProcessor instruments class that match the following criteria". The symetric implementation "this class is handled by those chained PreProcessor" is not yet implemented (version 1-0).


  • Starts your WebLogic server with the -Dweblogic.classloader.preprocessor=... option (see table below).
  • Declare the configuration file to use with the -Dbesee.conf=... option.
  • Write the configuration file declared, and the log4j configuration file.

Configuration What Sample
WebLogic startup script add -Dweblogic.classloader.preprocessor= com.gnilux.besee.preprocessor.ChainingPreProcessor java option
WebLogic startup script add -Dbesee.conf= path to your file java option -Dbesee.conf=/besee/conf/

The following details the syntax of the file.

Directive Description Sample
besee.runtime Path to the directory for isolated 3rd party jars (see Architecture ) besee.runtime = /besee/runtime
besee.log Path to log4j configuration file besee.log = /besee/conf/
besee.keep [optional] Path to the directory where to keep instrumented class. The directory must exist. besee.keep = /besee/keep
besee.first Name of the first Chained PreProcessor in the chain - see below for details besee.first = A

Hot reload

The Chaining PreProcessor registers itself in the JMX server (if available) under the name com.gnilux.besee:service=HotPreProcessorChain . Use any JMX client application to see the current chain loaded or to recreate the chain by re-readiing the configuration file set thru -Dbesee.conf.

This is a screenshot of the beJMX application managing the Chaining PreProcessor.

Hot reloading of configuration thru beJMX console

Chained PreProcessor


Chained PreProcessor are PreProcessors that are registered in the Chaining PreProcessor. All Chained PreProcessor share common properties when used within the Chaining PreProcessor, and have also specific properties.

A Chained PreProcessor is declared with its class instance. In the following sample A is the name of a com.gnilux.besee.ppClassName PreProcessor. In this sample, A as a property called sampleProperty . This vocabulary is used in the next parts of this document.

# understand what is called
#		NAME of a Chained PreProcessor
#		PROPERTY of a Chained PreProcessor

# here the NAME is "A'. This will add an instance of ppClassName PreProcessor in the chain.
besee.A = com.gnilux.besee.ppClassName

# here a PROPERTY of A is "sampleProperty", its value is "sample". Case is of concern.
besee.A.sampleProperty = sample

Shared Properties

All Chained PreProcessor are using there full className as log4j logger to log various internal information.

The following are properties that applies to all Chained PreProcessor when used in the Chaining PreProcessor model.

Property Description Sample
next [optional] The name of the next Chained PreProcessor in the chain.

If a loop is produced, the chain is stopped to avoid infinite loop.

If not presents, this PreProcessor is the last in the chain. = B
classMatch [optional] A regular expression for matching the full className (including package).

If not match, the class instrumentation by this Chained PreProcessor is skept

The regexp considered is prefixed with a "^" and postfixed with a "$" to match the whole.

If not presents, defaults to ".*" (ie "^.*$" match all).

Note: to use the "." (dot) to express package / subpackage, you should escape it, but this is often not necessary since the regexp "." matches the caracter ".".
besee.A.classMatch = com.myapp.(ejb1|ejb2).*FacadeBean
classNotMatch [optional] A regular expression for non-matching the full className (including package).

If match, the class instrumentation by this Chained PreProcessor is skept

If not presents, defaults to "" (ie "^$", match nothing).
besee.A.classNotMatch = com.myapp.ejb1.Ignore(This|AndThat)FacadeBean
methodMatch [optional] A regular expression for matching the method name.

This is only used by Chained PreProcessor that works at the method level. The method level class instrumentation by this Chained PreProcessor is skept for all methods that don't match.

If not presents, default to ".*" (match all).
besee.A.methodMatch = get.*

Stdout PreProcessor

The com.gnilux.besee.preprocessor.StdoutPreProcessor prints in its log4j logger the className of the class that is beeing instrumented.

It is considered as a non instrumenting PreProcessor (it does not instrument the class). The class will then not appear in besee.keep unless instrumented elsewhere.

# sample
besee.A = com.gnilux.besee.preprocessor.StdoutPreProcessor = B
besee.A.classMatch = org.apache.struts.webapp..*			

Trace PreProcessor

The com.gnilux.preprocessor.TracePreProcessor acts at method level and instruments easily all wished methods off classes by adding log4j log call just before the method executes and just after the method returns (including when an exception is thrown).

Property Description Sample
logger name ot the log4l logger to use (should be configured in the besee.log log4j configuration file) besee.Z.logger = besee.test
fullName Accepts [0, 1].

Set to 1 to print the full className in the log message. Else use the short className (without package information)

Defaults to 0.
besee.Z.fullName = 0
verboseIn Accepts [0, 1, 2].

Set to 0 to log only the method name. Set to 1 to add the input parameters value. Set to 2 to add the input parameters type and values.

Defaults to 0.
besee.Z.verboseIn = 1
verboseOut Accepts [0, 1, 2].

Set to 0 to log only the method name. Set to 1 to add the input / output parameters value. Set to 2 to add the input / output parameters type and values.

Defaults to 0.
besee.Z.verboseOut = 2
cflowSP Accepts [0, 1].

Set to 1 to use the cflow indentation (this will work only if the CFlowPreProcessor is used and is "after" in the chain).

Defaults to 0.
besee.Z.cflowSP = 1
mt.modifier [optional] Method modifier regexp. If the method mofifier match, it is instrumented.

Defaults to "public".|protected)
# sample
besee.Z = com.gnilux.besee.preprocessor.TracePreProcessor = AA
besee.Z.classMatch = com.gnilux.besee.test.trace.*
besee.Z.logger = besee.test
besee.Z.fullName = 0
besee.Z.verboseIn = 0
besee.Z.verboseOut = 2
besee.Z.cflowSP = 1|private|protected)			

AllMethods PreProcessor

The com.gnilux.preprocessor.AllMethodsPreProcessor acts at method level and instruments easily all wished methods off classes in the way you want it.

Since this Chained PreProcessor is reserved to advanced usage, you should refer to javadoc for complete documentation.

besee.B = com.gnilux.besee.preprocessor.AllMethodsPreProcessor = C
besee.B.classMatch = com.gnilux.besee.test.(SimplePPTestCase|SuperFoo|Foo|Bar)
besee.B.ct.before ={\
.debug($$cflowSP + " new $$className()");\
 java.lang.System.out.println("hello $$className");\
besee.B.ct.after =\
.debug($$cflowSP +"_new $$className()"); =\
.debug($$cflowSP +" $$className.$$method(" +\
 com.gnilux.besee.util.StringUtil.dumpTypeValueArray($args)+")"); =\
.debug($$cflowSP +"_$$className.$$method(" +\
 com.gnilux.besee.util.StringUtil.dumpValueArray($args)+") = " +\
 com.gnilux.besee.util.StringUtil.dumpValueArray(($w)$_) );|private|protected)

CFlow PreProcessor

The com.gnilux.preprocessor.CFlowPreProcessor acts transparently at method level and instruments all wished methods off classes to add the flow depth support . It should be configured last in the chain when used to interact correctly with cflowSP and cflow substitution at runtime in AllMethodsPreProcessor and TracePreProcessor.

# last PP in chain to enable $$cflow and $$cflowSP

besee.AA = com.gnilux.besee.preprocessor.CflowPreProcessor = 
besee.AA.classMatch = com.gnilux.besee.test.*