Skip to content

Commit eedfe2d

Browse files
authored
Enable Cold Start (#602)
* removing logAlways and converting to equivalent error methods wherever possible * Better log decoration
1 parent a15ee07 commit eedfe2d

26 files changed

+330
-247
lines changed

agent/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ apply from: "$buildScriptsDir/common-java.gradle"
2828
shadowJar {
2929
classifier = ''
3030
relocate 'org.objectweb.asm', 'com.microsoft.applicationinsights.agent.dependencies.asm'
31+
relocate 'org.apache.commons', 'com.microsoft.applicationinsights.agent.dependencies.apachecommons'
3132
}
3233
archivesBaseName = 'applicationinsights-agent'
3334

@@ -47,6 +48,7 @@ jar {
4748
dependencies {
4849
compile group: 'org.ow2.asm', name: 'asm-commons', version: '5.2'
4950
compile group: 'org.ow2.asm', name: 'asm-all', version: '5.2'
51+
compile group: 'org.apache.commons', name:'commons-lang3', version:'3.7'
5052
testCompile group: 'commons-io', name: 'commons-io', version: '2.6'
5153
testCompile group: 'junit', name: 'junit', version: '4.12'
5254
testCompile group: 'org.mockito', name: 'mockito-all', version: '1.10.19'

agent/src/main/java/com/microsoft/applicationinsights/agent/internal/agent/AgentImplementation.java

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import com.microsoft.applicationinsights.agent.internal.config.DataOfConfigurationForException;
2828
import com.microsoft.applicationinsights.agent.internal.coresync.impl.ImplementationsCoordinator;
2929
import com.microsoft.applicationinsights.agent.internal.logger.InternalAgentLogger;
30+
import org.apache.commons.lang3.exception.ExceptionUtils;
3031

3132
import java.io.File;
3233
import java.io.IOException;
@@ -63,13 +64,15 @@ public static void premain(String args, Instrumentation inst) {
6364
throw td;
6465
} catch (Throwable throwable) {
6566
try {
66-
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.ERROR, "Agent is NOT activated: failed to load to bootstrap class loader: %s", throwable.toString()); throwable.printStackTrace();
67+
InternalAgentLogger.INSTANCE.error("Agent is NOT activated: failed to load to bootstrap class loader: %s",
68+
ExceptionUtils.getStackTrace(throwable));
6769
System.exit(-1);
6870
} catch (ThreadDeath td) {
6971
throw td;
7072
} catch (Throwable t) {
7173
// chomp
7274
}
75+
7376
}
7477
}
7578

@@ -93,21 +96,21 @@ private static void initializeCodeInjector(Instrumentation inst) throws Throwabl
9396
DataOfConfigurationForException exceptionData = agentConfiguration.getBuiltInConfiguration().getDataOfConfigurationForException();
9497
if (inst.isRetransformClassesSupported()) {
9598
if (exceptionData.isEnabled()) {
96-
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.TRACE, "Instrumenting runtime exceptions.");
99+
InternalAgentLogger.INSTANCE.trace("Instrumenting runtime exceptions.");
97100

98101
inst.addTransformer(codeInjector, true);
99102
ImplementationsCoordinator.INSTANCE.setExceptionData(exceptionData);
100103
inst.retransformClasses(RuntimeException.class);
101104
inst.removeTransformer(codeInjector);
102105
}
103-
} else {
106+
} else {
104107
if (exceptionData.isEnabled()) {
105-
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.TRACE, "The JVM does not support re-transformation of classes.");
108+
InternalAgentLogger.INSTANCE.trace("The JVM does not support re-transformation of classes.");
106109
}
107-
}
110+
}
108111
inst.addTransformer(codeInjector);
109112
} catch (Exception e) {
110-
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.ERROR, "Failed to load the code injector, exception: %s", e.toString());
113+
InternalAgentLogger.INSTANCE.error("Failed to load the code injector, exception: %s", ExceptionUtils.getStackTrace(e));
111114
throw e;
112115
}
113116
}
@@ -120,13 +123,13 @@ private static void appendJarsToBootstrapClassLoader(Instrumentation inst) throw
120123
for (File file : agentFolder.listFiles()) {
121124
if (file.getName().indexOf(AGENT_JAR_PREFIX) != -1) {
122125
agentJarName = file.getName();
123-
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.INFO,"Agent jar name is %s", agentJarName);
126+
InternalAgentLogger.INSTANCE.info("Agent jar name is %s", agentJarName);
124127
break;
125128
}
126129
}
127130

