[slf4j-dev] svn commit: r1148 - in slf4j/trunk/slf4j-ext/src/main/java/org/slf4j: agent instrumentation
ravn at slf4j.org
ravn at slf4j.org
Tue Sep 23 23:25:23 CEST 2008
Author: ravn
Date: Tue Sep 23 23:25:23 2008
New Revision: 1148
Added:
slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/instrumentation/AddEntryExitLoggingTransformer.java (contents, props changed)
Modified:
slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/agent/AgentMain.java
Log:
moved instrumentation methods from AgentMain to AddEntryExitLogginTransformer
Modified: slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/agent/AgentMain.java
==============================================================================
--- slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/agent/AgentMain.java (original)
+++ slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/agent/AgentMain.java Tue Sep 23 23:25:23 2008
@@ -7,19 +7,13 @@
import java.util.HashSet;
import java.util.Set;
-import javassist.CannotCompileException;
-import javassist.ClassPool;
-import javassist.CtBehavior;
-import javassist.CtClass;
-import javassist.CtField;
-import javassist.NotFoundException;
+import org.slf4j.instrumentation.AddEntryExitLoggingTransformer;
-import org.slf4j.instrumentation.JavassistHelper;
-
-public class AgentMain implements ClassFileTransformer {
+public class AgentMain {
public static void premain(String agentArgument,
Instrumentation instrumentation) {
+
if (agentArgument != null) {
String[] args = agentArgument.split(",");
Set<String> argSet = new HashSet<String>(Arrays.asList(args));
@@ -37,91 +31,8 @@
}
// ... more agent option handling here
}
- instrumentation.addTransformer(new AgentMain());
- }
-
- // Determine name of logger
-
- String def = "private static org.slf4j.Logger " + "_log" + ";";
- String ifLog = "if (_log.isDebugEnabled())";
-
- String[] ignore = new String[] { "sun/", "java/", "javax/", "org/slf4j/",
- "ch/qos/logback/" };
-
- //
- // The transform(...) method calls doClass(...) if the class name does not
- // start with any of the prefixes it has been told to ignore (note that the
- // separators are slashes, not dots).
-
- public byte[] transform(ClassLoader loader, String className, Class<?> clazz,
- java.security.ProtectionDomain domain, byte[] bytes) {
-
- for (int i = 0; i < ignore.length; i++) {
- if (className.startsWith(ignore[i])) {
- return bytes;
- }
- }
- //System.out.println("Adding to " + className);
- return doClass(className, clazz, bytes);
- }
- //
- // The doClass(...) method uses javassist to analyze the byte stream. If it
- // is a real class, a logger field is added and initialized to the name of
- // the class. Each non-empty method is then processed with doMethod(...).
- // The finally-clause ensures that the class definition is removed again
- // from the javassist pools to keep memory usage down.
- //
- // Note: The logger variable has been named _log. In a production version an
- // unused variable name should be found and used.
-
- private byte[] doClass(String name, Class<?> clazz, byte[] b) {
- ClassPool pool = ClassPool.getDefault();
- CtClass cl = null;
- try {
- cl = pool.makeClass(new java.io.ByteArrayInputStream(b));
- if (cl.isInterface() == false) {
-
- CtField field = CtField.make(def, cl);
- String getLogger = "org.slf4j.LoggerFactory.getLogger("
- + name.replace('/', '.') + ".class);";
- cl.addField(field, getLogger);
- System.out.println(getLogger);
-
- CtBehavior[] methods = cl.getDeclaredBehaviors();
- for (int i = 0; i < methods.length; i++) {
- if (methods[i].isEmpty() == false) {
- doMethod(methods[i]);
- }
- }
- b = cl.toBytecode();
- }
- } catch (Exception e) {
- System.err.println("Could not instrument " + name
- + ", exception : " + e.getMessage());
- } finally {
- if (cl != null) {
- cl.detach();
- }
- }
- return b;
+ instrumentation.addTransformer(new AddEntryExitLoggingTransformer());
}
- // The doMethod(...) class creates "_log.info(...)" snippets to insert at
- // the beginning and end of each method. Both contain the parameters (as
- // they may have changed), and the end method statement contain the return
- // value for non-void methods (which is available as $_ in the javassist
- // compiler).
-
- private void doMethod(CtBehavior method) throws NotFoundException,
- CannotCompileException {
-
- String signature = JavassistHelper.getSignature(method);
- String returnValue = JavassistHelper.returnValue(method);
-
- method.insertBefore(ifLog + "_log" + ".info(\">> " + signature + ");");
-
- method.insertAfter(ifLog + "_log" + ".info(\"<< " + signature
- + returnValue + ");");
- }
}
\ No newline at end of file
Added: slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/instrumentation/AddEntryExitLoggingTransformer.java
==============================================================================
--- (empty file)
+++ slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/instrumentation/AddEntryExitLoggingTransformer.java Tue Sep 23 23:25:23 2008
@@ -0,0 +1,85 @@
+/**
+ *
+ */
+package org.slf4j.instrumentation;
+
+import java.io.ByteArrayInputStream;
+import java.lang.instrument.ClassFileTransformer;
+
+import javassist.CannotCompileException;
+import javassist.ClassPool;
+import javassist.CtBehavior;
+import javassist.CtClass;
+import javassist.CtField;
+import javassist.NotFoundException;
+
+
+public class AddEntryExitLoggingTransformer implements
+ ClassFileTransformer {
+
+ final String def = "private static org.slf4j.Logger " + "_log" + ";";
+ final String ifLog = "if (_log.isDebugEnabled())";
+ String[] ignore = new String[] { "sun/", "java/", "javax/", "org/slf4j/",
+ "ch/qos/logback/" };
+
+ public byte[] transform(ClassLoader loader, String className, Class<?> clazz,
+ java.security.ProtectionDomain domain, byte[] bytes) {
+
+ for (int i = 0; i < ignore.length; i++) {
+ if (className.startsWith(ignore[i])) {
+ return bytes;
+ }
+ }
+ //System.out.println("Adding to " + className);
+ return doClass(className, clazz, bytes);
+ }
+
+ //
+ // The transform(...) method calls doClass(...) if the class name does not
+ // start with any of the prefixes it has been told to ignore (note that the
+ // separators are slashes, not dots).
+
+ private byte[] doClass(String name, Class<?> clazz, byte[] b) {
+ ClassPool pool = ClassPool.getDefault();
+ CtClass cl = null;
+ try {
+ cl = pool.makeClass(new ByteArrayInputStream(b));
+ if (cl.isInterface() == false) {
+
+ CtField field = CtField.make(def, cl);
+ String getLogger = "org.slf4j.LoggerFactory.getLogger("
+ + name.replace('/', '.') + ".class);";
+ cl.addField(field, getLogger);
+ System.out.println(getLogger);
+
+ CtBehavior[] methods = cl.getDeclaredBehaviors();
+ for (int i = 0; i < methods.length; i++) {
+ if (methods[i].isEmpty() == false) {
+ doMethod(methods[i]);
+ }
+ }
+ b = cl.toBytecode();
+ }
+ } catch (Exception e) {
+ System.err.println("Could not instrument " + name
+ + ", exception : " + e.getMessage());
+ } finally {
+ if (cl != null) {
+ cl.detach();
+ }
+ }
+ return b;
+ }
+
+ private void doMethod(CtBehavior method) throws NotFoundException,
+ CannotCompileException {
+
+ String signature = JavassistHelper.getSignature(method);
+ String returnValue = JavassistHelper.returnValue(method);
+
+ method.insertBefore(ifLog + "_log" + ".info(\">> " + signature + ");");
+
+ method.insertAfter(ifLog + "_log" + ".info(\"<< " + signature
+ + returnValue + ");");
+ }
+}
\ No newline at end of file
More information about the slf4j-dev
mailing list