diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/CHANGELOG.md b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/CHANGELOG.md index 237ba0f7ce2b..8e458e592b70 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/CHANGELOG.md +++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/CHANGELOG.md @@ -10,6 +10,8 @@ ### Other Changes +- Align customer-facing SDKStats configuration and custom dimension names with the stable specification. + ## 1.5.0 (2026-06-11) ### Features Added diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/README.md b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/README.md index 3aed3839ba3f..0e0884a09f1b 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/README.md +++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/README.md @@ -152,6 +152,14 @@ Learn more about [OpenTelemetry SDK logging][logging_otel_sdk]. You can disable the [live metrics][live_metrics] by setting the `APPLICATIONINSIGHTS_LIVE_METRICS_ENABLED` environment variable to false, the `applicationinsights.live.metrics.enabled` Java system property to false, or programmatically with a properties supplier: `sdkBuilder.addPropertiesSupplier(() -> Collections.singletonMap("applicationinsights.live.metrics.enabled", "false"))`. +### Customer-facing SDKStats + +Customer-facing SDKStats emit `Item_Success_Count`, `Item_Dropped_Count`, and `Item_Retry_Count` +custom metrics to the configured Application Insights resource by default. Set +`APPLICATIONINSIGHTS_SDKSTATS_DISABLED` to `true` to disable them. Metrics are exported every 900 +seconds by default; set `APPLICATIONINSIGHTS_SDKSTATS_EXPORT_INTERVAL` to a positive number of +seconds to change the interval. + ## Next steps Learn more about [OpenTelemetry][opentelemetry_io] @@ -206,4 +214,3 @@ This project has adopted the [Microsoft Open Source Code of Conduct][coc]. For m [coc]: https://opensource.microsoft.com/codeofconduct/ [coc_faq]: https://opensource.microsoft.com/codeofconduct/faq/ [coc_contact]: mailto:opencode@microsoft.com - diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorExporterBuilder.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorExporterBuilder.java index b001b0e354ce..f741482dcc70 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorExporterBuilder.java +++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorExporterBuilder.java @@ -68,9 +68,9 @@ class AzureMonitorExporterBuilder { private static final String STATSBEAT_SHORT_INTERVAL_SECONDS_PROPERTY_NAME = "STATSBEAT_SHORT_INTERVAL_SECONDS_PROPERTY_NAME"; - private static final String SDKSTATS_DISABLED_ENV_VAR = "APPLICATIONINSIGHTS_SDKSTATS_DISABLED"; + private static final String SDKSTATS_DISABLED_PROPERTY_NAME = "applicationinsights.sdkstats.disabled"; private static final String SDKSTATS_DISABLED_ALL_ENV_VAR = "APPLICATIONINSIGHTS_SDKStats_DISABLED_ALL"; - private static final String SDKSTATS_EXPORT_INTERVAL_ENV_VAR = "APPLICATIONINSIGHTS_SDKSTATS_EXPORT_INTERVAL"; + private static final String SDKSTATS_EXPORT_INTERVAL_PROPERTY_NAME = "applicationinsights.sdkstats.export.interval"; private static final long SDKSTATS_DEFAULT_EXPORT_INTERVAL_SECONDS = 900; // 15 minutes private static final Map PROPERTIES @@ -261,8 +261,8 @@ private void startStatsbeatModule(StatsbeatModule statsbeatModule, ConfigPropert } private CustomerSdkStats createCustomerSdkStats() { - // Use the raw library version number (e.g. "3.6.0") for the customer-facing stats dimension - String version = PropertyHelper.getSdkVersionNumber(); + // Use the raw distro version number (e.g. "1.6.0-beta.1") for the customer-facing stats dimension. + String version = VersionGenerator.getSdkVersionNumber(); return CustomerSdkStats.create(version); } @@ -271,12 +271,16 @@ private boolean isCustomerSdkStatsEnabled() { } static boolean isCustomerSdkStatsEnabled(ConfigProperties configProperties) { - if ("true".equalsIgnoreCase(configProperties.getString(SDKSTATS_DISABLED_ALL_ENV_VAR))) { + String disabledAll = configProperties.getString(SDKSTATS_DISABLED_ALL_ENV_VAR); + if (disabledAll == null) { + disabledAll = Configuration.getGlobalConfiguration().get(SDKSTATS_DISABLED_ALL_ENV_VAR); + } + if ("true".equalsIgnoreCase(disabledAll)) { return false; } - String disabledValue = configProperties.getString(SDKSTATS_DISABLED_ENV_VAR); - if ("true".equalsIgnoreCase(disabledValue)) { - LOGGER.verbose("Customer SDKStats is disabled via configuration property {}.", SDKSTATS_DISABLED_ENV_VAR); + if ("true".equalsIgnoreCase(configProperties.getString(SDKSTATS_DISABLED_PROPERTY_NAME))) { + LOGGER.verbose("Customer SDKStats is disabled via configuration property {}.", + SDKSTATS_DISABLED_PROPERTY_NAME); return false; } return true; @@ -285,11 +289,12 @@ static boolean isCustomerSdkStatsEnabled(ConfigProperties configProperties) { private void startCustomerSdkStats(CustomerSdkStats customerSdkStats, CustomerSdkStatsTelemetryPipelineListener customerSdkStatsListener, Resource resource) { // Get export interval from configuration or use default - long exportIntervalSeconds - = configProperties.getLong(SDKSTATS_EXPORT_INTERVAL_ENV_VAR, SDKSTATS_DEFAULT_EXPORT_INTERVAL_SECONDS); + long exportIntervalSeconds = configProperties.getLong(SDKSTATS_EXPORT_INTERVAL_PROPERTY_NAME, + SDKSTATS_DEFAULT_EXPORT_INTERVAL_SECONDS); if (exportIntervalSeconds <= 0) { LOGGER.warning("Value for {} must be positive: {}. Using default {} seconds.", - SDKSTATS_EXPORT_INTERVAL_ENV_VAR, exportIntervalSeconds, SDKSTATS_DEFAULT_EXPORT_INTERVAL_SECONDS); + SDKSTATS_EXPORT_INTERVAL_PROPERTY_NAME, exportIntervalSeconds, + SDKSTATS_DEFAULT_EXPORT_INTERVAL_SECONDS); exportIntervalSeconds = SDKSTATS_DEFAULT_EXPORT_INTERVAL_SECONDS; } diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/statsbeat/CustomerSdkStats.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/statsbeat/CustomerSdkStats.java index a366c3340c54..d43f6a4b727b 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/statsbeat/CustomerSdkStats.java +++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/statsbeat/CustomerSdkStats.java @@ -77,7 +77,7 @@ public void incrementSuccessCount(Map itemCountsByType) { * @param itemCountsByType the per-type item counts * @param dropCode the drop code (e.g. "CLIENT_EXCEPTION", "402", etc.) * @param dropReason the drop reason (e.g. "Exceeded daily quota") - * @param successItemCountsByType success items by type (for telemetry_success dimension on + * @param successItemCountsByType success items by type (for telemetrySuccess dimension on * REQUEST/DEPENDENCY) * @param failureItemCountsByType failure items by type */ @@ -87,7 +87,7 @@ public void incrementDroppedCount(Map itemCountsByType, String dro String telemetryType = entry.getKey(); long totalCount = entry.getValue(); - // For REQUEST and DEPENDENCY, split by telemetry_success + // For REQUEST and DEPENDENCY, split by telemetrySuccess if ("REQUEST".equals(telemetryType) || "DEPENDENCY".equals(telemetryType)) { long successCount = successItemCountsByType.getOrDefault(telemetryType, 0L); long failureCount = failureItemCountsByType.getOrDefault(telemetryType, 0L); @@ -108,7 +108,7 @@ public void incrementDroppedCount(Map itemCountsByType, String dro droppedCounts.computeIfAbsent(key, k -> new AtomicLong()).addAndGet(unaccounted); } } else { - // For non-REQUEST/DEPENDENCY types, telemetry_success is not applicable + // For non-REQUEST/DEPENDENCY types, telemetrySuccess is not applicable DroppedKey key = new DroppedKey(telemetryType, dropCode, dropReason, null); droppedCounts.computeIfAbsent(key, k -> new AtomicLong()).addAndGet(totalCount); } @@ -153,7 +153,7 @@ public List collectAndReset(ConnectionString connectionString, St builder.setTime(FormattedTime.offSetDateTimeFromNow()); addCommonTags(builder, sdkVersion, cloudRole, cloudRoleInstance); addCommonProperties(builder); - builder.addProperty("telemetry_type", key.telemetryType); + builder.addProperty("telemetryType", key.telemetryType); telemetryItems.add(builder.build()); } @@ -170,13 +170,13 @@ public List collectAndReset(ConnectionString connectionString, St builder.setTime(FormattedTime.offSetDateTimeFromNow()); addCommonTags(builder, sdkVersion, cloudRole, cloudRoleInstance); addCommonProperties(builder); - builder.addProperty("telemetry_type", key.telemetryType); - builder.addProperty("drop.code", key.dropCode); + builder.addProperty("telemetryType", key.telemetryType); + builder.addProperty("dropCode", key.dropCode); if (key.dropReason != null) { - builder.addProperty("drop.reason", key.dropReason); + builder.addProperty("dropReason", key.dropReason); } if (key.telemetrySuccess != null) { - builder.addProperty("telemetry_success", key.telemetrySuccess.toString()); + builder.addProperty("telemetrySuccess", key.telemetrySuccess.toString()); } telemetryItems.add(builder.build()); } @@ -194,10 +194,10 @@ public List collectAndReset(ConnectionString connectionString, St builder.setTime(FormattedTime.offSetDateTimeFromNow()); addCommonTags(builder, sdkVersion, cloudRole, cloudRoleInstance); addCommonProperties(builder); - builder.addProperty("telemetry_type", key.telemetryType); - builder.addProperty("retry.code", key.retryCode); + builder.addProperty("telemetryType", key.telemetryType); + builder.addProperty("retryCode", key.retryCode); if (key.retryReason != null) { - builder.addProperty("retry.reason", key.retryReason); + builder.addProperty("retryReason", key.retryReason); } telemetryItems.add(builder.build()); } diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/statsbeat/CustomerSdkStatsExceptionCategory.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/statsbeat/CustomerSdkStatsExceptionCategory.java index 3199d95ba389..1be1e5b5ed76 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/statsbeat/CustomerSdkStatsExceptionCategory.java +++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/statsbeat/CustomerSdkStatsExceptionCategory.java @@ -11,7 +11,7 @@ /** * Categorizes exceptions into low-cardinality reason strings for customer-facing SDKStats - * drop.reason and retry.reason dimensions. + * dropReason and retryReason dimensions. */ final class CustomerSdkStatsExceptionCategory { diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/statsbeat/CustomerSdkStatsTelemetryType.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/statsbeat/CustomerSdkStatsTelemetryType.java index 359547766619..d48777b5abea 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/statsbeat/CustomerSdkStatsTelemetryType.java +++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/statsbeat/CustomerSdkStatsTelemetryType.java @@ -10,7 +10,7 @@ import java.util.Map; /** - * Maps TelemetryItem.getName() values to the telemetry_type dimension values + * Maps TelemetryItem.getName() values to the telemetryType dimension values * used in customer-facing SDKStats metrics. */ public final class CustomerSdkStatsTelemetryType { @@ -31,10 +31,10 @@ public final class CustomerSdkStatsTelemetryType { } /** - * Maps a TelemetryItem name to its customer-facing telemetry_type value. + * Maps a TelemetryItem name to its customer-facing telemetryType value. * * @param telemetryItemName the value from TelemetryItem.getName() - * @return the telemetry_type dimension value, or null if the item should be skipped + * @return the telemetryType dimension value, or null if the item should be skipped * (e.g. "Statsbeat" internal metrics) */ @Nullable diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/utils/VersionGenerator.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/utils/VersionGenerator.java index 8f9309f3f3ae..4dd587baf5d7 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/utils/VersionGenerator.java +++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/utils/VersionGenerator.java @@ -14,6 +14,7 @@ public final class VersionGenerator { private static final String UNKNOWN_VERSION_VALUE = "unknown"; private static final String sdkVersionString; + private static final String sdkVersionNumber; static { String componentName = null; @@ -41,8 +42,9 @@ public final class VersionGenerator { componentVersion = otelAutoconfigureProperties.get("version"); } + sdkVersionNumber = componentVersion != null ? componentVersion : UNKNOWN_VERSION_VALUE; sdkVersionString = getPrefix() + "java" + getJavaVersion() + getJavaRuntime() + ":" + "otel" - + getOpenTelemetryApiVersion() + ":" + componentName + componentVersion; + + getOpenTelemetryApiVersion() + ":" + componentName + sdkVersionNumber; } private static String getPrefix() { @@ -82,6 +84,15 @@ public static String getSdkVersion() { return sdkVersionString; } + /** + * Returns the version of the Azure Monitor distro represented in {@link #getSdkVersion()}. + * + * @return the Azure Monitor distro version. + */ + public static String getSdkVersionNumber() { + return sdkVersionNumber; + } + private static String getJavaVersion() { return System.getProperty("java.version"); } diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/samples/java/com/azure/monitor/opentelemetry/autoconfigure/SimpleWebAppSample-README.md b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/samples/java/com/azure/monitor/opentelemetry/autoconfigure/SimpleWebAppSample-README.md index d9f3aa25abfc..9b8b4f0158be 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/samples/java/com/azure/monitor/opentelemetry/autoconfigure/SimpleWebAppSample-README.md +++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/samples/java/com/azure/monitor/opentelemetry/autoconfigure/SimpleWebAppSample-README.md @@ -147,4 +147,4 @@ Press `Ctrl+C` in the terminal running the sample. - In **drop/retry** modes, both application telemetry and SDKStats metrics go through the same mock pipeline. SDKStats metrics are visible only in the console output, not in Azure Monitor. - The mock server automatically gunzips incoming payloads and prints each telemetry item on its own line. -- SDKStats dimensions include: `computeType`, `language`, `version`, `telemetry_type`, `telemetry_success`, and mode-specific fields (`drop.code`/`drop.reason` or `retry.code`/`retry.reason`). +- SDKStats dimensions include: `computeType`, `language`, `version`, `telemetryType`, `telemetrySuccess`, and mode-specific fields (`dropCode`/`dropReason` or `retryCode`/`retryReason`). diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorExporterBuilderTest.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorExporterBuilderTest.java index 0fe02055ac94..69f5af577285 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorExporterBuilderTest.java +++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/AzureMonitorExporterBuilderTest.java @@ -24,7 +24,7 @@ public void customerSdkStatsEnabledByDefault() { @Test public void customerSdkStatsDisabledByPublicProperty() { ConfigProperties config = DefaultConfigProperties - .createFromMap(Collections.singletonMap("APPLICATIONINSIGHTS_SDKSTATS_DISABLED", "true")); + .createFromMap(Collections.singletonMap("applicationinsights.sdkstats.disabled", "true")); assertThat(AzureMonitorExporterBuilder.isCustomerSdkStatsEnabled(config)).isFalse(); } @@ -38,7 +38,7 @@ public void customerSdkStatsDisabledByAllProperty() { @Test public void customerSdkStatsDisabledAllTakesPrecedence() { Map props = new HashMap<>(); - props.put("APPLICATIONINSIGHTS_SDKSTATS_DISABLED", "false"); + props.put("applicationinsights.sdkstats.disabled", "false"); props.put("APPLICATIONINSIGHTS_SDKStats_DISABLED_ALL", "true"); ConfigProperties config = DefaultConfigProperties.createFromMap(props); assertThat(AzureMonitorExporterBuilder.isCustomerSdkStatsEnabled(config)).isFalse(); @@ -46,8 +46,16 @@ public void customerSdkStatsDisabledAllTakesPrecedence() { @Test public void customerSdkStatsDisabledAllFalseLeavesEnabled() { + Map props = new HashMap<>(); + props.put("APPLICATIONINSIGHTS_SDKStats_DISABLED_ALL", "false"); + ConfigProperties config = DefaultConfigProperties.createFromMap(props); + assertThat(AzureMonitorExporterBuilder.isCustomerSdkStatsEnabled(config)).isTrue(); + } + + @Test + public void customerSdkStatsDisabledFalseLeavesEnabled() { ConfigProperties config = DefaultConfigProperties - .createFromMap(Collections.singletonMap("APPLICATIONINSIGHTS_SDKStats_DISABLED_ALL", "false")); + .createFromMap(Collections.singletonMap("applicationinsights.sdkstats.disabled", "false")); assertThat(AzureMonitorExporterBuilder.isCustomerSdkStatsEnabled(config)).isTrue(); } } diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/statsbeat/CustomerSdkStatsTest.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/statsbeat/CustomerSdkStatsTest.java index 767a5ed565dc..441f75c2082d 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/statsbeat/CustomerSdkStatsTest.java +++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/statsbeat/CustomerSdkStatsTest.java @@ -4,7 +4,9 @@ package com.azure.monitor.opentelemetry.autoconfigure.implementation.statsbeat; import com.azure.monitor.opentelemetry.autoconfigure.implementation.configuration.ConnectionString; +import com.azure.monitor.opentelemetry.autoconfigure.implementation.models.MetricsData; import com.azure.monitor.opentelemetry.autoconfigure.implementation.models.TelemetryItem; +import com.azure.monitor.opentelemetry.autoconfigure.implementation.utils.TestUtils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -17,6 +19,7 @@ import java.util.concurrent.TimeUnit; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; public class CustomerSdkStatsTest { @@ -119,12 +122,54 @@ public void testCollectAndResetReturnsCorrectMetrics() { // Should have 3 metric items assertThat(items).hasSize(3); + MetricsData successMetric = getMetric(items, CustomerSdkStats.ITEM_SUCCESS_COUNT); + assertThat(successMetric.getMetrics().get(0).getValue()).isEqualTo(10); + assertThat(successMetric.getProperties()).containsOnly(entry("computeType", "unknown"), + entry("language", "java"), entry("version", "3.5.1"), entry("telemetryType", "REQUEST")); + + MetricsData droppedMetric = getMetric(items, CustomerSdkStats.ITEM_DROPPED_COUNT); + assertThat(droppedMetric.getMetrics().get(0).getValue()).isEqualTo(5); + assertThat(droppedMetric.getProperties()).containsOnly(entry("computeType", "unknown"), + entry("language", "java"), entry("version", "3.5.1"), entry("telemetryType", "DEPENDENCY"), + entry("dropCode", "402"), entry("dropReason", "Exceeded daily quota")); + + MetricsData retryMetric = getMetric(items, CustomerSdkStats.ITEM_RETRY_COUNT); + assertThat(retryMetric.getMetrics().get(0).getValue()).isEqualTo(3); + assertThat(retryMetric.getProperties()).containsOnly(entry("computeType", "unknown"), entry("language", "java"), + entry("version", "3.5.1"), entry("telemetryType", "TRACE"), entry("retryCode", "429"), + entry("retryReason", "Too many requests")); + + assertThat(items).allSatisfy(item -> { + assertThat(item.getInstrumentationKey()).isEqualTo(CONNECTION_STRING.getInstrumentationKey()); + assertThat(item.getTags()).containsEntry("ai.internal.sdkVersion", SDK_VERSION) + .containsEntry("ai.cloud.role", CLOUD_ROLE) + .containsEntry("ai.cloud.roleInstance", CLOUD_ROLE_INSTANCE); + }); + // Verify that counters are cleared assertThat(customerSdkStats.getSuccessCount("REQUEST")).isEqualTo(0); assertThat(customerSdkStats.getDroppedCount("DEPENDENCY", "402")).isEqualTo(0); assertThat(customerSdkStats.getRetryCount("TRACE", "429")).isEqualTo(0); } + @Test + public void testDroppedMetricUsesTelemetrySuccessDimension() { + customerSdkStats.incrementDroppedCount(Collections.singletonMap("REQUEST", 2L), "402", "Exceeded daily quota", + Collections.singletonMap("REQUEST", 1L), Collections.singletonMap("REQUEST", 1L)); + + List items + = customerSdkStats.collectAndReset(CONNECTION_STRING, SDK_VERSION, CLOUD_ROLE, CLOUD_ROLE_INSTANCE); + + assertThat(items).hasSize(2); + assertThat(items) + .extracting( + item -> TestUtils.toMetricsData(item.getData().getBaseData()).getProperties().get("telemetrySuccess")) + .containsExactlyInAnyOrder("true", "false"); + assertThat(items) + .allSatisfy(item -> assertThat(TestUtils.toMetricsData(item.getData().getBaseData()).getProperties()) + .doesNotContainKeys("telemetry_success", "telemetry_type", "drop.code", "drop.reason")); + } + @Test public void testCollectAndResetEmptyReturnsEmptyList() { List items @@ -167,4 +212,14 @@ public void testConcurrentIncrements() throws InterruptedException { assertThat(customerSdkStats.getSuccessCount("REQUEST")).isEqualTo(threads * incrementsPerThread); } + + private static MetricsData getMetric(List items, String metricName) { + for (TelemetryItem item : items) { + MetricsData metric = TestUtils.toMetricsData(item.getData().getBaseData()); + if (metricName.equals(metric.getMetrics().get(0).getName())) { + return metric; + } + } + throw new AssertionError("Metric not found: " + metricName); + } } diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/utils/VersionGeneratorTest.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/utils/VersionGeneratorTest.java new file mode 100644 index 000000000000..265bd2e1ac40 --- /dev/null +++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/utils/VersionGeneratorTest.java @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.monitor.opentelemetry.autoconfigure.implementation.utils; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class VersionGeneratorTest { + + @Test + public void sdkVersionNumberIsAvailable() { + assertThat(VersionGenerator.getSdkVersionNumber()).isNotEqualTo("unknown"); + assertThat(VersionGenerator.getSdkVersion()).endsWith(VersionGenerator.getSdkVersionNumber()); + } +}