A quick introduction to byteman: Built by the jboss community, it allows you to add code to your existing java program on the fly.
It is very handy in situations like:
- You want to print a parameter value on the method (better yet, run a getter chain on it)
- Change return value of the method
- Know what's going on in code that you don't own
- ...
This demonstration is to enable debug logging for log4j. Obviously there are other ways to enable debug logging for log4j, but it is useful in situations where you don't have write access to the config file, or you don't know what config file to change.
Here is a typical call to log something in debug - protected by a isDebugEnabled() call.
We have to make sure the isDebugEnabled returns true, and then the call to debug goes through overriding the internal log4j check to verify if debug is indeed enabled.
Byteman works with rules, here we are creating two rules to make sure debug log is written.
Rule 1: make sure isDebugEnabled() returns "true"
Here is a typical call to log something in debug - protected by a isDebugEnabled() call.
if (logger.isDebugEnabled())
{
logger.debug("The parameter value " + param + " is valid");
}
We have to make sure the isDebugEnabled returns true, and then the call to debug goes through overriding the internal log4j check to verify if debug is indeed enabled.
Byteman works with rules, here we are creating two rules to make sure debug log is written.
Rule 1: make sure isDebugEnabled() returns "true"
RULE enable debug logging
CLASS org.apache.log4j.Category
METHOD isDebugEnabled()
AT ENTRY
IF true
DO return true
ENDRULE
Rule 2: call the forcedLog() when logger.debug() is called
RULE force debug logging
CLASS org.apache.log4j.Category
METHOD debug(java.lang.Object)
AT ENTRY
IF true
DO $0.forcedLog(org.apache.log4j.Category.FQCN, org.apache.log4j.Level.DEBUG, $1, null)
ENDRULE
Attach byteman to your jvm: The following command will deploy byteman agent into your running jvm (pid), and listens at port 6666. More help here
java -jar lib/byteman-install.jar -h localhost -p 6666 --pid--
Deploy the rules file:
java -classpath lib/byteman.jar:lib/byteman-submit.jar \
org.jboss.byteman.agent.submit.Submit \
-h localhost -p 6666 -path to script-
Now, debug logging should be enabled for all categories now. If you want to filter only a certain logger, you can modify the rule which returns true on isDebugEnabled as follows
RULE Enable debug logging
CLASS org.apache.log4j.Category
METHOD isDebugEnabled()
AT ENTRY
BIND constant:string = "NAME OF MY LOGGER"
IF $0.getName().contains(constant)
DO return true
ENDRULE
When you are done, remove all the rules
java -classpath lib/byteman.jar:lib/byteman-submit.jar \
org.jboss.byteman.agent.submit.Submit \
-h localhost -p 6666 -u
That's it, download Byteman and instrument your code.