128131
if (agentJarName == null) {
129-
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.ERROR,"Agent Jar Name is null....Throwing runtime exception");
132+
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.ERROR, "Agent Jar Name is null....Throwing runtime exception");
130133
throw new RuntimeException("Could not find agent jar");
131134
}
132135

@@ -138,7 +141,7 @@ private static void appendJarsToBootstrapClassLoader(Instrumentation inst) throw
138141

139142
inst.appendToBootstrapClassLoaderSearch(agentJar);
140143

141-
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.TRACE, "Successfully loaded Agent jar");
144+
InternalAgentLogger.INSTANCE.trace("Successfully loaded Agent jar");
142145
}
143146

144147
public static String getAgentJarLocation() throws UnsupportedEncodingException {
@@ -149,7 +152,7 @@ public static String getAgentJarLocation() throws UnsupportedEncodingException {
149152
String urlPath = url.getPath();
150153

151154
if (urlPath.indexOf(AGENT_JAR_PREFIX) != -1) {
152-
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.INFO,"Agent jar found at %s", urlPath);
155+
InternalAgentLogger.INSTANCE.info("Agent jar found at %s", urlPath);
153156
int index = urlPath.lastIndexOf('/');
154157
urlPath = urlPath.substring(0, index + 1);
155158
return urlPath;
@@ -160,7 +163,7 @@ public static String getAgentJarLocation() throws UnsupportedEncodingException {
160163
} catch (ThreadDeath td) {
161164
throw td;
162165
} catch (Throwable throwable) {
163-
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.ERROR, "Error while trying to fetch Jar Location, Exception: %s", throwable.toString());
166+
InternalAgentLogger.INSTANCE.error("Error while trying to fetch Jar Location, Exception: %s", ExceptionUtils.getStackTrace(throwable));
164167
}
165168

166169
String stringPath = AgentImplementation.class.getProtectionDomain().getCodeSource().getLocation().getPath();
@@ -175,76 +178,76 @@ private static void SetNonWebAppModeIfAskedByConf(String sdkPath) throws Throwab
175178
File sdkFolder = new File(path);
176179
if (!sdkFolder.exists()) {
177180
String errorMessage = String.format("Path %s for core jar does not exist", path);
178-
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.ERROR, errorMessage);
181+
InternalAgentLogger.INSTANCE.error(errorMessage);
179182
throw new Exception(errorMessage);
180183
}
181184

182185
if (!sdkFolder.isDirectory()) {
183186
String errorMessage = String.format("Path %s for core jar must be a folder", path);
184-
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.ERROR, errorMessage);
187+
InternalAgentLogger.INSTANCE.error(errorMessage);
185188
throw new Exception(errorMessage);
186189
}
187190

188191
if (!sdkFolder.canRead()) {
189192
String errorMessage = String.format("Path %s for core jar must be a folder that can be read", path);
190-
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.ERROR, errorMessage);
193+
InternalAgentLogger.INSTANCE.error(errorMessage);
191194
throw new Exception(errorMessage);
192195
}
193196

194-
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.TRACE, "Found %s", path);
197+
InternalAgentLogger.INSTANCE.trace("Found %s", path);
195198
String coreJarName = null;
196199
for (File file : sdkFolder.listFiles()) {
197200
if (file.getName().indexOf(CORE_JAR_PREFIX) != -1 || file.getName().indexOf(DISTRIBUTION_JAR_PREFIX) != -1) {
198201
coreJarName = file.getAbsolutePath();
199-
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.TRACE, "Found core jar: %s", coreJarName);
202+
InternalAgentLogger.INSTANCE.trace("Found core jar: %s", coreJarName);
200203
break;
201204
}
202205
}
203206

