AgentPremain.java revision a579aaf9c32a01a29111be23170824e6b0f3912a
1cdfaeefef04d5b1500e897ecc75982a5316407e8Thorbjorn Ravn Andersenpackage org.slf4j.agent; 2cdfaeefef04d5b1500e897ecc75982a5316407e8Thorbjorn Ravn Andersen 3cdfaeefef04d5b1500e897ecc75982a5316407e8Thorbjorn Ravn Andersenimport static org.slf4j.helpers.MessageFormatter.format; 4cdfaeefef04d5b1500e897ecc75982a5316407e8Thorbjorn Ravn Andersen 51adb4e0c1aa8507a14e69f57cb61698f9b0e0859Thorbjorn Ravn Andersenimport java.io.ByteArrayInputStream; 61adb4e0c1aa8507a14e69f57cb61698f9b0e0859Thorbjorn Ravn Andersenimport java.io.IOException; 7cdfaeefef04d5b1500e897ecc75982a5316407e8Thorbjorn Ravn Andersenimport java.lang.instrument.Instrumentation; 8cdfaeefef04d5b1500e897ecc75982a5316407e8Thorbjorn Ravn Andersenimport java.util.Date; 91adb4e0c1aa8507a14e69f57cb61698f9b0e0859Thorbjorn Ravn Andersenimport java.util.Properties; 10cdfaeefef04d5b1500e897ecc75982a5316407e8Thorbjorn Ravn Andersen 11cdfaeefef04d5b1500e897ecc75982a5316407e8Thorbjorn Ravn Andersenimport org.slf4j.instrumentation.LogTransformer; 12cdfaeefef04d5b1500e897ecc75982a5316407e8Thorbjorn Ravn Andersen 13fdb2c137a1e0917a356fe61846c4c406fb99fc7fThorbjorn Ravn Andersen/** 14fdb2c137a1e0917a356fe61846c4c406fb99fc7fThorbjorn Ravn Andersen * Entry point for slf4j-ext when used as a Java agent. 15a579aaf9c32a01a29111be23170824e6b0f3912aThorbjorn Ravn Andersen * 16fdb2c137a1e0917a356fe61846c4c406fb99fc7fThorbjorn Ravn Andersen */ 17cdfaeefef04d5b1500e897ecc75982a5316407e8Thorbjorn Ravn Andersenpublic class AgentPremain { 18cdfaeefef04d5b1500e897ecc75982a5316407e8Thorbjorn Ravn Andersen 19864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen private static final String START_MSG = "Start at {}"; 20864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen private static final String STOP_MSG = "Stop at {}, execution time = {} ms"; 21864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen 22864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen /** 23864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen * JavaAgent premain entry point as specified in the MANIFEST.MF file. See 24a579aaf9c32a01a29111be23170824e6b0f3912aThorbjorn Ravn Andersen * {@link http://java.sun.com/javase/6/docs/api/java/lang/instrument/package-summary.html} 25a579aaf9c32a01a29111be23170824e6b0f3912aThorbjorn Ravn Andersen * for details. 26864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen * 27864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen * @param agentArgument 28864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen * string provided after "=" up to first space 29864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen * @param instrumentation 308f3f8818814e1cd403a252fce527b1439147dd80Thorbjorn Ravn Andersen * instrumentation environment provided by the JVM 31864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen */ 32864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen public static void premain(String agentArgument, 33864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen Instrumentation instrumentation) { 34864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen 35864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen LogTransformer.Builder builder = new LogTransformer.Builder(); 36864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen builder = builder.addEntryExit(true); 37864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen 38864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen if (agentArgument != null) { 3942d254db97a8103ede6461d8d16303cbd037ccd5Thorbjorn Ravn Andersen Properties args = parseArguments(agentArgument, ";"); 40864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen 41fdb2c137a1e0917a356fe61846c4c406fb99fc7fThorbjorn Ravn Andersen if (args.containsKey(AgentOptions.VERBOSE)) { 42864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen builder = builder.verbose(true); 43864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen } 44864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen 45fdb2c137a1e0917a356fe61846c4c406fb99fc7fThorbjorn Ravn Andersen if (args.containsKey(AgentOptions.TIME)) { 46864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen printStartStopTimes(); 47864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen } 48864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen 49fdb2c137a1e0917a356fe61846c4c406fb99fc7fThorbjorn Ravn Andersen if (args.containsKey(AgentOptions.IGNORE)) { 50a579aaf9c32a01a29111be23170824e6b0f3912aThorbjorn Ravn Andersen String ignore = args.getProperty(AgentOptions.IGNORE); 51a579aaf9c32a01a29111be23170824e6b0f3912aThorbjorn Ravn Andersen builder = builder.ignore(ignore.split(",")); 52864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen } 53864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen 54fdb2c137a1e0917a356fe61846c4c406fb99fc7fThorbjorn Ravn Andersen if (args.containsKey(AgentOptions.LEVEL)) { 55fdb2c137a1e0917a356fe61846c4c406fb99fc7fThorbjorn Ravn Andersen builder = builder.level(args.getProperty(AgentOptions.LEVEL)); 56864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen } 57864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen } 58864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen 59864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen instrumentation.addTransformer(builder.build()); 60864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen } 61864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen 6242d254db97a8103ede6461d8d16303cbd037ccd5Thorbjorn Ravn Andersen /** 6342d254db97a8103ede6461d8d16303cbd037ccd5Thorbjorn Ravn Andersen * Consider the argument string to be a property file (by converting the 6442d254db97a8103ede6461d8d16303cbd037ccd5Thorbjorn Ravn Andersen * splitter character to line feeds), and then reading it like any other 6542d254db97a8103ede6461d8d16303cbd037ccd5Thorbjorn Ravn Andersen * property file. 6642d254db97a8103ede6461d8d16303cbd037ccd5Thorbjorn Ravn Andersen * 6742d254db97a8103ede6461d8d16303cbd037ccd5Thorbjorn Ravn Andersen * 6842d254db97a8103ede6461d8d16303cbd037ccd5Thorbjorn Ravn Andersen * @param agentArgument 6942d254db97a8103ede6461d8d16303cbd037ccd5Thorbjorn Ravn Andersen * string given by instrumentation framework 7042d254db97a8103ede6461d8d16303cbd037ccd5Thorbjorn Ravn Andersen * @param separator 7142d254db97a8103ede6461d8d16303cbd037ccd5Thorbjorn Ravn Andersen * String to convert to line feeds 7242d254db97a8103ede6461d8d16303cbd037ccd5Thorbjorn Ravn Andersen * @return argument converted to properties 7342d254db97a8103ede6461d8d16303cbd037ccd5Thorbjorn Ravn Andersen */ 7442d254db97a8103ede6461d8d16303cbd037ccd5Thorbjorn Ravn Andersen private static Properties parseArguments(String agentArgument, 7542d254db97a8103ede6461d8d16303cbd037ccd5Thorbjorn Ravn Andersen String separator) { 76864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen Properties p = new Properties(); 77864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen try { 7842d254db97a8103ede6461d8d16303cbd037ccd5Thorbjorn Ravn Andersen String argumentAsLines = agentArgument.replaceAll(separator, "\n"); 7942d254db97a8103ede6461d8d16303cbd037ccd5Thorbjorn Ravn Andersen p.load(new ByteArrayInputStream(argumentAsLines.getBytes())); 80864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen } catch (IOException e) { 81864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen String s = "Could not load arguments as properties"; 82864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen throw new RuntimeException(s, e); 83864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen } 84864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen return p; 85864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen } 86864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen 87864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen /** 8842d254db97a8103ede6461d8d16303cbd037ccd5Thorbjorn Ravn Andersen * Print the start message to System.err with the time NOW, and register a 8942d254db97a8103ede6461d8d16303cbd037ccd5Thorbjorn Ravn Andersen * shutdown hook which will print the stop message to System.err with the time 9042d254db97a8103ede6461d8d16303cbd037ccd5Thorbjorn Ravn Andersen * then and the number of milliseconds passed since. 91864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen * 92864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen */ 93864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen private static void printStartStopTimes() { 94864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen final long start = System.currentTimeMillis(); 95864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen System.err.println(format(START_MSG, new Date())); 96864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen 97864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen Thread hook = new Thread() { 98864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen @Override 99864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen public void run() { 100864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen long timePassed = System.currentTimeMillis() - start; 101864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen String message = format(STOP_MSG, new Date(), timePassed); 102864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen System.err.println(message); 103864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen } 104864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen }; 105864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen Runtime.getRuntime().addShutdownHook(hook); 106864af74b88c29f18244ba6dfb61636be7f120baaThorbjorn Ravn Andersen } 107cdfaeefef04d5b1500e897ecc75982a5316407e8Thorbjorn Ravn Andersen}