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.