204207
if (coreJarName == null) {
205208
String errorMessage = String.format("Did not find core jar in path %s", path);
206-
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.ERROR, errorMessage);
209+
InternalAgentLogger.INSTANCE.error(errorMessage);
207210
throw new Exception(errorMessage);
208211
}
209212

210-
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.TRACE, "Found jar: %s", coreJarName);
213+
InternalAgentLogger.INSTANCE.trace("Found jar: %s", coreJarName);
211214

212215
JarFile jarFile = null;
213216
try {
214217
jarFile = new JarFile(coreJarName);
215218
} catch (IOException e) {
216-
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.ERROR, "Could not load jar: %s", coreJarName);
219+
InternalAgentLogger.INSTANCE.error("Could not load jar: %s", coreJarName);
217220
throw e;
218221
}
219222
Enumeration<JarEntry> e = jarFile.entries();
220223

221-
URL[] urls = { new URL("jar:file:" + coreJarName+"!/") };
224+
URL[] urls = {new URL("jar:file:" + coreJarName + "!/")};
222225
URLClassLoader cl = URLClassLoader.newInstance(urls);
223226

224227
while (e.hasMoreElements()) {
225228
JarEntry je = e.nextElement();
226-
if(je.isDirectory() || !je.getName().endsWith(".class")){
229+
if (je.isDirectory() || !je.getName().endsWith(".class")) {
227230
continue;
228231
}
229232
try {
230233
Class clazz = cl.loadClass(CORE_SELF_REGISTRATOR_CLASS_NAME);
231234
clazz.getDeclaredConstructor().newInstance();
232-
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.TRACE, "Loaded core jar");
235+
InternalAgentLogger.INSTANCE.trace("Loaded core jar");
233236
break;
234237
} catch (ClassNotFoundException e1) {
235-
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.ERROR, "Could not load class: %s, ClassNotFoundException", CORE_SELF_SHORT_REGISTRATOR_CLASS_NAME);
238+
InternalAgentLogger.INSTANCE.error("Could not load class: %s, ClassNotFoundException", CORE_SELF_SHORT_REGISTRATOR_CLASS_NAME);
236239
throw e1;
237240
} catch (InvocationTargetException e1) {
238-
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.ERROR, "Could not load class: %s, InvocationTargetException", CORE_SELF_SHORT_REGISTRATOR_CLASS_NAME);
241+
InternalAgentLogger.INSTANCE.error("Could not load class: %s, InvocationTargetException", CORE_SELF_SHORT_REGISTRATOR_CLASS_NAME);
239242
throw e1;
240243
} catch (NoSuchMethodException e1) {
241-
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.ERROR, "Could not load class: %s, NoSuchMethodException", CORE_SELF_SHORT_REGISTRATOR_CLASS_NAME);
244+
InternalAgentLogger.INSTANCE.error("Could not load class: %s, NoSuchMethodException", CORE_SELF_SHORT_REGISTRATOR_CLASS_NAME);
242245
throw e1;
243246
} catch (InstantiationException e1) {
244-
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.ERROR, "Could not load class: %s, InstantiationException", CORE_SELF_SHORT_REGISTRATOR_CLASS_NAME);
247+
InternalAgentLogger.INSTANCE.error("Could not load class: %s, InstantiationException", CORE_SELF_SHORT_REGISTRATOR_CLASS_NAME);
245248
throw e1;
246249
} catch (IllegalAccessException e1) {
247-
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.ERROR, "Could not load class: %s, IllegalAccessException", CORE_SELF_SHORT_REGISTRATOR_CLASS_NAME);
250+
InternalAgentLogger.INSTANCE.error("Could not load class: %s, IllegalAccessException", CORE_SELF_SHORT_REGISTRATOR_CLASS_NAME);
248251
throw e1;
249252
}
250253
}

agent/src/main/java/com/microsoft/applicationinsights/agent/internal/agent/CodeInjector.java

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,11 @@
3131
import com.microsoft.applicationinsights.agent.internal.config.AgentConfigurationBuilderFactory;
3232
import com.microsoft.applicationinsights.agent.internal.coresync.impl.ImplementationsCoordinator;
3333
import com.microsoft.applicationinsights.agent.internal.logger.InternalAgentLogger;
34+
import org.apache.commons.lang3.exception.ExceptionUtils;
3435

