AgentPremain xref

View Javadoc

    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  	 */
    52  	public static void premain(String agentArgument,
    53  			Instrumentation instrumentation) {
    54
    55  		// We cannot do sanity checks for slf4j here as the jars loaded
    56  		// by the application are not visible here.
    57
    58  		LogTransformer.Builder builder = new LogTransformer.Builder();
    59  		builder = builder.addEntryExit(true);
    60
    61  		if (agentArgument != null) {
    62  			Properties args = parseArguments(agentArgument, ",");
    63
    64  			if (args.containsKey(AgentOptions.VERBOSE)) {
    65  				builder = builder.verbose(true);
    66  			}
    67
    68  			if (args.containsKey(AgentOptions.TIME)) {
    69  				printStartStopTimes();
    70  			}
    71
    72  			if (args.containsKey(AgentOptions.IGNORE)) {
    73  				String ignore = args.getProperty(AgentOptions.IGNORE);
    74  				builder = builder.ignore(ignore.split(":"));
    75  			}
    76
    77  			if (args.containsKey(AgentOptions.LEVEL)) {
    78  				builder = builder.level(args.getProperty(AgentOptions.LEVEL));
    79  			}
    80  		}
    81
    82  		instrumentation.addTransformer(builder.build());
    83  	}
    84
    85  	/**
    86  	 * Consider the argument string to be a property file (by converting the
    87  	 * splitter character to line feeds), and then reading it like any other
    88  	 * property file.
    89  	 *
    90  	 *
    91  	 * @param agentArgument
    92  	 *            string given by instrumentation framework
    93  	 * @param separator
    94  	 *            String to convert to line feeds
    95  	 * @return argument converted to properties
    96  	 */
    97  	private static Properties parseArguments(String agentArgument,
    98  			String separator) {
    99  		Properties p = new Properties();
    100 		try {
    101 			String argumentAsLines = agentArgument.replaceAll(separator, "\n");
    102 			p.load(new ByteArrayInputStream(argumentAsLines.getBytes()));
    103 		} catch (IOException e) {
    104 			String s = "Could not load arguments as properties";
    105 			throw new RuntimeException(s, e);
    106 		}
    107 		return p;
    108 	}
    109
    110 	/**
    111 	 * Print the start message to System.err with the time NOW, and register a
    112 	 * shutdown hook which will print the stop message to System.err with the
    113 	 * time then and the number of milliseconds passed since.
    114 	 *
    115 	 */
    116 	private static void printStartStopTimes() {
    117 		final long start = System.currentTimeMillis();
    118
    119 		System.err.println("Start at " + new Date());
    120
    121 		Thread hook = new Thread() {
    122 			@Override
    123 			public void run() {
    124 				long timePassed = System.currentTimeMillis() - start;
    125 				System.err.println("Stop at " + new Date()
    126 						+ ", execution time = " + timePassed + " ms");
    127 			}
    128 		};
    129 		Runtime.getRuntime().addShutdownHook(hook);
    130 	}
    131 }