[slf4j-dev] svn commit: r1155 - in slf4j/trunk/slf4j-ext/src/main/java/org/slf4j: agent instrumentation

ravn at slf4j.org ravn at slf4j.org
Wed Oct 1 21:57:55 CEST 2008


Author: ravn
Date: Wed Oct  1 21:57:55 2008
New Revision: 1155

Added:
   slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/agent/AgentPremain.java   (contents, props changed)
      - copied, changed from r1154, /slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/agent/AgentMain.java
   slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/instrumentation/LogTransformer.java   (contents, props changed)
      - copied, changed from r1154, /slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/instrumentation/AddEntryExitLoggingTransformer.java
Removed:
   slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/agent/AgentMain.java
   slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/instrumentation/AddEntryExitLoggingTransformer.java

Log:
beginning to generalize premain() and log transformer (which now has a builder)

Copied: slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/agent/AgentPremain.java (from r1154, /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/AgentPremain.java	Wed Oct  1 21:57:55 2008
@@ -1,37 +1,62 @@
 package org.slf4j.agent;
 
+import static org.slf4j.helpers.MessageFormatter.format;
+
 import java.lang.instrument.Instrumentation;
 import java.util.Arrays;
 import java.util.Date;
 import java.util.HashSet;
 import java.util.Set;
 
-import org.slf4j.instrumentation.AddEntryExitLoggingTransformer;
+import org.slf4j.instrumentation.LogTransformer;
+
+public class AgentPremain {
 
-public class AgentMain {
+	private static final String START_MSG = "Start at {}";
+	private static final String STOP_MSG = "Stop at {}, execution time = {} ms";
 
 	public static void premain(String agentArgument,
 			Instrumentation instrumentation) {
 
+		LogTransformer.Builder builder = new LogTransformer.Builder();
+		builder = builder.addEntryExit(true);
+		
 		if (agentArgument != null) {
 			String[] args = agentArgument.split(",");
 			Set<String> argSet = new HashSet<String>(Arrays.asList(args));
 
+			if (argSet.contains("verbose")) {
+				builder = builder.verbose(true);
+			}
+			
 			if (argSet.contains("time")) {
-				final long start = System.currentTimeMillis();
-				System.out.println("Start at " + new Date());
-				Runtime.getRuntime().addShutdownHook(new Thread() {
-					public void run() {
-						System.out.println("Stop at " + new Date()
-								+ ", execution time = "
-								+ (System.currentTimeMillis() - start) + " ms");
-					}
-				});
+				printStartStopTimes();
 			}
+			
 			// ... more agent option handling here
 		}
 
-		instrumentation.addTransformer(new AddEntryExitLoggingTransformer());
+		instrumentation.addTransformer(builder.build());
+	}
+
+	/**
+	 * Print the start message with the time NOW, and register a shutdown hook
+	 * which will print the stop message with the time then and the number of
+	 * milliseconds passed since.
+	 * 
+	 */
+	private static void printStartStopTimes() {
+		final long start = System.currentTimeMillis();
+		System.err.println(format(START_MSG, new Date()));
+
+		Thread hook = new Thread() {
+			public void run() {
+				long timePassed = System.currentTimeMillis() - start;
+				String message = format(STOP_MSG, new Date(), timePassed);
+				System.err.println(message);
+			}
+		};
+		Runtime.getRuntime().addShutdownHook(hook);
 	}
 
 }
\ No newline at end of file

Copied: slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/instrumentation/LogTransformer.java (from r1154, /slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/instrumentation/AddEntryExitLoggingTransformer.java)
==============================================================================
--- /slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/instrumentation/AddEntryExitLoggingTransformer.java	(original)
+++ slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/instrumentation/LogTransformer.java	Wed Oct  1 21:57:55 2008
@@ -16,21 +16,75 @@
 import javassist.CtField;
 import javassist.NotFoundException;
 
-public class AddEntryExitLoggingTransformer implements ClassFileTransformer {
+public class LogTransformer implements ClassFileTransformer {
+
+	public static class Builder {
+		public LogTransformer build() {
+			return new LogTransformer(this);
+		}
+
+		boolean addEntryExit;
+
+		public Builder addEntryExit(boolean b) {
+			addEntryExit = b;
+			return this;
+		}
+
+		boolean addVariableAssignment;
+
+		public Builder addVariableAssignment(boolean b) {
+			System.err.println("cannot currently log variable assignments.");
+			addVariableAssignment = b;
+			return this;
+		}
+		boolean verbose;
+
+		public Builder verbose(boolean b) {
+			verbose = b;
+			return this;
+		}
+	}
+
+
+	private LogTransformer(Builder builder) {
+		this.addEntryExit = builder.addEntryExit;
+		this.addVariableAssignment = builder.addVariableAssignment;
+		this.verbose = builder.verbose;
+	}
 
 	private static final String _LOG = "_log";
-	String[] ignore = new String[] { "sun/", "java/", "javax/", "org/slf4j/",
+	String[] ignore = { "sun/", "java/", "javax/", "org/slf4j/",
 			"ch/qos/logback/" };
 
+	private boolean addEntryExit;
+	private boolean addVariableAssignment;
+	private boolean verbose;
+
 	public byte[] transform(ClassLoader loader, String className,
 			Class<?> clazz, ProtectionDomain domain, byte[] bytes) {
 
+		return transform0(className, clazz, bytes);
+	}
+
+	/**
+	 * transform0 sees if the className starts with any of the namespaces to
+	 * ignore, if so it is returned unchanged. Otherwise it is processed by
+	 * doClass(...)
+	 * 
+	 * @param className
+	 * @param clazz
+	 * @param bytes
+	 * @return
+	 */
+	private byte[] transform0(String className, Class<?> clazz, byte[] bytes) {
 		for (int i = 0; i < ignore.length; i++) {
 			if (className.startsWith(ignore[i])) {
 				return bytes;
 			}
 		}
-		// System.out.println("Adding to " + className);
+		if (verbose) {
+			System.err.println("Loggifying " + className);
+		}
 		return doClass(className, clazz, bytes);
 	}
 
@@ -95,14 +149,16 @@
 		String signature = JavassistHelper.getSignature(method);
 		String returnValue = JavassistHelper.returnValue(method);
 
-		String messagePattern = "if ({}.isDebugEnabled()) {}.info(\">> {}\");";
-		Object[] arg1 = new Object[] { _LOG, _LOG, signature };
-		String before = format(messagePattern, arg1);
-		method.insertBefore(before);
-
-		String messagePattern2 = "if ({}.isDebugEnabled()) {}.info(\"<< {}{}\");";
-		Object[] arg2 = new Object[] { _LOG, _LOG, signature, returnValue };
-		String after = format(messagePattern2, arg2);
-		method.insertAfter(after);
+		if (addEntryExit) {
+			String messagePattern = "if ({}.isDebugEnabled()) {}.info(\">> {}\");";
+			Object[] arg1 = new Object[] { _LOG, _LOG, signature };
+			String before = format(messagePattern, arg1);
+			method.insertBefore(before);
+
+			String messagePattern2 = "if ({}.isDebugEnabled()) {}.info(\"<< {}{}\");";
+			Object[] arg2 = new Object[] { _LOG, _LOG, signature, returnValue };
+			String after = format(messagePattern2, arg2);
+			method.insertAfter(after);
+		}
 	}
 }
\ No newline at end of file



More information about the slf4j-dev mailing list