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}