diff --git a/agent/agent-bootstrap/src/main/java/com/microsoft/applicationinsights/agent/bootstrap/BytecodeUtil.java b/agent/agent-bootstrap/src/main/java/com/microsoft/applicationinsights/agent/bootstrap/BytecodeUtil.java index f0e707c1f93..f49c4272a99 100644 --- a/agent/agent-bootstrap/src/main/java/com/microsoft/applicationinsights/agent/bootstrap/BytecodeUtil.java +++ b/agent/agent-bootstrap/src/main/java/com/microsoft/applicationinsights/agent/bootstrap/BytecodeUtil.java @@ -25,7 +25,6 @@ import java.util.Collections; import java.util.Date; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; import io.opentelemetry.instrumentation.api.aisdk.MicrometerUtil; import io.opentelemetry.instrumentation.api.aisdk.MicrometerUtil.MicrometerUtilDelegate; @@ -46,57 +45,62 @@ public static void setDelegate(final BytecodeUtilDelegate delegate) { MicrometerUtil.setDelegate(new MicrometerUtilDelegate() { @Override public void trackMetric(String name, double value, Integer count, Double min, Double max, Map properties) { - delegate.trackMetric(name, value, count, min, max, null, properties, Collections.emptyMap()); + delegate.trackMetric(name, value, count, min, max, null, properties, Collections.emptyMap(), null); } }); } } - public static void trackEvent(String name, Map properties, Map tags, Map metrics) { + public static void trackEvent(String name, Map properties, Map tags, + Map metrics, String instrumentationKey) { if (delegate != null) { - delegate.trackEvent(name, properties, tags, metrics); + delegate.trackEvent(name, properties, tags, metrics, instrumentationKey); } } public static void trackMetric(String name, double value, Integer count, Double min, Double max, Double stdDev, - Map properties, Map tags) { + Map properties, Map tags, String instrumentationKey) { if (delegate != null) { - delegate.trackMetric(name, value, count, min, max, stdDev, properties, tags); + delegate.trackMetric(name, value, count, min, max, stdDev, properties, tags, instrumentationKey); } } public static void trackDependency(String name, String id, String resultCode, Long totalMillis, boolean success, String commandName, String type, String target, Map properties, - Map tags, Map metrics) { + Map tags, Map metrics, String instrumentationKey) { if (delegate != null) { delegate.trackDependency(name, id, resultCode, totalMillis, success, commandName, type, target, properties, - tags, metrics); + tags, metrics, instrumentationKey); } } public static void trackPageView(String name, URI uri, long totalMillis, Map properties, Map tags, - Map metrics) { + Map metrics, String instrumentationKey) { if (delegate != null) { - delegate.trackPageView(name, uri, totalMillis, properties, tags, metrics); + delegate.trackPageView(name, uri, totalMillis, properties, tags, metrics, instrumentationKey); } } - public static void trackTrace(String message, int severityLevel, Map properties, Map tags) { + public static void trackTrace(String message, int severityLevel, Map properties, Map tags, + String instrumentationKey) { if (delegate != null) { - delegate.trackTrace(message, severityLevel, properties, tags); + delegate.trackTrace(message, severityLevel, properties, tags, instrumentationKey); } } public static void trackRequest(String id, String name, URL url, Date timestamp, Long duration, String responseCode, boolean success, - String source, Map properties, Map tags, Map metrics) { + String source, Map properties, Map tags, Map metrics, + String instrumentationKey) { if (delegate != null) { - delegate.trackRequest(id, name, url, timestamp, duration, responseCode, success, source, properties, tags, metrics); + delegate.trackRequest(id, name, url, timestamp, duration, responseCode, success, source, properties, tags, + metrics, instrumentationKey); } } - public static void trackException(Exception exception, Map properties, Map tags, Map metrics) { + public static void trackException(Exception exception, Map properties, Map tags, + Map metrics, String instrumentationKey) { if (delegate != null) { - delegate.trackException(exception, properties, tags, metrics); + delegate.trackException(exception, properties, tags, metrics, instrumentationKey); } } @@ -120,27 +124,23 @@ public static long getTotalMilliseconds(long days, int hours, int minutes, int s + milliseconds; } - // basically the same as SDK MapUtil.copy() - public static void copy(Map source, Map target) { - if (target == null) { - throw new IllegalArgumentException("target must not be null"); - } - - if (source == null || source.isEmpty()) { + // originally from SDK MapUtil.copy() + public static void copy(Map source, Map target, String excludePrefix) { + if (source == null) { return; } - for (Map.Entry entry : source.entrySet()) { String key = entry.getKey(); if (key == null || key.isEmpty()) { continue; } - + if (excludePrefix != null && key.startsWith(excludePrefix)) { + continue; + } if (!target.containsKey(key)) { - if (target instanceof ConcurrentHashMap && entry.getValue() == null) { - continue; - } else { - target.put(key, entry.getValue()); + String value = entry.getValue(); + if (value != null) { + target.put(key, value); } } } @@ -148,25 +148,31 @@ public static void copy(Map source, Map target) public interface BytecodeUtilDelegate { - void trackEvent(String name, Map properties, Map tags, Map metrics); + void trackEvent(String name, Map properties, Map tags, Map metrics, + String instrumentationKey); void trackMetric(String name, double value, Integer count, Double min, Double max, - Double stdDev, Map properties, Map tags); + Double stdDev, Map properties, Map tags, + String instrumentationKey); void trackDependency(String name, String id, String resultCode, Long totalMillis, boolean success, String commandName, String type, String target, - Map properties, Map tags, Map metrics); + Map properties, Map tags, Map metrics, + String instrumentationKey); void trackPageView(String name, URI uri, long totalMillis, Map properties, Map tags, - Map metrics); + Map metrics, String instrumentationKey); - void trackTrace(String message, int severityLevel, Map properties, Map tags); + void trackTrace(String message, int severityLevel, Map properties, Map tags, + String instrumentationKey); void trackRequest(String id, String name, URL url, Date timestamp, Long duration, String responseCode, boolean success, - String source, Map properties, Map tags, Map metrics); + String source, Map properties, Map tags, Map metrics, + String instrumentationKey); // TODO also handle cases where ExceptionTelemetry parsedStack is used directly instead of indirectly through Exception - void trackException(Exception exception, Map properties, Map tags, Map metrics); + void trackException(Exception exception, Map properties, Map tags, + Map metrics, String instrumentationKey); void flush(); diff --git a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/AiComponentInstaller.java b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/AiComponentInstaller.java index 86ebd714870..9265fc7ed55 100644 --- a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/AiComponentInstaller.java +++ b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/AiComponentInstaller.java @@ -165,6 +165,7 @@ private static void start(Instrumentation instrumentation) { SystemInformation.INSTANCE.getProcessId(), formServiceProfilerConfig(config.preview.profiler), configuration.getRoleInstance(), + // TODO this will not work with Azure Spring Cloud updating connection string at runtime configuration.getInstrumentationKey(), telemetryClient, formApplicationInsightsUserAgent() diff --git a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/instrumentation/sdk/BytecodeUtilImpl.java b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/instrumentation/sdk/BytecodeUtilImpl.java index 0385107874a..263575399b8 100644 --- a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/instrumentation/sdk/BytecodeUtilImpl.java +++ b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/instrumentation/sdk/BytecodeUtilImpl.java @@ -58,7 +58,8 @@ public class BytecodeUtilImpl implements BytecodeUtilDelegate { private static final AtomicBoolean alreadyLoggedError = new AtomicBoolean(); @Override - public void trackEvent(String name, Map properties, Map tags, Map metrics) { + public void trackEvent(String name, Map properties, Map tags, + Map metrics, String instrumentationKey) { if (Strings.isNullOrEmpty(name)) { return; @@ -67,14 +68,15 @@ public void trackEvent(String name, Map properties, Map properties, Map tags) { + public void trackMetric(String name, double value, Integer count, Double min, Double max, Double stdDev, + Map properties, Map tags, String instrumentationKey) { if (Strings.isNullOrEmpty(name)) { return; @@ -88,6 +90,7 @@ public void trackMetric(String name, double value, Integer count, Double min, Do telemetry.setStandardDeviation(stdDev); telemetry.getProperties().putAll(properties); telemetry.getContext().getTags().putAll(tags); + telemetry.getContext().setInstrumentationKey(instrumentationKey); track(telemetry); } @@ -95,7 +98,8 @@ public void trackMetric(String name, double value, Integer count, Double min, Do @Override public void trackDependency(String name, String id, String resultCode, @Nullable Long totalMillis, boolean success, String commandName, String type, String target, - Map properties, Map tags, Map metrics) { + Map properties, Map tags, Map metrics, + String instrumentationKey) { if (Strings.isNullOrEmpty(name)) { return; @@ -114,13 +118,14 @@ public void trackDependency(String name, String id, String resultCode, @Nullable telemetry.getProperties().putAll(properties); telemetry.getContext().getTags().putAll(tags); telemetry.getMetrics().putAll(metrics); + telemetry.getContext().setInstrumentationKey(instrumentationKey); track(telemetry); } @Override public void trackPageView(String name, URI uri, long totalMillis, Map properties, - Map tags, Map metrics) { + Map tags, Map metrics, String instrumentationKey) { if (Strings.isNullOrEmpty(name)) { return; @@ -132,12 +137,14 @@ public void trackPageView(String name, URI uri, long totalMillis, Map properties, Map tags) { + public void trackTrace(String message, int severityLevel, Map properties, Map tags, + String instrumentationKey) { if (Strings.isNullOrEmpty(message)) { return; } @@ -149,13 +156,15 @@ public void trackTrace(String message, int severityLevel, Map pr } telemetry.getProperties().putAll(properties); telemetry.getContext().getTags().putAll(tags); + telemetry.getContext().setInstrumentationKey(instrumentationKey); track(telemetry); } @Override public void trackRequest(String id, String name, URL url, Date timestamp, @Nullable Long duration, String responseCode, boolean success, - String source, Map properties, Map tags, Map metrics) { + String source, Map properties, Map tags, Map metrics, + String instrumentationKey) { if (Strings.isNullOrEmpty(name)) { return; } @@ -176,13 +185,14 @@ public void trackRequest(String id, String name, URL url, Date timestamp, @Nulla telemetry.getProperties().putAll(properties); telemetry.getContext().getTags().putAll(tags); telemetry.getMetrics().putAll(metrics); + telemetry.getContext().setInstrumentationKey(instrumentationKey); track(telemetry); } @Override public void trackException(Exception exception, Map properties, Map tags, - Map metrics) { + Map metrics, String instrumentationKey) { if (exception == null) { return; } @@ -193,6 +203,7 @@ public void trackException(Exception exception, Map properties, telemetry.getProperties().putAll(properties); telemetry.getContext().getTags().putAll(tags); telemetry.getMetrics().putAll(metrics); + telemetry.getContext().setInstrumentationKey(instrumentationKey); track(telemetry); } diff --git a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/instrumentation/sdk/TelemetryClientClassFileTransformer.java b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/instrumentation/sdk/TelemetryClientClassFileTransformer.java index 65a562a72a7..a3c67e2d4f5 100644 --- a/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/instrumentation/sdk/TelemetryClientClassFileTransformer.java +++ b/agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/instrumentation/sdk/TelemetryClientClassFileTransformer.java @@ -211,7 +211,8 @@ private void overwriteTrackMethod(MethodVisitor mv) { mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEINTERFACE, unshadedPrefix + "/telemetry/Telemetry", "getContext", "()L" + unshadedPrefix + "/telemetry/TelemetryContext;", true); mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/TelemetryContext", "getTags", "()Ljava/util/concurrent/ConcurrentMap;", false); - mv.visitMethodInsn(INVOKESTATIC, BYTECODE_UTIL_INTERNAL_NAME, "copy", "(Ljava/util/Map;Ljava/util/Map;)V", false); + mv.visitLdcInsn("ai.cloud."); + mv.visitMethodInsn(INVOKESTATIC, BYTECODE_UTIL_INTERNAL_NAME, "copy", "(Ljava/util/Map;Ljava/util/Map;Ljava/lang/String;)V", false); Label label8 = new Label(); mv.visitLabel(label8); mv.visitVarInsn(ALOAD, 0); @@ -220,7 +221,8 @@ private void overwriteTrackMethod(MethodVisitor mv) { mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEINTERFACE, unshadedPrefix + "/telemetry/Telemetry", "getContext", "()L" + unshadedPrefix + "/telemetry/TelemetryContext;", true); mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/TelemetryContext", "getProperties", "()Ljava/util/concurrent/ConcurrentMap;", false); - mv.visitMethodInsn(INVOKESTATIC, BYTECODE_UTIL_INTERNAL_NAME, "copy", "(Ljava/util/Map;Ljava/util/Map;)V", false); + mv.visitInsn(ACONST_NULL); + mv.visitMethodInsn(INVOKESTATIC, BYTECODE_UTIL_INTERNAL_NAME, "copy", "(Ljava/util/Map;Ljava/util/Map;Ljava/lang/String;)V", false); mv.visitLabel(label0); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(INSTANCEOF, unshadedPrefix + "/telemetry/EventTelemetry"); @@ -231,8 +233,7 @@ private void overwriteTrackMethod(MethodVisitor mv) { mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, unshadedPrefix + "/telemetry/EventTelemetry"); - mv.visitMethodInsn(INVOKESPECIAL, unshadedPrefix + "/TelemetryClient", "agent$trackEventTelemetry", - "(L" + unshadedPrefix + "/telemetry/EventTelemetry;)V", false); + mv.visitMethodInsn(INVOKESPECIAL, unshadedPrefix + "/TelemetryClient", "agent$trackEventTelemetry", "(L" + unshadedPrefix + "/telemetry/EventTelemetry;)V", false); mv.visitLabel(label9); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitVarInsn(ALOAD, 1); @@ -244,8 +245,7 @@ private void overwriteTrackMethod(MethodVisitor mv) { mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, unshadedPrefix + "/telemetry/MetricTelemetry"); - mv.visitMethodInsn(INVOKESPECIAL, unshadedPrefix + "/TelemetryClient", "agent$trackMetricTelemetry", - "(L" + unshadedPrefix + "/telemetry/MetricTelemetry;)V", false); + mv.visitMethodInsn(INVOKESPECIAL, unshadedPrefix + "/TelemetryClient", "agent$trackMetricTelemetry", "(L" + unshadedPrefix + "/telemetry/MetricTelemetry;)V", false); mv.visitLabel(label11); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitVarInsn(ALOAD, 1); @@ -257,8 +257,7 @@ private void overwriteTrackMethod(MethodVisitor mv) { mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, unshadedPrefix + "/telemetry/RemoteDependencyTelemetry"); - mv.visitMethodInsn(INVOKESPECIAL, unshadedPrefix + "/TelemetryClient", "agent$trackRemoteDependencyTelemetry", - "(L" + unshadedPrefix + "/telemetry/RemoteDependencyTelemetry;)V", false); + mv.visitMethodInsn(INVOKESPECIAL, unshadedPrefix + "/TelemetryClient", "agent$trackRemoteDependencyTelemetry", "(L" + unshadedPrefix + "/telemetry/RemoteDependencyTelemetry;)V", false); mv.visitLabel(label13); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitVarInsn(ALOAD, 1); @@ -270,8 +269,7 @@ private void overwriteTrackMethod(MethodVisitor mv) { mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, unshadedPrefix + "/telemetry/PageViewTelemetry"); - mv.visitMethodInsn(INVOKESPECIAL, unshadedPrefix + "/TelemetryClient", "agent$trackPageViewTelemetry", - "(L" + unshadedPrefix + "/telemetry/PageViewTelemetry;)V", false); + mv.visitMethodInsn(INVOKESPECIAL, unshadedPrefix + "/TelemetryClient", "agent$trackPageViewTelemetry", "(L" + unshadedPrefix + "/telemetry/PageViewTelemetry;)V", false); mv.visitLabel(label15); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitVarInsn(ALOAD, 1); @@ -283,8 +281,7 @@ private void overwriteTrackMethod(MethodVisitor mv) { mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, unshadedPrefix + "/telemetry/TraceTelemetry"); - mv.visitMethodInsn(INVOKESPECIAL, unshadedPrefix + "/TelemetryClient", "agent$trackTraceTelemetry", - "(L" + unshadedPrefix + "/telemetry/TraceTelemetry;)V", false); + mv.visitMethodInsn(INVOKESPECIAL, unshadedPrefix + "/TelemetryClient", "agent$trackTraceTelemetry", "(L" + unshadedPrefix + "/telemetry/TraceTelemetry;)V", false); mv.visitLabel(label17); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitVarInsn(ALOAD, 1); @@ -296,8 +293,7 @@ private void overwriteTrackMethod(MethodVisitor mv) { mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, unshadedPrefix + "/telemetry/RequestTelemetry"); - mv.visitMethodInsn(INVOKESPECIAL, unshadedPrefix + "/TelemetryClient", "agent$trackRequestTelemetry", - "(L" + unshadedPrefix + "/telemetry/RequestTelemetry;)V", false); + mv.visitMethodInsn(INVOKESPECIAL, unshadedPrefix + "/TelemetryClient", "agent$trackRequestTelemetry", "(L" + unshadedPrefix + "/telemetry/RequestTelemetry;)V", false); mv.visitLabel(label19); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitVarInsn(ALOAD, 1); @@ -308,8 +304,7 @@ private void overwriteTrackMethod(MethodVisitor mv) { mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, unshadedPrefix + "/telemetry/ExceptionTelemetry"); - mv.visitMethodInsn(INVOKESPECIAL, unshadedPrefix + "/TelemetryClient", "agent$trackExceptionTelemetry", - "(L" + unshadedPrefix + "/telemetry/ExceptionTelemetry;)V", false); + mv.visitMethodInsn(INVOKESPECIAL, unshadedPrefix + "/TelemetryClient", "agent$trackExceptionTelemetry", "(L" + unshadedPrefix + "/telemetry/ExceptionTelemetry;)V", false); mv.visitLabel(label1); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); Label label22 = new Label(); @@ -320,8 +315,7 @@ private void overwriteTrackMethod(MethodVisitor mv) { Label label23 = new Label(); mv.visitLabel(label23); mv.visitVarInsn(ALOAD, 2); - mv.visitMethodInsn(INVOKESTATIC, BYTECODE_UTIL_INTERNAL_NAME, "logErrorOnce", "(Ljava/lang/Throwable;)V", - false); + mv.visitMethodInsn(INVOKESTATIC, BYTECODE_UTIL_INTERNAL_NAME, "logErrorOnce", "(Ljava/lang/Throwable;)V", false); mv.visitLabel(label22); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitInsn(RETURN); @@ -374,25 +368,28 @@ private void writeAgentTrackEventTelemetryMethod() { Label label0 = new Label(); mv.visitLabel(label0); mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/EventTelemetry", "getName", - "()Ljava/lang/String;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/EventTelemetry", "getName", "()Ljava/lang/String;", false); mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/EventTelemetry", "getProperties", - "()Ljava/util/Map;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/EventTelemetry", "getProperties", "()Ljava/util/Map;", false); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/EventTelemetry", "getContext", "()L" + unshadedPrefix + "/telemetry/TelemetryContext;", false); mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/TelemetryContext", "getTags", "()Ljava/util/concurrent/ConcurrentMap;", false); mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/EventTelemetry", "getMetrics", - "()Ljava/util/concurrent/ConcurrentMap;", false); - mv.visitMethodInsn(INVOKESTATIC, BYTECODE_UTIL_INTERNAL_NAME, "trackEvent", - "(Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;)V", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/EventTelemetry", "getMetrics", "()Ljava/util/concurrent/ConcurrentMap;", false); + mv.visitVarInsn(ALOAD, 1); Label label1 = new Label(); mv.visitLabel(label1); - mv.visitInsn(RETURN); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/EventTelemetry", "getContext", "()L" + unshadedPrefix + "/telemetry/TelemetryContext;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/TelemetryContext", "getInstrumentationKey", "()Ljava/lang/String;", false); Label label2 = new Label(); mv.visitLabel(label2); - mv.visitMaxs(4, 2); + mv.visitMethodInsn(INVOKESTATIC, BYTECODE_UTIL_INTERNAL_NAME, "trackEvent", "(Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/lang/String;)V", false); + Label label3 = new Label(); + mv.visitLabel(label3); + mv.visitInsn(RETURN); + Label label4 = new Label(); + mv.visitLabel(label4); + mv.visitMaxs(5, 2); mv.visitEnd(); } @@ -403,130 +400,122 @@ private void writeAgentTrackMetricTelemetryMethod() { Label label0 = new Label(); mv.visitLabel(label0); mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/MetricTelemetry", "getName", - "()Ljava/lang/String;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/MetricTelemetry", "getName", "()Ljava/lang/String;", false); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/MetricTelemetry", "getValue", "()D", false); mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/MetricTelemetry", "getCount", - "()Ljava/lang/Integer;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/MetricTelemetry", "getCount", "()Ljava/lang/Integer;", false); mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/MetricTelemetry", "getMin", - "()Ljava/lang/Double;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/MetricTelemetry", "getMin", "()Ljava/lang/Double;", false); mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/MetricTelemetry", "getMax", - "()Ljava/lang/Double;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/MetricTelemetry", "getMax", "()Ljava/lang/Double;", false); mv.visitVarInsn(ALOAD, 1); Label label1 = new Label(); mv.visitLabel(label1); - mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/MetricTelemetry", "getStandardDeviation", - "()Ljava/lang/Double;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/MetricTelemetry", "getStandardDeviation", "()Ljava/lang/Double;", false); mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/MetricTelemetry", "getProperties", - "()Ljava/util/Map;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/MetricTelemetry", "getProperties", "()Ljava/util/Map;", false); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/MetricTelemetry", "getContext", "()L" + unshadedPrefix + "/telemetry/TelemetryContext;", false); mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/TelemetryContext", "getTags", "()Ljava/util/concurrent/ConcurrentMap;", false); + mv.visitVarInsn(ALOAD, 1); Label label2 = new Label(); mv.visitLabel(label2); - mv.visitMethodInsn(INVOKESTATIC, BYTECODE_UTIL_INTERNAL_NAME, "trackMetric", - "(Ljava/lang/String;DLjava/lang/Integer;Ljava/lang/Double;Ljava/lang/Double;Ljava/lang/Double;Ljava/util/Map;Ljava/util/Map;)V", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/MetricTelemetry", "getContext", "()L" + unshadedPrefix + "/telemetry/TelemetryContext;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/TelemetryContext", "getInstrumentationKey", "()Ljava/lang/String;", false); Label label3 = new Label(); mv.visitLabel(label3); - mv.visitInsn(RETURN); + mv.visitMethodInsn(INVOKESTATIC, BYTECODE_UTIL_INTERNAL_NAME, "trackMetric", "(Ljava/lang/String;DLjava/lang/Integer;Ljava/lang/Double;Ljava/lang/Double;Ljava/lang/Double;Ljava/util/Map;Ljava/util/Map;Ljava/lang/String;)V", false); Label label4 = new Label(); mv.visitLabel(label4); - mv.visitMaxs(9, 2); + mv.visitInsn(RETURN); + Label label5 = new Label(); + mv.visitLabel(label5); + mv.visitMaxs(10, 2); mv.visitEnd(); } private void writeAgentTrackRemoteDependencyTelemetryMethod() { - MethodVisitor mv = cw.visitMethod(ACC_PRIVATE, "agent$trackRemoteDependencyTelemetry", - "(L" + unshadedPrefix + "/telemetry/RemoteDependencyTelemetry;)V", null, null); + MethodVisitor mv = cw.visitMethod(ACC_PRIVATE, "agent$trackRemoteDependencyTelemetry", "(L" + unshadedPrefix + "/telemetry/RemoteDependencyTelemetry;)V", null, null); mv.visitCode(); Label label0 = new Label(); mv.visitLabel(label0); mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/RemoteDependencyTelemetry", "getName", - "()Ljava/lang/String;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/RemoteDependencyTelemetry", "getName", "()Ljava/lang/String;", false); mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/RemoteDependencyTelemetry", "getId", - "()Ljava/lang/String;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/RemoteDependencyTelemetry", "getId", "()Ljava/lang/String;", false); mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/RemoteDependencyTelemetry", - "getResultCode", "()Ljava/lang/String;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/RemoteDependencyTelemetry", "getResultCode", "()Ljava/lang/String;", false); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/RemoteDependencyTelemetry", "getDuration", - "()L" + unshadedPrefix + "/telemetry/Duration;", false); - mv.visitMethodInsn(INVOKESPECIAL, unshadedPrefix + "/TelemetryClient", "agent$toMillis", - "(L" + unshadedPrefix + "/telemetry/Duration;)Ljava/lang/Long;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/RemoteDependencyTelemetry", "getDuration", "()L" + unshadedPrefix + "/telemetry/Duration;", false); + mv.visitMethodInsn(INVOKESPECIAL, unshadedPrefix + "/TelemetryClient", "agent$toMillis", "(L" + unshadedPrefix + "/telemetry/Duration;)Ljava/lang/Long;", false); mv.visitVarInsn(ALOAD, 1); Label label1 = new Label(); mv.visitLabel(label1); - mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/RemoteDependencyTelemetry", "getSuccess", - "()Z", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/RemoteDependencyTelemetry", "getSuccess", "()Z", false); mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/RemoteDependencyTelemetry", "getCommandName", - "()Ljava/lang/String;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/RemoteDependencyTelemetry", "getCommandName", "()Ljava/lang/String;", false); mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/RemoteDependencyTelemetry", "getType", - "()Ljava/lang/String;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/RemoteDependencyTelemetry", "getType", "()Ljava/lang/String;", false); mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/RemoteDependencyTelemetry", "getTarget", - "()Ljava/lang/String;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/RemoteDependencyTelemetry", "getTarget", "()Ljava/lang/String;", false); mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/RemoteDependencyTelemetry", "getProperties", - "()Ljava/util/Map;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/RemoteDependencyTelemetry", "getProperties", "()Ljava/util/Map;", false); mv.visitVarInsn(ALOAD, 1); + Label label2 = new Label(); + mv.visitLabel(label2); mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/RemoteDependencyTelemetry", "getContext", "()L" + unshadedPrefix + "/telemetry/TelemetryContext;", false); mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/TelemetryContext", "getTags", "()Ljava/util/concurrent/ConcurrentMap;", false); mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/RemoteDependencyTelemetry", "getMetrics", - "()Ljava/util/Map;", false); - Label label2 = new Label(); - mv.visitLabel(label2); - mv.visitMethodInsn(INVOKESTATIC, BYTECODE_UTIL_INTERNAL_NAME, "trackDependency", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;)V", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/RemoteDependencyTelemetry", "getMetrics", "()Ljava/util/Map;", false); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/RemoteDependencyTelemetry", "getContext", "()L" + unshadedPrefix + "/telemetry/TelemetryContext;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/TelemetryContext", "getInstrumentationKey", "()Ljava/lang/String;", false); Label label3 = new Label(); mv.visitLabel(label3); - mv.visitInsn(RETURN); + mv.visitMethodInsn(INVOKESTATIC, BYTECODE_UTIL_INTERNAL_NAME, "trackDependency", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/lang/String;)V", false); Label label4 = new Label(); mv.visitLabel(label4); - mv.visitMaxs(11, 2); + mv.visitInsn(RETURN); + Label label5 = new Label(); + mv.visitLabel(label5); + mv.visitMaxs(12, 2); mv.visitEnd(); } private void writeAgentTrackPageViewTelemetryMethod() { - MethodVisitor mv = cw.visitMethod(ACC_PRIVATE, "agent$trackPageViewTelemetry", - "(L" + unshadedPrefix + "/telemetry/PageViewTelemetry;)V", null, null); + MethodVisitor mv = cw.visitMethod(ACC_PRIVATE, "agent$trackPageViewTelemetry", "(L" + unshadedPrefix + "/telemetry/PageViewTelemetry;)V", null, null); mv.visitCode(); Label label0 = new Label(); mv.visitLabel(label0); mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/PageViewTelemetry", "getName", - "()Ljava/lang/String;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/PageViewTelemetry", "getName", "()Ljava/lang/String;", false); mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/PageViewTelemetry", "getUri", - "()Ljava/net/URI;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/PageViewTelemetry", "getUri", "()Ljava/net/URI;", false); mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/PageViewTelemetry", "getDuration", "()J", - false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/PageViewTelemetry", "getDuration", "()J", false); mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/PageViewTelemetry", "getProperties", - "()Ljava/util/Map;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/PageViewTelemetry", "getProperties", "()Ljava/util/Map;", false); mv.visitVarInsn(ALOAD, 1); + Label label1 = new Label(); + mv.visitLabel(label1); mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/PageViewTelemetry", "getContext", "()L" + unshadedPrefix + "/telemetry/TelemetryContext;", false); mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/TelemetryContext", "getTags", "()Ljava/util/concurrent/ConcurrentMap;", false); mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/PageViewTelemetry", "getMetrics", - "()Ljava/util/concurrent/ConcurrentMap;", false); - mv.visitMethodInsn(INVOKESTATIC, BYTECODE_UTIL_INTERNAL_NAME, "trackPageView", "(Ljava/lang/String;Ljava/net/URI;JLjava/util/Map;Ljava/util/Map;Ljava/util/Map;)V", false); - Label label1 = new Label(); - mv.visitLabel(label1); - mv.visitInsn(RETURN); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/PageViewTelemetry", "getMetrics", "()Ljava/util/concurrent/ConcurrentMap;", false); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/PageViewTelemetry", "getContext", "()L" + unshadedPrefix + "/telemetry/TelemetryContext;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/TelemetryContext", "getInstrumentationKey", "()Ljava/lang/String;", false); Label label2 = new Label(); mv.visitLabel(label2); - mv.visitMaxs(7, 2); + mv.visitMethodInsn(INVOKESTATIC, BYTECODE_UTIL_INTERNAL_NAME, "trackPageView", "(Ljava/lang/String;Ljava/net/URI;JLjava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/lang/String;)V", false); + Label label3 = new Label(); + mv.visitLabel(label3); + mv.visitInsn(RETURN); + Label label4 = new Label(); + mv.visitLabel(label4); + mv.visitMaxs(8, 2); mv.visitEnd(); } @@ -563,13 +552,20 @@ private void writeAgentTrackTraceTelemetryMethod() { mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/TraceTelemetry", "getContext", "()L" + unshadedPrefix + "/telemetry/TelemetryContext;", false); mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/TelemetryContext", "getTags", "()Ljava/util/concurrent/ConcurrentMap;", false); - mv.visitMethodInsn(INVOKESTATIC, BYTECODE_UTIL_INTERNAL_NAME, "trackTrace", "(Ljava/lang/String;ILjava/util/Map;Ljava/util/Map;)V", false); + mv.visitVarInsn(ALOAD, 1); Label label5 = new Label(); mv.visitLabel(label5); - mv.visitInsn(RETURN); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/TraceTelemetry", "getContext", "()L" + unshadedPrefix + "/telemetry/TelemetryContext;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/TelemetryContext", "getInstrumentationKey", "()Ljava/lang/String;", false); Label label6 = new Label(); mv.visitLabel(label6); - mv.visitMaxs(4, 4); + mv.visitMethodInsn(INVOKESTATIC, BYTECODE_UTIL_INTERNAL_NAME, "trackTrace", "(Ljava/lang/String;ILjava/util/Map;Ljava/util/Map;Ljava/lang/String;)V", false); + Label label7 = new Label(); + mv.visitLabel(label7); + mv.visitInsn(RETURN); + Label label8 = new Label(); + mv.visitLabel(label8); + mv.visitMaxs(5, 4); mv.visitEnd(); } @@ -607,26 +603,31 @@ private void writeAgentTrackRequestTelemetryMethod() { mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/RequestTelemetry", "getContext", "()L" + unshadedPrefix + "/telemetry/TelemetryContext;", false); mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/TelemetryContext", "getTags", "()Ljava/util/concurrent/ConcurrentMap;", false); mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/RequestTelemetry", "getMetrics", "()Ljava/util/concurrent/ConcurrentMap;", false); Label label4 = new Label(); mv.visitLabel(label4); - mv.visitMethodInsn(INVOKESTATIC, BYTECODE_UTIL_INTERNAL_NAME, "trackRequest", "(Ljava/lang/String;Ljava/lang/String;Ljava/net/URL;Ljava/util/Date;Ljava/lang/Long;Ljava/lang/String;ZLjava/lang/String;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;)V", false); - mv.visitLabel(label1); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/RequestTelemetry", "getMetrics", "()Ljava/util/concurrent/ConcurrentMap;", false); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/RequestTelemetry", "getContext", "()L" + unshadedPrefix + "/telemetry/TelemetryContext;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/TelemetryContext", "getInstrumentationKey", "()Ljava/lang/String;", false); Label label5 = new Label(); - mv.visitJumpInsn(GOTO, label5); + mv.visitLabel(label5); + mv.visitMethodInsn(INVOKESTATIC, BYTECODE_UTIL_INTERNAL_NAME, "trackRequest", "(Ljava/lang/String;Ljava/lang/String;Ljava/net/URL;Ljava/util/Date;Ljava/lang/Long;Ljava/lang/String;ZLjava/lang/String;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/lang/String;)V", false); + mv.visitLabel(label1); + Label label6 = new Label(); + mv.visitJumpInsn(GOTO, label6); mv.visitLabel(label2); mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/net/MalformedURLException"}); mv.visitVarInsn(ASTORE, 2); - Label label6 = new Label(); - mv.visitLabel(label6); + Label label7 = new Label(); + mv.visitLabel(label7); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKESTATIC, BYTECODE_UTIL_INTERNAL_NAME, "logErrorOnce", "(Ljava/lang/Throwable;)V", false); - mv.visitLabel(label5); + mv.visitLabel(label6); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitInsn(RETURN); - Label label7 = new Label(); - mv.visitLabel(label7); - mv.visitMaxs(11, 3); + Label label8 = new Label(); + mv.visitLabel(label8); + mv.visitMaxs(12, 3); mv.visitEnd(); } @@ -644,13 +645,20 @@ private void writeAgentTrackExceptionTelemetryMethod() { mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/TelemetryContext", "getTags", "()Ljava/util/concurrent/ConcurrentMap;", false); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/ExceptionTelemetry", "getMetrics", "()Ljava/util/concurrent/ConcurrentMap;", false); - mv.visitMethodInsn(INVOKESTATIC, BYTECODE_UTIL_INTERNAL_NAME, "trackException", "(Ljava/lang/Exception;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;)V", false); + mv.visitVarInsn(ALOAD, 1); Label label1 = new Label(); mv.visitLabel(label1); - mv.visitInsn(RETURN); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/ExceptionTelemetry", "getContext", "()L" + unshadedPrefix + "/telemetry/TelemetryContext;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, unshadedPrefix + "/telemetry/TelemetryContext", "getInstrumentationKey", "()Ljava/lang/String;", false); Label label2 = new Label(); mv.visitLabel(label2); - mv.visitMaxs(4, 2); + mv.visitMethodInsn(INVOKESTATIC, BYTECODE_UTIL_INTERNAL_NAME, "trackException", "(Ljava/lang/Exception;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/lang/String;)V", false); + Label label3 = new Label(); + mv.visitLabel(label3); + mv.visitInsn(RETURN); + Label label4 = new Label(); + mv.visitLabel(label4); + mv.visitMaxs(5, 2); mv.visitEnd(); } @@ -751,9 +759,8 @@ public void track(Telemetry telemetry) { // while still allowing them to be overridden at Telemetry level // rationale: if setting something programmatically, then can un-set it programmatically - - BytecodeUtil.copy(getContext().getTags(), telemetry.getContext().getTags()); - BytecodeUtil.copy(getContext().getProperties(), telemetry.getContext().getProperties()); + BytecodeUtil.copy(getContext().getTags(), telemetry.getContext().getTags(), "ai.cloud."); + BytecodeUtil.copy(getContext().getProperties(), telemetry.getContext().getProperties(), null); // don't run telemetry initializers or telemetry processors // (otherwise confusing message to have different rules for 2.x SDK interop telemetry) @@ -786,40 +793,47 @@ public void track(Telemetry telemetry) { } private void agent$trackEventTelemetry(EventTelemetry t) { - BytecodeUtil.trackEvent(t.getName(), t.getProperties(), t.getContext().getTags(), t.getMetrics()); + BytecodeUtil.trackEvent(t.getName(), t.getProperties(), t.getContext().getTags(), t.getMetrics(), + t.getContext().getInstrumentationKey()); } private void agent$trackMetricTelemetry(MetricTelemetry t) { BytecodeUtil.trackMetric(t.getName(), t.getValue(), t.getCount(), t.getMin(), t.getMax(), - t.getStandardDeviation(), t.getProperties(), t.getContext().getTags()); + t.getStandardDeviation(), t.getProperties(), t.getContext().getTags(), + t.getContext().getInstrumentationKey()); } private void agent$trackRemoteDependencyTelemetry(RemoteDependencyTelemetry t) { BytecodeUtil.trackDependency(t.getName(), t.getId(), t.getResultCode(), agent$toMillis(t.getDuration()), - t.getSuccess(), t.getCommandName(), t.getType(), t.getTarget(), t.getProperties(), t.getContext().getTags(), t.getMetrics()); + t.getSuccess(), t.getCommandName(), t.getType(), t.getTarget(), t.getProperties(), + t.getContext().getTags(), t.getMetrics(), t.getContext().getInstrumentationKey()); } private void agent$trackPageViewTelemetry(PageViewTelemetry t) { - BytecodeUtil.trackPageView(t.getName(), t.getUri(), t.getDuration(), t.getProperties(), t.getContext().getTags(), t.getMetrics()); + BytecodeUtil.trackPageView(t.getName(), t.getUri(), t.getDuration(), t.getProperties(), + t.getContext().getTags(), t.getMetrics(), t.getContext().getInstrumentationKey()); } private void agent$trackTraceTelemetry(TraceTelemetry t) { SeverityLevel level = t.getSeverityLevel(); int severityLevel = level != null ? level.getValue() : -1; - BytecodeUtil.trackTrace(t.getMessage(), severityLevel, t.getProperties(), t.getContext().getTags()); + BytecodeUtil.trackTrace(t.getMessage(), severityLevel, t.getProperties(), t.getContext().getTags(), + t.getContext().getInstrumentationKey()); } private void agent$trackRequestTelemetry(RequestTelemetry t) { try { BytecodeUtil.trackRequest(t.getId(), t.getName(), t.getUrl(), t.getTimestamp(), agent$toMillis(t.getDuration()), - t.getResponseCode(), t.isSuccess(), t.getSource(), t.getProperties(), t.getContext().getTags(), t.getMetrics()); + t.getResponseCode(), t.isSuccess(), t.getSource(), t.getProperties(), t.getContext().getTags(), + t.getMetrics(), t.getContext().getInstrumentationKey()); } catch (MalformedURLException e) { BytecodeUtil.logErrorOnce(e); } } private void agent$trackExceptionTelemetry(ExceptionTelemetry t) { - BytecodeUtil.trackException(t.getException(), t.getProperties(), t.getContext().getTags(), t.getMetrics()); + BytecodeUtil.trackException(t.getException(), t.getProperties(), t.getContext().getTags(), t.getMetrics(), + t.getContext().getInstrumentationKey()); } @Nullable diff --git a/agent/exporter/src/main/java/com/microsoft/applicationinsights/agent/Exporter.java b/agent/exporter/src/main/java/com/microsoft/applicationinsights/agent/Exporter.java index c0b0b974ce9..b7082373f09 100644 --- a/agent/exporter/src/main/java/com/microsoft/applicationinsights/agent/Exporter.java +++ b/agent/exporter/src/main/java/com/microsoft/applicationinsights/agent/Exporter.java @@ -722,6 +722,22 @@ private static void setExtraAttributes(Telemetry telemetry, Attributes attribute telemetry.getContext().getUser().setUserAgent((String) value); return; } + if (stringKey.equals("ai.preview.instrumentation_key") && value instanceof String) { + telemetry.getContext().setInstrumentationKey((String) value); + return; + } + if (stringKey.equals("ai.preview.service_name") && value instanceof String) { + telemetry.getContext().getCloud().setRole((String) value); + return; + } + if (stringKey.equals("ai.preview.service_instance_id") && value instanceof String) { + telemetry.getContext().getCloud().setRoleInstance((String) value); + return; + } + if (stringKey.equals("ai.preview.service_version") && value instanceof String) { + telemetry.getContext().getComponent().setVersion((String) value); + return; + } int index = stringKey.indexOf("."); String prefix = index == -1 ? stringKey : stringKey.substring(0, index); if (STANDARD_ATTRIBUTE_PREFIXES.contains(prefix)) { diff --git a/core/src/main/java/com/microsoft/applicationinsights/TelemetryClient.java b/core/src/main/java/com/microsoft/applicationinsights/TelemetryClient.java index c0e1d959ccd..b9dcc6b6c82 100644 --- a/core/src/main/java/com/microsoft/applicationinsights/TelemetryClient.java +++ b/core/src/main/java/com/microsoft/applicationinsights/TelemetryClient.java @@ -22,6 +22,7 @@ package com.microsoft.applicationinsights; import java.util.Date; +import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; @@ -29,6 +30,7 @@ import com.microsoft.applicationinsights.channel.TelemetryChannel; import com.microsoft.applicationinsights.common.CommonUtils; import com.microsoft.applicationinsights.extensibility.ContextInitializer; +import com.microsoft.applicationinsights.extensibility.context.ContextTagKeys; import com.microsoft.applicationinsights.extensibility.context.InternalContext; import com.microsoft.applicationinsights.extensibility.initializer.TelemetryObservers; import com.microsoft.applicationinsights.internal.quickpulse.QuickPulseDataCollector; @@ -122,24 +124,28 @@ public void track(Telemetry telemetry) { telemetry.setTimestamp(new Date()); } - // TODO does this work with auto-updating Azure Spring Cloud connection string, since existing is not null? - if (Strings.isNullOrEmpty(getContext().getInstrumentationKey())) { - getContext().setInstrumentationKey(configuration.getInstrumentationKey()); - } - TelemetryContext context = telemetry.getContext(); - // always use agent instrumentationKey, since that is (at least currently) always global in OpenTelemetry world - // (otherwise confusing message to have different rules for 2.x SDK interop telemetry) - context.setInstrumentationKey(getContext().getInstrumentationKey(), getContext().getNormalizedInstrumentationKey()); + // do not overwrite if the user has explicitly set the instrumentation key + // (either via 2.x SDK or ai.preview.instrumentation_key span attribute) + if (Strings.isNullOrEmpty(context.getInstrumentationKey())) { + context.setInstrumentationKey(getContext().getInstrumentationKey(), getContext().getNormalizedInstrumentationKey()); + } // the TelemetryClient's base context contains tags: // * cloud role name // * cloud role instance // * sdk version // * component version - // always use agent "resource attributes", since those are (at least currently) always global in OpenTelemetry world - // (otherwise confusing message to have different rules for 2.x SDK interop telemetry) - context.getTags().putAll(getContext().getTags()); + // do not overwrite if the user has explicitly set the cloud role name, cloud role instance, + // or application version (either via 2.x SDK, ai.preview.service_name, ai.preview.service_instance_id, + // or ai.preview.service_version span attributes) + for (Map.Entry entry : getContext().getTags().entrySet()) { + String key = entry.getKey(); + // only overwrite ai.internal.* tags, e.g. sdk version + if (key.startsWith("ai.internal.") || !context.getTags().containsKey(key)) { + context.getTags().put(key, entry.getValue()); + } + } // the TelemetryClient's base context contains properties: // * "customDimensions" provided by json configuration diff --git a/test/smoke/appServers/global-resources/opentelemetryapisupport_applicationinsights.json b/test/smoke/appServers/global-resources/opentelemetryapisupport_applicationinsights.json index 852cceef57e..161fedd1271 100644 --- a/test/smoke/appServers/global-resources/opentelemetryapisupport_applicationinsights.json +++ b/test/smoke/appServers/global-resources/opentelemetryapisupport_applicationinsights.json @@ -1,5 +1,9 @@ { "connectionString": "InstrumentationKey=00000000-0000-0000-0000-0FEEDDADBEEF;IngestionEndpoint=http://host.docker.internal:6060/", + "role": { + "name": "testrolename", + "instance": "testroleinstance" + }, "preview": { "httpMethodInOperationName": true, "openTelemetryApiSupport": true diff --git a/test/smoke/testApps/CoreAndFilter/build.gradle b/test/smoke/testApps/CoreAndFilter/build.gradle index bb96c62893c..943406cd0b2 100644 --- a/test/smoke/testApps/CoreAndFilter/build.gradle +++ b/test/smoke/testApps/CoreAndFilter/build.gradle @@ -1,7 +1,8 @@ apply plugin: 'war' dependencies { - implementation 'com.microsoft.azure:applicationinsights-web:0.9.3' // testing against oldest version with trackDependency() + implementation 'com.microsoft.azure:applicationinsights-web:2.2.0' // 0.9.3 is the oldest version with trackDependency() + // 2.2.0 is the oldest version with CloudContext testImplementation aiCoreJar // the test code (not the app under test) needs a modern core jar (well, at least 1.0.8) implementation 'com.google.guava:guava:20.0' diff --git a/test/smoke/testApps/CoreAndFilter/src/main/java/com/microsoft/applicationinsights/smoketestapp/SimpleTestRequestSlowWithResponseTime.java b/test/smoke/testApps/CoreAndFilter/src/main/java/com/microsoft/applicationinsights/smoketestapp/SimpleTestRequestSlowWithResponseTime.java index 0051a82be21..29ea6303649 100644 --- a/test/smoke/testApps/CoreAndFilter/src/main/java/com/microsoft/applicationinsights/smoketestapp/SimpleTestRequestSlowWithResponseTime.java +++ b/test/smoke/testApps/CoreAndFilter/src/main/java/com/microsoft/applicationinsights/smoketestapp/SimpleTestRequestSlowWithResponseTime.java @@ -1,7 +1,5 @@ package com.microsoft.applicationinsights.smoketestapp; -import org.apache.commons.lang3.StringUtils; - import java.io.IOException; import java.util.concurrent.TimeUnit; @@ -20,7 +18,7 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) int sleepTime = 25; final String customSleepTime = request.getParameter("sleeptime"); - if (StringUtils.isNotBlank(customSleepTime)) { + if (customSleepTime != null) { try { sleepTime = Integer.parseInt(customSleepTime); } catch (NumberFormatException e) { diff --git a/test/smoke/testApps/CoreAndFilter/src/main/java/com/microsoft/applicationinsights/smoketestapp/SimpleTrackPageViewServlet.java b/test/smoke/testApps/CoreAndFilter/src/main/java/com/microsoft/applicationinsights/smoketestapp/SimpleTrackPageViewServlet.java index 02172eb67e7..085fdcb4bbd 100644 --- a/test/smoke/testApps/CoreAndFilter/src/main/java/com/microsoft/applicationinsights/smoketestapp/SimpleTrackPageViewServlet.java +++ b/test/smoke/testApps/CoreAndFilter/src/main/java/com/microsoft/applicationinsights/smoketestapp/SimpleTrackPageViewServlet.java @@ -22,7 +22,11 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t client.flush(); PageViewTelemetry pvt2 = new PageViewTelemetry("test-page-2"); + // instrumentation key set on the Telemetry is used by interop pvt2.getContext().setInstrumentationKey("12341234-1234-1234-1234-123412341234"); + // role name and instance set on the Telemetry is used by interop + pvt2.getContext().getCloud().setRole("role-goes-here"); + pvt2.getContext().getCloud().setRoleInstance("role-instance-goes-here"); pvt2.getContext().getOperation().setName("operation-name-goes-here"); pvt2.getContext().getUser().setId("user-id-goes-here"); pvt2.getContext().getUser().setAccountId("account-id-goes-here"); @@ -39,8 +43,11 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t client.trackPageView(pvt2); TelemetryClient otherClient = new TelemetryClient(); - // instrumentation key set directly on the TelemetryClient is intentionally ignored by interop + // instrumentation key set on the TelemetryClient is intentionally ignored by interop otherClient.getContext().setInstrumentationKey("12341234-1234-1234-1234-123412341234"); + // role name and instance set on the TelemetryClient are intentionally ignored by interop + otherClient.getContext().getCloud().setRole("role-goes-here"); + otherClient.getContext().getCloud().setRoleInstance("role-instance-goes-here"); otherClient.getContext().getOperation().setName("operation-name-goes-here"); otherClient.getContext().getUser().setId("user-id-goes-here"); otherClient.getContext().getUser().setAccountId("account-id-goes-here"); diff --git a/test/smoke/testApps/CoreAndFilter/src/main/java/com/microsoft/applicationinsights/smoketestapp/SlowRequestCpuBoundServlet.java b/test/smoke/testApps/CoreAndFilter/src/main/java/com/microsoft/applicationinsights/smoketestapp/SlowRequestCpuBoundServlet.java index a2fe8c354b9..11f9a52ec42 100644 --- a/test/smoke/testApps/CoreAndFilter/src/main/java/com/microsoft/applicationinsights/smoketestapp/SlowRequestCpuBoundServlet.java +++ b/test/smoke/testApps/CoreAndFilter/src/main/java/com/microsoft/applicationinsights/smoketestapp/SlowRequestCpuBoundServlet.java @@ -1,7 +1,5 @@ package com.microsoft.applicationinsights.smoketestapp; -import org.apache.commons.lang3.StringUtils; - import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; @@ -23,13 +21,13 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) ServletFuncs.geRrenderHtml(request, response); int responseTime = 25; - final String customRepsonseTime = request.getParameter("responseTime"); - if (StringUtils.isNotBlank(customRepsonseTime)) { + final String customResponseTime = request.getParameter("responseTime"); + if (customResponseTime != null) { try { - responseTime = Integer.parseInt(customRepsonseTime); + responseTime = Integer.parseInt(customResponseTime); System.out.println("Custom responseTime = "+responseTime); } catch (NumberFormatException e) { - System.err.printf("Invalid value for 'responseTime': '%s'%n", customRepsonseTime); + System.err.printf("Invalid value for 'responseTime': '%s'%n", customResponseTime); } } diff --git a/test/smoke/testApps/CoreAndFilter/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/CoreAndFilterTests.java b/test/smoke/testApps/CoreAndFilter/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/CoreAndFilterTests.java index ca815f50c58..477b9c3c630 100644 --- a/test/smoke/testApps/CoreAndFilter/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/CoreAndFilterTests.java +++ b/test/smoke/testApps/CoreAndFilter/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/CoreAndFilterTests.java @@ -302,10 +302,11 @@ public void testTrackPageView() throws Exception { assertEquals("os-goes-here", pvdEnvelope2.getTags().get("ai.device.os")); assertEquals("session-id-goes-here", pvdEnvelope2.getTags().get("ai.session.id")); assertEquals("1.2.3.4", pvdEnvelope2.getTags().get("ai.location.ip")); - // checking that instrumentation key, cloud role name, cloud role instance, and sdk version are from the agent - assertEquals("00000000-0000-0000-0000-0FEEDDADBEEF", pvdEnvelope2.getIKey()); - assertEquals("testrolename", pvdEnvelope2.getTags().get("ai.cloud.role")); - assertEquals("testroleinstance", pvdEnvelope2.getTags().get("ai.cloud.roleInstance")); + // checking that instrumentation key, cloud role name and cloud role instance are overridden + assertEquals("12341234-1234-1234-1234-123412341234", pvdEnvelope2.getIKey()); + assertEquals("role-goes-here", pvdEnvelope2.getTags().get("ai.cloud.role")); + assertEquals("role-instance-goes-here", pvdEnvelope2.getTags().get("ai.cloud.roleInstance")); + // checking that sdk version is from the agent assertTrue(pvdEnvelope2.getTags().get("ai.internal.sdkVersion").startsWith("java:3.")); @@ -321,10 +322,11 @@ public void testTrackPageView() throws Exception { assertEquals("os-goes-here", pvdEnvelope3.getTags().get("ai.device.os")); assertEquals("session-id-goes-here", pvdEnvelope3.getTags().get("ai.session.id")); assertEquals("1.2.3.4", pvdEnvelope3.getTags().get("ai.location.ip")); - // checking that instrumentation key, cloud role name, cloud role instance, and sdk version are from the agent + // checking that instrumentation key, cloud role name and cloud role instance are from the agent assertEquals("00000000-0000-0000-0000-0FEEDDADBEEF", pvdEnvelope3.getIKey()); assertEquals("testrolename", pvdEnvelope3.getTags().get("ai.cloud.role")); assertEquals("testroleinstance", pvdEnvelope3.getTags().get("ai.cloud.roleInstance")); + // checking that sdk version is from the agent assertTrue(pvdEnvelope3.getTags().get("ai.internal.sdkVersion").startsWith("java:3.")); assertParentChild(rd, rdEnvelope, pvdEnvelope1, "GET /CoreAndFilter/trackPageView"); diff --git a/test/smoke/testApps/OpenTelemetryApiSupport/src/main/java/com/microsoft/applicationinsights/smoketestapp/TestController.java b/test/smoke/testApps/OpenTelemetryApiSupport/src/main/java/com/microsoft/applicationinsights/smoketestapp/TestController.java index fcdfa91bded..29620c5f5ea 100644 --- a/test/smoke/testApps/OpenTelemetryApiSupport/src/main/java/com/microsoft/applicationinsights/smoketestapp/TestController.java +++ b/test/smoke/testApps/OpenTelemetryApiSupport/src/main/java/com/microsoft/applicationinsights/smoketestapp/TestController.java @@ -22,6 +22,15 @@ public String testApi() { return "OK!"; } + @GetMapping("/test-overriding-ikey-etc") + public String testOverridingIkeyEtc() { + Span.current().setAttribute("ai.preview.instrumentation_key", "12341234-1234-1234-1234-123412341234"); + Span.current().setAttribute("ai.preview.service_name", "role-name-here"); + Span.current().setAttribute("ai.preview.service_instance_id", "role-instance-here"); + Span.current().setAttribute("ai.preview.service_version", "application-version-here"); + return "OK!"; + } + @GetMapping("/test-annotations") public String testAnnotations() { return underAnnotation(); diff --git a/test/smoke/testApps/OpenTelemetryApiSupport/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/OpenTelemetryApiSupportTest.java b/test/smoke/testApps/OpenTelemetryApiSupport/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/OpenTelemetryApiSupportTest.java index f0980c0930b..de7f1df889a 100644 --- a/test/smoke/testApps/OpenTelemetryApiSupport/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/OpenTelemetryApiSupportTest.java +++ b/test/smoke/testApps/OpenTelemetryApiSupport/src/smokeTest/java/com/microsoft/applicationinsights/smoketest/OpenTelemetryApiSupportTest.java @@ -33,8 +33,15 @@ public void testApi() throws Exception { assertTrue(rd.getSuccess()); assertEquals("myspanname", rdd.getName()); - // ideally want these on rd, but can't get SERVER span yet + + // ideally want the properties below on rd, but can't get SERVER span yet // see https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/1726#issuecomment-731890267 + + // checking that instrumentation key, cloud role name, cloud role instance, and sdk version are from the agent + assertEquals("00000000-0000-0000-0000-0FEEDDADBEEF", rddEnvelope.getIKey()); + assertEquals("testrolename", rddEnvelope.getTags().get("ai.cloud.role")); + assertEquals("testroleinstance", rddEnvelope.getTags().get("ai.cloud.roleInstance")); + assertTrue(rddEnvelope.getTags().get("ai.internal.sdkVersion").startsWith("java:3.")); assertEquals("myuser", rddEnvelope.getTags().get("ai.user.id")); assertEquals("myvalue1", rdd.getProperties().get("myattr1")); assertEquals("myvalue2", rdd.getProperties().get("myattr2")); @@ -44,6 +51,40 @@ public void testApi() throws Exception { assertParentChild(rd.getId(), rdEnvelope, rddEnvelope); } + @Test + @TargetUri("/test-overriding-ikey-etc") + public void testOverridingIkeyEtc() throws Exception { + List rdList = mockedIngestion.waitForItems("RequestData", 1); + + Envelope rdEnvelope = rdList.get(0); + String operationId = rdEnvelope.getTags().get("ai.operation.id"); + List rddList = mockedIngestion.waitForItemsInOperation("RemoteDependencyData", 1, operationId); + assertEquals(0, mockedIngestion.getCountForType("EventData")); + + Envelope rddEnvelope = rddList.get(0); + + RequestData rd = (RequestData) ((Data) rdEnvelope.getData()).getBaseData(); + RemoteDependencyData rdd = (RemoteDependencyData) ((Data) rddEnvelope.getData()).getBaseData(); + + assertEquals("GET /OpenTelemetryApiSupport/test-overriding-ikey-etc", rd.getName()); + assertTrue(rd.getProperties().isEmpty()); + assertTrue(rd.getSuccess()); + + // ideally want the properties below on rd, but can't get SERVER span yet + // see https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/1726#issuecomment-731890267 + + // checking that instrumentation key, cloud role name, cloud role instance, and sdk version are from the agent + assertEquals("12341234-1234-1234-1234-123412341234", rddEnvelope.getIKey()); + assertEquals("role-name-here", rddEnvelope.getTags().get("ai.cloud.role")); + assertEquals("role-instance-here", rddEnvelope.getTags().get("ai.cloud.roleInstance")); + assertEquals("application-version-here", rddEnvelope.getTags().get("ai.application.ver")); + assertTrue(rddEnvelope.getTags().get("ai.internal.sdkVersion").startsWith("java:3.")); + assertTrue(rdd.getProperties().isEmpty()); + assertTrue(rdd.getSuccess()); + + assertParentChild(rd.getId(), rdEnvelope, rddEnvelope); + } + @Test @TargetUri("/test-annotations") public void testAnnotations() throws Exception {