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