[slf4j-dev] svn commit: r1155 - in slf4j/trunk/slf4j-ext/src/main/java/org/slf4j: agent instrumentation
Ralph Goers
ralph.goers at dslextreme.com
Wed Oct 1 22:53:36 CEST 2008
Can you describe how this is intended to work? Does this inject logging
at runtime or build time?
ravn at slf4j.org wrote:
> 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
> _______________________________________________
> dev mailing list
> dev at slf4j.org
> http://www.slf4j.org/mailman/listinfo/dev
>
More information about the slf4j-dev
mailing list