3536
/**
3637
* The class is responsible for finding needed classes
37-
*
38+
* <p>
3839
* Created by gupele on 5/11/2015.
3940
*/
4041
public final class CodeInjector implements ClassFileTransformer {
@@ -45,19 +46,19 @@ public final class CodeInjector implements ClassFileTransformer {
4546
/**
4647
* The constructor will set all the data needed for the transformation
4748
*
48-
* @param agentConfiguration The configuration
49+
* @param agentConfiguration The configuration
4950
*/
5051
public CodeInjector(AgentConfiguration agentConfiguration) {
5152
try {
5253
loadConfiguration(agentConfiguration);
54+
InternalAgentLogger.INSTANCE.info("Agent is up");
5355

54-
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.INFO, "Agent is up");
5556
} catch (ThreadDeath td) {
5657
throw td;
5758
} catch (Throwable throwable) {
5859
try {
59-
throwable.printStackTrace();
60-
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.INFO, "Agent is NOT activated: failed to initialize CodeInjector: '%s'", throwable.toString());
60+
InternalAgentLogger.INSTANCE.error("Agent is NOT activated: failed to initialize CodeInjector: '%s'",
61+
ExceptionUtils.getStackTrace(throwable));
6162
} catch (ThreadDeath td) {
6263
throw td;
6364
} catch (Throwable t2) {
@@ -68,11 +69,12 @@ public CodeInjector(AgentConfiguration agentConfiguration) {
6869

6970
/**
7071
* Main method that transforms classes
71-
* @param loader The class loader that loaded this class
72-
* @param className The class name
72+
*
73+
* @param loader The class loader that loaded this class
74+
* @param className The class name
7375
* @param classBeingRedefined The class that is being redefined
74-
* @param protectionDomain The protection domain
75-
* @param originalBuffer The class that was loaded before transforming it
76+
* @param protectionDomain The protection domain
77+
* @param originalBuffer The class that was loaded before transforming it
7678
* @return A byte array that contains the transformed original class or the original one if nothing was done.
7779
* @throws IllegalClassFormatException Theoretical, since the following implementation won't throw.
7880
*/
@@ -91,8 +93,8 @@ public byte[] transform(
9193
throw td;
9294
} catch (Throwable throwable) {
9395
try {
94-
throwable.printStackTrace();
95-
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.ERROR, "Failed to instrument '%s', exception: '%s': ", className, throwable.toString());
96+
InternalAgentLogger.INSTANCE.error("Failed to instrument '%s', " +
97+
"exception: '%s'", className, ExceptionUtils.getStackTrace(throwable));
9698
} catch (ThreadDeath td) {
9799
throw td;
98100
} catch (Throwable t2) {
@@ -107,6 +109,7 @@ public byte[] transform(
107109
/**
108110
* The method will try to load the configuration file for the Agent. The file is optional but
109111
* is assumed to be located 'near' the agent jar. Failing to put the file there will cause the file not to be loaded
112+
*
110113
* @param agentConfiguration The configuration
111114
*/
112115
private void loadConfiguration(AgentConfiguration agentConfiguration) {
@@ -115,9 +118,9 @@ private void loadConfiguration(AgentConfiguration agentConfiguration) {
115118

116119
if (agentConfiguration.getBuiltInConfiguration().isJmxEnabled()) {
117120
jmxConnectorLoader = new JmxConnectorLoader();
118-
if (!jmxConnectorLoader.initialize()) {
119-
jmxConnectorLoader = null;
120-
}
121+
if (!jmxConnectorLoader.initialize()) {
122+
jmxConnectorLoader = null;
123+
}
121124
}
122125
}
123126
}

agent/src/main/java/com/microsoft/applicationinsights/agent/internal/agent/exceptions/RuntimeExceptionProvider.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import com.microsoft.applicationinsights.agent.internal.agent.*;
2525
import com.microsoft.applicationinsights.agent.internal.coresync.InstrumentedClassType;
2626
import com.microsoft.applicationinsights.agent.internal.logger.InternalAgentLogger;
27+
import org.apache.commons.lang3.exception.ExceptionUtils;
2728
import org.objectweb.asm.MethodVisitor;
2829

2930
import java.util.Map;
@@ -58,10 +59,11 @@ public MethodVisitor create(MethodInstrumentationDecision decision, int access,
5859

5960
classesToInstrument.put(RUNTIME_EXCEPTION_CLASS_NAME, data);
6061
} catch (ThreadDeath td) {
61-
throw td;
62+
throw td;
6263
} catch (Throwable t) {
6364
try {
64-
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.ERROR, "Failed to load instrumentation for Jedis: '%s'", t.toString()); } catch (ThreadDeath td) {
65+
InternalAgentLogger.INSTANCE.error("Failed to load instrumentation for Jedis: '%s'", ExceptionUtils.getStackTrace(t));
66+
} catch (ThreadDeath td) {
6567
throw td;
6668
} catch (Throwable t2) {
6769
// chomp

agent/src/main/java/com/microsoft/applicationinsights/agent/internal/agent/redis/JedisClassDataProvider.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
package com.microsoft.applicationinsights.agent.internal.agent.redis;
2323

2424
import com.microsoft.applicationinsights.agent.internal.logger.InternalAgentLogger;
25+
import org.apache.commons.lang3.exception.ExceptionUtils;
2526
import org.objectweb.asm.MethodVisitor;
2627

2728
import java.util.Map;
@@ -31,6 +32,7 @@
3132
import com.microsoft.applicationinsights.agent.internal.agent.MethodInstrumentationDecision;
3233
import com.microsoft.applicationinsights.agent.internal.agent.MethodVisitorFactory;
3334
import com.microsoft.applicationinsights.agent.internal.coresync.InstrumentedClassType;
35+
3436
/**
3537
* Created by gupele on 8/6/2015.
3638
*/
@@ -59,10 +61,11 @@ public MethodVisitor create(MethodInstrumentationDecision decision, int access,
5961

6062
classesToInstrument.put(JEDIS_CLASS_NAME, data);
6163
} catch (ThreadDeath td) {
62-
throw td;
64+
throw td;
6365
} catch (Throwable t) {
6466
try {
65-
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.ERROR, "Failed to load instrumentation for Jedis: '%s'", t.toString()); } catch (ThreadDeath td) {
67+
InternalAgentLogger.INSTANCE.error("Failed to load instrumentation for Jedis: '%s'", ExceptionUtils.getStackTrace(t));
68+
} catch (ThreadDeath td) {
6669
throw td;
6770
} catch (Throwable t2) {
6871
// chomp

agent/src/main/java/com/microsoft/applicationinsights/agent/internal/config/ConfigRuntimeExceptionDataBuilder.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
import com.microsoft.applicationinsights.agent.internal.common.StringUtils;
2525
import com.microsoft.applicationinsights.agent.internal.logger.InternalAgentLogger;
26+
import org.apache.commons.lang3.exception.ExceptionUtils;
2627
import org.w3c.dom.Element;
2728
import org.w3c.dom.Node;
2829
import org.w3c.dom.NodeList;
@@ -103,7 +104,8 @@ private void FetchStackSize(Element rtExceptionElement, DataOfConfigurationForEx
103104
int maxStackSize = Integer.parseInt(preparedValue);
104105
stackSize = maxStackSize;
105106
} catch (Exception e) {
106-
InternalAgentLogger.INSTANCE.logAlways(InternalAgentLogger.LoggingLevel.ERROR, "Failed to parse attribute %s with value %s, will send full stack", MAX_STACK_SIZE, maxStackSizeAsString);
107+
InternalAgentLogger.INSTANCE.error("Failed to parse attribute %s with value %s, will send full stack" +
108+
"exception : %s", MAX_STACK_SIZE, maxStackSizeAsString, ExceptionUtils.getStackTrace(e));
107109
}
108110
}
109111

0 commit comments

Comments
 (0)