From aef6fab2c3e5ab33711ca624c7a096f3cd86dc76 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Thu, 11 Mar 2021 16:48:03 -0800 Subject: [PATCH 1/2] Always write to log on startup failure --- .../internal/wasbootstrap/MainEntryPoint.java | 22 ++++++++++++++++--- .../configuration/ConfigurationBuilder.java | 4 +++- .../configuration/ConfigurationTest.java | 10 +++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/wasbootstrap/MainEntryPoint.java b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/wasbootstrap/MainEntryPoint.java index 6a2126531be..f9b8ece02ac 100644 --- a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/wasbootstrap/MainEntryPoint.java +++ b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/wasbootstrap/MainEntryPoint.java @@ -21,6 +21,7 @@ package com.microsoft.applicationinsights.agent.internal.wasbootstrap; import java.io.File; +import java.io.FileWriter; import java.lang.instrument.Instrumentation; import java.net.URL; import java.nio.file.Path; @@ -134,19 +135,34 @@ private static void logErrorMessage(Logger startupLogger, String message, boolea try { // IF the startupLogger failed to be initialized due to configuration syntax error, try initializing it here Path agentPath = new File(bootstrapURL.toURI()).toPath(); - startupLogger = configureLogging(new SelfDiagnostics(), agentPath); + SelfDiagnostics selfDiagnostics = new SelfDiagnostics(); + selfDiagnostics.file.path = ConfigurationBuilder.overlayWithEnvVar( + ConfigurationBuilder.APPLICATIONINSIGHTS_SELF_DIAGNOSTICS_FILE_PATH, selfDiagnostics.file.path); + startupLogger = configureLogging(selfDiagnostics, agentPath); if (isFriendlyException) { startupLogger.error(message); } else { startupLogger.error(message, t); } - } catch (Throwable e) { - // If the startupLogger still have some issues being initialized, just print the error stack trace + } catch (Throwable ignored) { + // this is a last resort in cases where the JVM doesn't have write permission to the directory where the agent lives + // and the user has not specified APPLICATIONINSIGHTS_SELF_DIAGNOSTICS_FILE_PATH + + // If the startupLogger still have some issues being initialized, print the error stack trace to stderr if (isFriendlyException) { System.err.println(message); } else { t.printStackTrace(); } + // and write to a temp file because some environments do not have (easy) access to stderr + String tmpDir = System.getProperty("java.io.tmpdir"); + File file = new File(tmpDir, "applicationinsights.log"); + try { + FileWriter out = new FileWriter(file); + out.write(message); + out.close(); + } catch (Throwable ignored2) { + } } } } diff --git a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/wasbootstrap/configuration/ConfigurationBuilder.java b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/wasbootstrap/configuration/ConfigurationBuilder.java index 6ac9787097f..e8254daec4f 100644 --- a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/wasbootstrap/configuration/ConfigurationBuilder.java +++ b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/wasbootstrap/configuration/ConfigurationBuilder.java @@ -64,6 +64,7 @@ public class ConfigurationBuilder { private static final String APPLICATIONINSIGHTS_INSTRUMENTATION_LOGGING_LEVEL = "APPLICATIONINSIGHTS_INSTRUMENTATION_LOGGING_LEVEL"; private static final String APPLICATIONINSIGHTS_SELF_DIAGNOSTICS_LEVEL = "APPLICATIONINSIGHTS_SELF_DIAGNOSTICS_LEVEL"; + public static final String APPLICATIONINSIGHTS_SELF_DIAGNOSTICS_FILE_PATH = "APPLICATIONINSIGHTS_SELF_DIAGNOSTICS_FILE_PATH"; private static final String APPLICATIONINSIGHTS_PREVIEW_OTEL_API_SUPPORT = "APPLICATIONINSIGHTS_PREVIEW_OTEL_API_SUPPORT"; @@ -223,6 +224,7 @@ public static void overlayEnvVars(Configuration config) throws IOException { config.sampling.percentage = overlayWithEnvVar(APPLICATIONINSIGHTS_SAMPLING_PERCENTAGE, config.sampling.percentage); config.selfDiagnostics.level = overlayWithEnvVar(APPLICATIONINSIGHTS_SELF_DIAGNOSTICS_LEVEL, config.selfDiagnostics.level); + config.selfDiagnostics.file.path = overlayWithEnvVar(APPLICATIONINSIGHTS_SELF_DIAGNOSTICS_FILE_PATH, config.selfDiagnostics.file.path); config.preview.openTelemetryApiSupport = overlayWithEnvVar(APPLICATIONINSIGHTS_PREVIEW_OTEL_API_SUPPORT, config.preview.openTelemetryApiSupport); @@ -255,7 +257,7 @@ private static String getWebsiteSiteNameEnvVar() { return value; } - static String overlayWithEnvVar(String name, String defaultValue) { + public static String overlayWithEnvVar(String name, String defaultValue) { String value = getEnvVar(name); return value != null ? value : defaultValue; } diff --git a/agent/agent-tooling/src/test/java/com/microsoft/applicationinsights/agent/internal/wasbootstrap/configuration/ConfigurationTest.java b/agent/agent-tooling/src/test/java/com/microsoft/applicationinsights/agent/internal/wasbootstrap/configuration/ConfigurationTest.java index a43349493e7..63a53d00541 100644 --- a/agent/agent-tooling/src/test/java/com/microsoft/applicationinsights/agent/internal/wasbootstrap/configuration/ConfigurationTest.java +++ b/agent/agent-tooling/src/test/java/com/microsoft/applicationinsights/agent/internal/wasbootstrap/configuration/ConfigurationTest.java @@ -337,6 +337,16 @@ public void shouldOverrideSelfDiagnosticsLevel() throws IOException { assertEquals("DEBUG", configuration.selfDiagnostics.level); } + @Test + public void shouldOverrideSelfDiagnosticsFilePath() throws IOException { + envVars.set("APPLICATIONINSIGHTS_SELF_DIAGNOSTICS_FILE_PATH", "/tmp/ai.log"); + + Configuration configuration = loadConfiguration(); + ConfigurationBuilder.overlayEnvVars(configuration); + + assertEquals("/tmp/ai.log", configuration.selfDiagnostics.file.path); + } + @Test public void shouldOverridePreviewOtelApiSupport() throws IOException { envVars.set("APPLICATIONINSIGHTS_PREVIEW_OTEL_API_SUPPORT", "true"); From 147d332cc2ee3d75ea4381231c812d1e39592e32 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Thu, 11 Mar 2021 17:55:01 -0800 Subject: [PATCH 2/2] Spotbugs --- .../agent/internal/wasbootstrap/MainEntryPoint.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/wasbootstrap/MainEntryPoint.java b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/wasbootstrap/MainEntryPoint.java index f9b8ece02ac..b3d9897745c 100644 --- a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/wasbootstrap/MainEntryPoint.java +++ b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/wasbootstrap/MainEntryPoint.java @@ -21,9 +21,12 @@ package com.microsoft.applicationinsights.agent.internal.wasbootstrap; import java.io.File; -import java.io.FileWriter; +import java.io.FileOutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; import java.lang.instrument.Instrumentation; import java.net.URL; +import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.util.Locale; @@ -158,7 +161,7 @@ private static void logErrorMessage(Logger startupLogger, String message, boolea String tmpDir = System.getProperty("java.io.tmpdir"); File file = new File(tmpDir, "applicationinsights.log"); try { - FileWriter out = new FileWriter(file); + Writer out = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8); out.write(message); out.close(); } catch (Throwable ignored2) {