1 /** 2 * Copyright (c) 2004-2011 QOS.ch 3 * All rights reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sublicense, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be 14 * included in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 * 24 */ 25 package org.slf4j.agent; 26 27 import java.io.ByteArrayInputStream; 28 import java.io.IOException; 29 import java.lang.instrument.Instrumentation; 30 import java.util.Date; 31 import java.util.Properties; 32 33 import org.slf4j.instrumentation.LogTransformer; 34 35 /** 36 * Entry point for slf4j-ext when used as a Java agent. 37 * 38 */ 39 public class AgentPremain { 40 41 /** 42 * JavaAgent premain entry point as specified in the MANIFEST.MF file. See 43 * {@link http 44 * ://java.sun.com/javase/6/docs/api/java/lang/instrument/package- 45 * summary.html} for details. 46 * 47 * @param agentArgument 48 * string provided after "=" up to first space 49 * @param instrumentation 50 * instrumentation environment provided by the JVM 51 */ premain(String agentArgument, Instrumentation instrumentation)52 public static void premain(String agentArgument, Instrumentation instrumentation) { 53 54 // We cannot do sanity checks for slf4j here as the jars loaded 55 // by the application are not visible here. 56 57 LogTransformer.Builder builder = new LogTransformer.Builder(); 58 builder = builder.addEntryExit(true); 59 60 if (agentArgument != null) { 61 Properties args = parseArguments(agentArgument, ","); 62 63 if (args.containsKey(AgentOptions.VERBOSE)) { 64 builder = builder.verbose(true); 65 } 66 67 if (args.containsKey(AgentOptions.TIME)) { 68 printStartStopTimes(); 69 } 70 71 if (args.containsKey(AgentOptions.IGNORE)) { 72 String ignore = args.getProperty(AgentOptions.IGNORE); 73 builder = builder.ignore(ignore.split(":")); 74 } 75 76 if (args.containsKey(AgentOptions.LEVEL)) { 77 builder = builder.level(args.getProperty(AgentOptions.LEVEL)); 78 } 79 } 80 81 instrumentation.addTransformer(builder.build()); 82 } 83 84 /** 85 * Consider the argument string to be a property file (by converting the 86 * splitter character to line feeds), and then reading it like any other 87 * property file. 88 * 89 * 90 * @param agentArgument 91 * string given by instrumentation framework 92 * @param separator 93 * String to convert to line feeds 94 * @return argument converted to properties 95 */ parseArguments(String agentArgument, String separator)96 private static Properties parseArguments(String agentArgument, String separator) { 97 Properties p = new Properties(); 98 try { 99 String argumentAsLines = agentArgument.replaceAll(separator, "\n"); 100 p.load(new ByteArrayInputStream(argumentAsLines.getBytes())); 101 } catch (IOException e) { 102 String s = "Could not load arguments as properties"; 103 throw new RuntimeException(s, e); 104 } 105 return p; 106 } 107 108 /** 109 * Print the start message to System.err with the time NOW, and register a 110 * shutdown hook which will print the stop message to System.err with the 111 * time then and the number of milliseconds passed since. 112 * 113 */ printStartStopTimes()114 private static void printStartStopTimes() { 115 final long start = System.currentTimeMillis(); 116 117 System.err.println("Start at " + new Date()); 118 119 Thread hook = new Thread() { 120 @Override 121 public void run() { 122 long timePassed = System.currentTimeMillis() - start; 123 System.err.println("Stop at " + new Date() + ", execution time = " + timePassed + " ms"); 124 } 125 }; 126 Runtime.getRuntime().addShutdownHook(hook); 127 } 128 }