Skip to content

Commit c956e8e

Browse files
authored
Enable Awesome Logging (#1387)
* initial commit * added awesome logging for cdsprofiler end point ssl issue * Added awesome logging to all configuration issue scenarios * Fixed cdsprofiler url in the friendly log message * added unit tests for getFriendlyException
1 parent c506231 commit c956e8e

File tree

18 files changed

+323
-90
lines changed

18 files changed

+323
-90
lines changed

agent/agent-bootstrap/src/main/java/com/microsoft/applicationinsights/agent/bootstrap/MainEntryPoint.java

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,15 @@
2121
package com.microsoft.applicationinsights.agent.bootstrap;
2222

2323
import java.io.File;
24-
import java.lang.instrument.ClassFileTransformer;
25-
import java.lang.instrument.IllegalClassFormatException;
2624
import java.lang.instrument.Instrumentation;
2725
import java.net.URL;
2826
import java.nio.file.Path;
29-
import java.security.ProtectionDomain;
3027

3128
import ch.qos.logback.classic.Level;
3229
import com.microsoft.applicationinsights.agent.bootstrap.configuration.Configuration;
3330
import com.microsoft.applicationinsights.agent.bootstrap.configuration.Configuration.SelfDiagnostics;
3431
import com.microsoft.applicationinsights.agent.bootstrap.configuration.ConfigurationBuilder;
32+
import com.microsoft.applicationinsights.agent.bootstrap.customExceptions.FriendlyException;
3533
import com.microsoft.applicationinsights.agent.bootstrap.diagnostics.DiagnosticsHelper;
3634
import com.microsoft.applicationinsights.agent.bootstrap.diagnostics.status.StatusFile;
3735
import io.opentelemetry.javaagent.bootstrap.AgentInitializer;
@@ -83,11 +81,14 @@ public static void start(Instrumentation instrumentation, URL bootstrapURL) {
8381
} catch (ThreadDeath td) {
8482
throw td;
8583
} catch (Throwable t) {
86-
if (startupLogger != null) {
87-
startupLogger.error("ApplicationInsights Java Agent failed to start", t);
84+
85+
FriendlyException friendlyException = getFriendlyException(t);
86+
if (friendlyException != null) {
87+
logErrorMessage(startupLogger, friendlyException.getMessage(), true, t);
8888
} else {
89-
t.printStackTrace();
89+
logErrorMessage(startupLogger, "ApplicationInsights Java Agent failed to start", false, t);
9090
}
91+
9192
} finally {
9293
try {
9394
StatusFile.putValueAndWrite("AgentInitializedSuccessfully", success, startupLogger != null);
@@ -102,6 +103,34 @@ public static void start(Instrumentation instrumentation, URL bootstrapURL) {
102103
}
103104
}
104105

106+
// visible for testing
107+
static FriendlyException getFriendlyException(Throwable t) {
108+
if (t instanceof FriendlyException) {
109+
return (FriendlyException) t;
110+
}
111+
Throwable cause = t.getCause();
112+
if (cause == null) {
113+
return null;
114+
}
115+
return getFriendlyException(cause);
116+
}
117+
118+
private static void logErrorMessage(Logger startupLogger, String message, boolean isFriendlyException, Throwable t) {
119+
if (startupLogger != null) {
120+
if (isFriendlyException) {
121+
startupLogger.error(message);
122+
} else {
123+
startupLogger.error(message, t);
124+
}
125+
} else {
126+
if (isFriendlyException) {
127+
System.err.println(message);
128+
} else {
129+
t.printStackTrace();
130+
}
131+
}
132+
}
133+
105134
private static Logger configureLogging(SelfDiagnostics selfDiagnostics, Path agentPath) {
106135
String logbackXml;
107136
String destination = selfDiagnostics.destination;

agent/agent-bootstrap/src/main/java/com/microsoft/applicationinsights/agent/bootstrap/configuration/Configuration.java

Lines changed: 68 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
import java.util.regex.Pattern;
3030
import java.util.regex.PatternSyntaxException;
3131

32-
import com.microsoft.applicationinsights.agent.bootstrap.configuration.ConfigurationBuilder.ConfigurationException;
32+
import com.microsoft.applicationinsights.agent.bootstrap.customExceptions.FriendlyException;
3333

3434
import static java.util.concurrent.TimeUnit.MINUTES;
3535

@@ -122,17 +122,23 @@ public static class ProcessorConfig {
122122
public List<ProcessorAction> actions; // specific for processor type "attributes"
123123
public NameConfig name; // specific for processor types "log" and "span"
124124

125-
private static void isValidRegex(String value) {
125+
private static void isValidRegex(String value) throws FriendlyException {
126126
try {
127127
Pattern.compile(value);
128128
} catch (PatternSyntaxException exception) {
129-
throw new ConfigurationException("User provided processor config do not have valid regex:" + value);
129+
throw new FriendlyException("ApplicationInsights Java Agent failed to start.",
130+
"Telemetry processor configuration does not have valid regex:" + value,
131+
"Please provide a valid regex in the telemetry processors configuration. " +
132+
"Learn more about telemetry processors here: https://go.microsoft.com/fwlink/?linkid=2151557");
130133
}
131134
}
132135

133-
public void validate() {
136+
public void validate() throws FriendlyException {
134137
if (type == null) {
135-
throw new ConfigurationException("User provided config has a processor with no type!!!");
138+
throw new FriendlyException("ApplicationInsights Java Agent failed to start.",
139+
"Telemetry processor configuration has a processor with no type!!!",
140+
"Please provide a type in the telemetry processors configuration. " +
141+
"Learn more about telemetry processors here: https://go.microsoft.com/fwlink/?linkid=2151557");
136142
}
137143
if (include != null ) {
138144
include.validate(type);
@@ -144,21 +150,27 @@ public void validate() {
144150
validateLogOrSpanProcessorConfig();
145151
}
146152

147-
public void validateAttributeProcessorConfig() {
153+
public void validateAttributeProcessorConfig() throws FriendlyException {
148154
if (type == ProcessorType.attribute) {
149155
if (actions == null || actions.isEmpty()) {
150-
throw new ConfigurationException("User provided config has invalid attribute processor configuration with empty actions!!!");
156+
throw new FriendlyException("ApplicationInsights Java Agent failed to start.",
157+
"Telemetry processor configuration has invalid attribute processor configuration with empty actions!!!",
158+
"Please provide at least one action in the attribute processors configuration. " +
159+
"Learn more about telemetry processors here: https://go.microsoft.com/fwlink/?linkid=2151557");
151160
}
152161
for (ProcessorAction action : actions) {
153162
action.validate();
154163
}
155164
}
156165
}
157166

158-
public void validateLogOrSpanProcessorConfig() {
167+
public void validateLogOrSpanProcessorConfig() throws FriendlyException {
159168
if (type == ProcessorType.log || type == ProcessorType.span) {
160169
if (name == null) {
161-
throw new ConfigurationException("User provided config has invalid span/log processor configuration with empty name object!!!");
170+
throw new FriendlyException("ApplicationInsights Java Agent failed to start.",
171+
"Telemetry processor configuration has invalid span/log processor configuration with empty name object!!!",
172+
"Please provide name in the span/log processor configuration. " +
173+
"Learn more about telemetry processors here: https://go.microsoft.com/fwlink/?linkid=2151557");
162174
}
163175
name.validate();
164176
}
@@ -170,9 +182,12 @@ public static class NameConfig {
170182
public ToAttributeConfig toAttributes;
171183
public String separator;
172184

173-
public void validate() {
185+
public void validate() throws FriendlyException {
174186
if (fromAttributes == null && toAttributes == null) {
175-
throw new ConfigurationException("User provided config has invalid name object with no fromAttributes or no toAttributes!!!");
187+
throw new FriendlyException("ApplicationInsights Java Agent failed to start.",
188+
"Telemetry processor configuration has invalid name object with no fromAttributes or no toAttributes!!!",
189+
"Please provide at least one of fromAttributes or toAttributes in the processor configuration. " +
190+
"Learn more about telemetry processors here: https://go.microsoft.com/fwlink/?linkid=2151557");
176191
}
177192
if (toAttributes != null) toAttributes.validate();
178193
}
@@ -181,9 +196,12 @@ public void validate() {
181196
public static class ToAttributeConfig {
182197
public List<String> rules;
183198

184-
public void validate() {
199+
public void validate() throws FriendlyException {
185200
if(rules==null || rules.isEmpty()) {
186-
throw new ConfigurationException("User provided config has invalid toAttribute value with no rules!!!");
201+
throw new FriendlyException("ApplicationInsights Java Agent failed to start.",
202+
"Telemetry processor configuration has invalid toAttribute value with no rules!!!",
203+
"Please provide at least one rule under the toAttribute section of processor configuration. " +
204+
"Learn more about telemetry processors here: https://go.microsoft.com/fwlink/?linkid=2151557");
187205
}
188206
for (String rule : rules) {
189207
ProcessorConfig.isValidRegex(rule);
@@ -198,14 +216,20 @@ public static class ProcessorIncludeExclude {
198216
public List<String> logNames;
199217
public List<ProcessorAttribute> attributes;
200218

201-
public void validate (ProcessorType processorType) {
219+
public void validate (ProcessorType processorType) throws FriendlyException {
202220
if (this.matchType == null) {
203-
throw new ConfigurationException("User provided config has invalid include/exclude value with no matchType!!!");
221+
throw new FriendlyException("ApplicationInsights Java Agent failed to start.",
222+
"Telemetry processor configuration has invalid include/exclude value with no matchType!!!",
223+
"Please provide matchType under the include/exclude section of processor configuration. " +
224+
"Learn more about telemetry processors here: https://go.microsoft.com/fwlink/?linkid=2151557");
204225
}
205226
if (this.attributes != null) {
206227
for (ProcessorAttribute attribute : this.attributes) {
207228
if (attribute.key == null || attribute.key.isEmpty()) {
208-
throw new ConfigurationException("User provided config has invalid include/exclude value with attribute which has empty key!!!");
229+
throw new FriendlyException("ApplicationInsights Java Agent failed to start.",
230+
"Telemetry processor configuration has invalid include/exclude value with attribute which has empty key!!!",
231+
"Please provide valid key with value under the include/exclude's attribute section of processor configuration. " +
232+
"Learn more about telemetry processors here: https://go.microsoft.com/fwlink/?linkid=2151557");
209233
}
210234
if (this.matchType == ProcessorMatchType.regexp && attribute.value != null) {
211235
ProcessorConfig.isValidRegex(attribute.value);
@@ -222,9 +246,12 @@ public void validate (ProcessorType processorType) {
222246

223247
}
224248

225-
private void validAttributeProcessorIncludeExclude() {
249+
private void validAttributeProcessorIncludeExclude() throws FriendlyException {
226250
if (spanNames == null && attributes == null) {
227-
throw new ConfigurationException("User provided config has invalid include/exclude value with no spanNames or no attributes!!!");
251+
throw new FriendlyException("ApplicationInsights Java Agent failed to start.",
252+
"Telemetry processor configuration has invalid include/exclude value with no spanNames or no attributes!!!",
253+
"Please provide at least one of spanNames or attributes under the include/exclude section of processor configuration. " +
254+
"Learn more about telemetry processors here: https://go.microsoft.com/fwlink/?linkid=2151557");
228255
}
229256
if (spanNames != null && matchType == ProcessorMatchType.regexp) {
230257
for (String spanName : spanNames) {
@@ -233,9 +260,12 @@ private void validAttributeProcessorIncludeExclude() {
233260
}
234261
}
235262

236-
private void validateLogProcessorIncludeExclude() {
263+
private void validateLogProcessorIncludeExclude() throws FriendlyException {
237264
if (logNames == null && attributes == null) {
238-
throw new ConfigurationException("User provided config has invalid include/exclude value with no logNames or no attributes!!!");
265+
throw new FriendlyException("ApplicationInsights Java Agent failed to start.",
266+
"Telemetry processor configuration has invalid include/exclude value with no logNames or no attributes!!!",
267+
"Please provide at least one of logNames or attributes under the include/exclude section of processor configuration. " +
268+
"Learn more about telemetry processors here: https://go.microsoft.com/fwlink/?linkid=2151557");
239269
}
240270
if (logNames != null && matchType == ProcessorMatchType.regexp) {
241271
for (String logName : logNames) {
@@ -244,9 +274,12 @@ private void validateLogProcessorIncludeExclude() {
244274
}
245275
}
246276

247-
private void validateSpanProcessorIncludeExclude() {
277+
private void validateSpanProcessorIncludeExclude() throws FriendlyException {
248278
if (spanNames == null && attributes == null) {
249-
throw new ConfigurationException("User provided config has invalid include/exclude value with no spanNames or no attributes!!!");
279+
throw new FriendlyException("ApplicationInsights Java Agent failed to start.",
280+
"Telemetry processor configuration has invalid include/exclude value with no spanNames or no attributes!!!",
281+
"Please provide at least one of spanNames or attributes under the include/exclude section of processor configuration. " +
282+
"Learn more about telemetry processors here: https://go.microsoft.com/fwlink/?linkid=2151557");
250283
}
251284
if (spanNames != null && matchType == ProcessorMatchType.regexp) {
252285
for (String spanName : spanNames) {
@@ -269,17 +302,26 @@ public static class ProcessorAction {
269302
public String value;
270303
public String fromAttribute;
271304

272-
public void validate() {
305+
public void validate() throws FriendlyException {
273306

274307
if (this.key == null || this.key.isEmpty()) {
275-
throw new ConfigurationException("User provided config has invalid action with empty key!!!");
308+
throw new FriendlyException("ApplicationInsights Java Agent failed to start.",
309+
"Telemetry processor configuration has invalid action with empty key!!!",
310+
"Please provide a valid key with value under each action section of processor configuration. " +
311+
"Learn more about telemetry processors here: https://go.microsoft.com/fwlink/?linkid=2151557");
276312
}
277313
if (this.action == null) {
278-
throw new ConfigurationException("User provided config has invalid action with empty action!!!");
314+
throw new FriendlyException("ApplicationInsights Java Agent failed to start.",
315+
"Telemetry processor configuration has invalid config with empty action!!!",
316+
"Please provide a valid action. Telemetry processors cannot have empty or no actions. " +
317+
"Learn more about telemetry processors here: https://go.microsoft.com/fwlink/?linkid=2151557");
279318
}
280319
if (this.action == ProcessorActionType.insert || this.action == ProcessorActionType.update) {
281320
if(this.value == null && this.fromAttribute == null) {
282-
throw new ConfigurationException("User provided config has invalid action with empty value or empty fromAttribute!!!");
321+
throw new FriendlyException("ApplicationInsights Java Agent failed to start.",
322+
"Telemetry processor configuration has invalid action with empty value or empty fromAttribute!!!",
323+
"Please provide a valid action with value under each action section of processor configuration. " +
324+
"Learn more about telemetry processors here: https://go.microsoft.com/fwlink/?linkid=2151557");
283325
}
284326
}
285327
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.microsoft.applicationinsights.agent.bootstrap.customExceptions;
2+
3+
// This class is duplicated from com.microsoft.applicationinsights.customExceptions.FriendlyException since we are not able to import core packages to agent-bootstrap
4+
public class FriendlyException extends RuntimeException {
5+
public FriendlyException() {
6+
super();
7+
}
8+
9+
public FriendlyException(String banner, String message, String action, String note, Throwable cause) {
10+
super(populateFriendlyMessage(banner, message, action, note), cause);
11+
}
12+
13+
public FriendlyException(String banner, String message, String action, String note) {
14+
super(populateFriendlyMessage(banner, message, action, note));
15+
}
16+
17+
public FriendlyException(String banner, String message, String action) {
18+
super(populateFriendlyMessage(banner, message, action, ""));
19+
}
20+
21+
public FriendlyException(String banner, String action, Throwable cause) {
22+
super(populateFriendlyMessage(banner, "", action, ""), cause);
23+
}
24+
25+
private static String populateFriendlyMessage(String banner, String description, String action, String note) {
26+
StringBuilder messageBuilder = new StringBuilder();
27+
messageBuilder.append(System.lineSeparator());
28+
messageBuilder.append("*************************").append(System.lineSeparator());
29+
messageBuilder.append(banner).append(System.lineSeparator());
30+
messageBuilder.append("*************************").append(System.lineSeparator());
31+
messageBuilder.append(System.lineSeparator());
32+
messageBuilder.append("Description:").append(System.lineSeparator());
33+
messageBuilder.append(description).append(System.lineSeparator());
34+
messageBuilder.append(System.lineSeparator());
35+
messageBuilder.append("Action:").append(System.lineSeparator());
36+
messageBuilder.append(action).append(System.lineSeparator());
37+
if (!note.isEmpty()) {
38+
messageBuilder.append(System.lineSeparator());
39+
messageBuilder.append("Note:").append(System.lineSeparator());
40+
messageBuilder.append(note).append(System.lineSeparator());
41+
}
42+
return new String(messageBuilder);
43+
}
44+
}

0 commit comments

Comments
 (0)