[slf4j-dev] svn commit: r1157 - in slf4j/trunk/slf4j-ext/src/main/java/org/slf4j: agent instrumentation
ravn at slf4j.org
ravn at slf4j.org
Thu Oct 2 00:26:25 CEST 2008
Author: ravn
Date: Thu Oct 2 00:26:24 2008
New Revision: 1157
Modified:
slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/agent/AgentPremain.java
slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/instrumentation/JavassistHelper.java
slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/instrumentation/LogTransformer.java
Log:
now usable as a javaagent, tested with log4j
Modified: slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/agent/AgentPremain.java
==============================================================================
--- slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/agent/AgentPremain.java (original)
+++ slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/agent/AgentPremain.java Thu Oct 2 00:26:24 2008
@@ -2,11 +2,11 @@
import static org.slf4j.helpers.MessageFormatter.format;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
import java.lang.instrument.Instrumentation;
-import java.util.Arrays;
import java.util.Date;
-import java.util.HashSet;
-import java.util.Set;
+import java.util.Properties;
import org.slf4j.instrumentation.LogTransformer;
@@ -20,25 +20,40 @@
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));
+ Properties args = parseArguments(agentArgument);
- if (argSet.contains("verbose")) {
+ if (args.containsKey("verbose")) {
builder = builder.verbose(true);
}
-
- if (argSet.contains("time")) {
+
+ if (args.containsKey("time")) {
printStartStopTimes();
}
-
+
+ if (args.containsKey("ignore")) {
+ builder = builder.ignore(args.getProperty("ignore").split(","));
+ }
+
// ... more agent option handling here
}
instrumentation.addTransformer(builder.build());
}
+ private static Properties parseArguments(String agentArgument) {
+ Properties p = new Properties();
+ try {
+ byte[] bytes = agentArgument.replaceAll(";", "\n").getBytes();
+ p.load(new ByteArrayInputStream(bytes));
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "Could not load arguments as properties", e);
+ }
+ return p;
+ }
+
/**
* 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
Modified: slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/instrumentation/JavassistHelper.java
==============================================================================
--- slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/instrumentation/JavassistHelper.java (original)
+++ slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/instrumentation/JavassistHelper.java Thu Oct 2 00:26:24 2008
@@ -68,7 +68,7 @@
sb.append("\"+ $" + (i + 1));
}
}
- sb.append("+\")\"");
+ sb.append("+\")");
String signature = sb.toString();
return signature;
Modified: slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/instrumentation/LogTransformer.java
==============================================================================
--- slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/instrumentation/LogTransformer.java (original)
+++ slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/instrumentation/LogTransformer.java Thu Oct 2 00:26:24 2008
@@ -16,15 +16,41 @@
import javassist.CtField;
import javassist.NotFoundException;
+import org.slf4j.helpers.MessageFormatter;
+
+/**
+ * LogTransformer does the work of analyzing each class, and if appropriate add
+ * log statements to each method to allow logging entry/exit.
+ *
+ */
public class LogTransformer implements ClassFileTransformer {
+ // http://rwhansen.blogspot.com/2007/07/theres-builder-pattern-that-joshua.html
public static class Builder {
+
+ /**
+ * Build and return the LogTransformer corresponding to the options set
+ * in this Builder.
+ *
+ * @return
+ */
public LogTransformer build() {
+ if (verbose) {
+ System.err.println("Creating LogTransformer");
+ }
return new LogTransformer(this);
}
boolean addEntryExit;
+ /**
+ * Should each method log entry (with parameters) and exit (with
+ * parameters and returnvalue)?
+ *
+ * @param b
+ * value of flag
+ * @return
+ */
public Builder addEntryExit(boolean b) {
addEntryExit = b;
return this;
@@ -32,38 +58,59 @@
boolean addVariableAssignment;
- public Builder addVariableAssignment(boolean b) {
+ private Builder addVariableAssignment(boolean b) {
System.err.println("cannot currently log variable assignments.");
addVariableAssignment = b;
return this;
}
+
boolean verbose;
+ /**
+ * Should LogTransformer be verbose in what it does? This currently list
+ * the names of the classes being processed.
+ *
+ * @param b
+ * @return
+ */
public Builder verbose(boolean b) {
verbose = b;
return this;
}
+
+ String[] ignore = { "sun/", "java/", "javax/", "org/slf4j/",
+ "ch/qos/logback/" , "org/apache/log4j/"};
+ public Builder ignore(String[] strings) {
+ this.ignore = strings;
+ return this;
+ }
}
-
private LogTransformer(Builder builder) {
this.addEntryExit = builder.addEntryExit;
this.addVariableAssignment = builder.addVariableAssignment;
this.verbose = builder.verbose;
+ this.ignore = builder.ignore;
}
private static final String _LOG = "_log";
- String[] ignore = { "sun/", "java/", "javax/", "org/slf4j/",
- "ch/qos/logback/" };
private boolean addEntryExit;
private boolean addVariableAssignment;
private boolean verbose;
+ private String[] ignore;
public byte[] transform(ClassLoader loader, String className,
Class<?> clazz, ProtectionDomain domain, byte[] bytes) {
+
- return transform0(className, clazz, bytes);
+ try {
+ return transform0(className, clazz, bytes);
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ return bytes;
+ }
}
/**
@@ -152,12 +199,14 @@
if (addEntryExit) {
String messagePattern = "if ({}.isDebugEnabled()) {}.info(\">> {}\");";
Object[] arg1 = new Object[] { _LOG, _LOG, signature };
- String before = format(messagePattern, arg1);
+ String before = MessageFormatter.arrayFormat(messagePattern, arg1);
+ //System.out.println(before);
method.insertBefore(before);
String messagePattern2 = "if ({}.isDebugEnabled()) {}.info(\"<< {}{}\");";
Object[] arg2 = new Object[] { _LOG, _LOG, signature, returnValue };
- String after = format(messagePattern2, arg2);
+ String after = MessageFormatter.arrayFormat(messagePattern2, arg2);
+ //System.out.println(after);
method.insertAfter(after);
}
}
More information about the slf4j-dev
mailing list