diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/checkstyle-suppressions.xml b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/checkstyle-suppressions.xml
index d505a0d2cd32..dcce54a16b2b 100644
--- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/checkstyle-suppressions.xml
+++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/checkstyle-suppressions.xml
@@ -252,6 +252,7 @@
+
@@ -368,6 +369,7 @@
+
diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/QuickPulseCoordinator.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/QuickPulseCoordinator.java
index 2cb45cdb8d6e..a2be60112d2d 100644
--- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/QuickPulseCoordinator.java
+++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/QuickPulseCoordinator.java
@@ -85,6 +85,7 @@ private long sendData() {
// in an error state (ping once a minute) if the first ping after the failing post also fails.
long errorDelayInNs = TimeUnit.SECONDS.toNanos(40);
pingSender.resetLastValidRequestTimeNs(dataSender.getLastValidPostRequestTimeNs() - errorDelayInNs);
+ logger.verbose("Switching to fallback mode.");
return waitOnErrorInMillis;
case QP_IS_OFF:
@@ -95,6 +96,7 @@ private long sendData() {
// sender to go into backoff state immediately instead of waiting 60s to go into backoff state like
// the spec describes. See: https://github.com/aep-health-and-standards/Telemetry-Collection-Spec/blob/main/ApplicationInsights/livemetrics.md#timings
pingSender.resetLastValidRequestTimeNs(dataSender.getLastValidPostRequestTimeNs());
+ logger.verbose("Switching to ping mode.");
return qpsServicePollingIntervalHintMillis > 0
? qpsServicePollingIntervalHintMillis
: waitBetweenPingsInMillis;
@@ -118,10 +120,12 @@ private long ping() {
collector.setQuickPulseStatus(qpStatus);
switch (qpStatus) {
case ERROR:
+ logger.verbose("In fallback mode");
return waitOnErrorInMillis;
case QP_IS_ON:
pingMode = false;
+ logger.verbose("Switching to post mode");
// Below two lines are necessary because there are cases where the last valid request is a ping
// before a failing post. This can happen in cases where authentication fails - pings would return
// http 200 but posts http 401.
diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/QuickPulseDataCollector.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/QuickPulseDataCollector.java
index 18a5d052368f..c11f574997dd 100644
--- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/QuickPulseDataCollector.java
+++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/QuickPulseDataCollector.java
@@ -29,6 +29,7 @@
import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.Trace;
import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.TelemetryType;
import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.AggregationType;
+import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.CollectionConfigurationError;
import com.azure.monitor.opentelemetry.autoconfigure.implementation.utils.CpuPerformanceCounterCalculator;
import reactor.util.annotation.Nullable;
@@ -59,7 +60,6 @@ final class QuickPulseDataCollector {
private volatile Supplier instrumentationKeySupplier;
- // TODO (harskaur): Track projection (runtime) related errors in future PR
private final AtomicReference configuration;
QuickPulseDataCollector(AtomicReference configuration) {
@@ -77,7 +77,8 @@ synchronized void disable() {
synchronized void enable(Supplier instrumentationKeySupplier) {
this.instrumentationKeySupplier = instrumentationKeySupplier;
- counters.set(new Counters(configuration.get().getValidProjectionInitInfo()));
+ FilteringConfiguration config = configuration.get();
+ counters.set(new Counters(config.getValidProjectionInitInfo(), config.getErrors()));
}
synchronized void setQuickPulseStatus(QuickPulseStatus quickPulseStatus) {
@@ -91,7 +92,9 @@ synchronized QuickPulseStatus getQuickPulseStatus() {
@Nullable
synchronized FinalCounters getAndRestart() {
- Counters currentCounters = counters.getAndSet(new Counters(configuration.get().getValidProjectionInitInfo()));
+ FilteringConfiguration config = configuration.get();
+ Counters currentCounters
+ = counters.getAndSet(new Counters(config.getValidProjectionInitInfo(), config.getErrors()));
if (currentCounters != null) {
return new FinalCounters(currentCounters);
}
@@ -180,7 +183,6 @@ private void applyMetricFilters(TelemetryColumns columns, TelemetryType telemetr
List metricsConfig = currentConfig.fetchMetricConfigForTelemetryType(telemetryType);
for (DerivedMetricInfo derivedMetricInfo : metricsConfig) {
if (Filter.checkMetricFilters(derivedMetricInfo, columns)) {
- // TODO (harskaur): In future PR, track any error that comes from calculateProjection
currentCounters.derivedMetrics.calculateProjection(derivedMetricInfo, columns);
}
}
@@ -411,6 +413,8 @@ class FinalCounters {
final Map projections;
+ final List configErrors;
+
private FinalCounters(Counters currentCounters) {
processPhysicalMemory = getPhysicalMemory(memory);
@@ -431,6 +435,7 @@ private FinalCounters(Counters currentCounters) {
this.documentList.addAll(currentCounters.documentList);
}
this.projections = currentCounters.derivedMetrics.fetchFinalDerivedMetricValues();
+ this.configErrors = currentCounters.configErrors;
}
@@ -486,8 +491,11 @@ static class Counters {
final DerivedMetricProjections derivedMetrics;
- Counters(Map projectionInfo) {
+ final List configErrors;
+
+ Counters(Map projectionInfo, List errors) {
derivedMetrics = new DerivedMetricProjections(projectionInfo);
+ configErrors = errors;
}
static long encodeCountAndDuration(long count, long duration) {
diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/QuickPulseDataFetcher.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/QuickPulseDataFetcher.java
index cbda612dab17..6b86026d2b21 100644
--- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/QuickPulseDataFetcher.java
+++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/QuickPulseDataFetcher.java
@@ -93,6 +93,7 @@ private MonitoringDataPoint buildMonitoringDataPoint(QuickPulseDataCollector.Fin
point.setVersion(sdkVersion);
point.setTimestamp(OffsetDateTime.now());
point.setMetrics(addMetricsToMonitoringDataPoint(counters));
+ point.setCollectionConfigurationErrors(counters.configErrors);
return point;
}
diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/QuickPulseDataSender.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/QuickPulseDataSender.java
index cee360f43d47..40a666923aea 100644
--- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/QuickPulseDataSender.java
+++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/QuickPulseDataSender.java
@@ -6,6 +6,7 @@
import com.azure.core.http.rest.Response;
import com.azure.core.util.logging.ClientLogger;
+import com.azure.core.util.logging.LogLevel;
import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.filtering.FilteringConfiguration;
import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.LiveMetricsRestAPIsForClientSDKs;
import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.CollectionConfigurationInfo;
@@ -79,13 +80,17 @@ public void run() {
dataPointList.add(point);
Date currentDate = new Date();
long transmissionTimeInTicks = currentDate.getTime() * 10000 + TICKS_AT_EPOCH;
+ String etag = configuration.get().getETag();
+
+ if (logger.canLogAtLevel(LogLevel.VERBOSE)) {
+ logger.verbose("Attempting to send data points to quickpulse with etag {}: {}", etag,
+ printListOfMonitoringPoints(dataPointList));
+ }
+
try {
- // TODO (harskaur): remove logging when manual testing done
- logger.verbose("Monitoring point: {}", point.toJsonString());
- logger.verbose("etag: {}", configuration.get().getETag());
Response responseMono = liveMetricsRestAPIsForClientSDKs
- .publishNoCustomHeadersWithResponseAsync(endpointPrefix, instrumentationKey.get(),
- configuration.get().getETag(), transmissionTimeInTicks, dataPointList)
+ .publishNoCustomHeadersWithResponseAsync(endpointPrefix, instrumentationKey.get(), etag,
+ transmissionTimeInTicks, dataPointList)
.block();
if (responseMono == null) {
// this shouldn't happen, the mono should complete with a response or a failure
@@ -105,17 +110,17 @@ public void run() {
lastValidRequestTimeNs = sendTime;
CollectionConfigurationInfo body = responseMono.getValue();
- if (body != null && !configuration.get().getETag().equals(body.getETag())) {
+ if (body != null && !etag.equals(body.getETag())) {
configuration.set(new FilteringConfiguration(body));
- // TODO (harskaur): remove logging when manual testing done
try {
- logger.verbose("passed in config {}", body.toJsonString());
+ logger.verbose("Received a new live metrics filtering configuration from post response: {}",
+ body.toJsonString());
} catch (IOException e) {
- logger.error(e.getMessage());
+ logger.verbose(e.getMessage());
}
}
- } catch (RuntimeException | IOException e) { // this includes ServiceErrorException & RuntimeException thrown from quickpulse post api
+ } catch (RuntimeException e) { // this includes ServiceErrorException & RuntimeException thrown from quickpulse post api
onPostError(sendTime);
logger.error(
"QuickPulseDataSender received a service error while attempting to send data to quickpulse {}",
@@ -136,6 +141,20 @@ private void onPostError(long sendTime) {
}
}
+ private String printListOfMonitoringPoints(List points) {
+ StringBuilder dataPointsPrint = new StringBuilder("[");
+ for (MonitoringDataPoint p : points) {
+ try {
+ dataPointsPrint.append(p.toJsonString());
+ dataPointsPrint.append("\n");
+ } catch (IOException e) {
+ logger.verbose(e.getMessage());
+ }
+ }
+ dataPointsPrint.append("]");
+ return dataPointsPrint.toString();
+ }
+
public void setRedirectEndpointPrefix(String endpointPrefix) {
this.redirectEndpointPrefix = endpointPrefix;
}
diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/QuickPulsePingSender.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/QuickPulsePingSender.java
index b9fca6455f25..92c4afe5ff4b 100644
--- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/QuickPulsePingSender.java
+++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/QuickPulsePingSender.java
@@ -17,6 +17,7 @@
import com.azure.monitor.opentelemetry.autoconfigure.implementation.utils.Strings;
import reactor.util.annotation.Nullable;
+import java.io.IOException;
import java.net.URL;
import java.util.Date;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -104,6 +105,12 @@ IsSubscribedHeaders ping(String redirectedEndpoint) {
CollectionConfigurationInfo body = responseMono.getValue();
if (body != null && !configuration.get().getETag().equals(body.getETag())) {
+ try {
+ logger.verbose("Received a new live metrics filtering configuration from ping response: {}",
+ body.toJsonString());
+ } catch (IOException e) {
+ logger.verbose(e.getMessage());
+ }
configuration.set(new FilteringConfiguration(body));
}
diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filtering/ConfigErrorTracker.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filtering/ConfigErrorTracker.java
new file mode 100644
index 000000000000..c973dc80778c
--- /dev/null
+++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filtering/ConfigErrorTracker.java
@@ -0,0 +1,56 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+package com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.filtering;
+
+import com.azure.core.util.logging.ClientLogger;
+import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.CollectionConfigurationError;
+import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.CollectionConfigurationErrorType;
+import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.KeyValuePairString;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ConfigErrorTracker {
+ private final List errors = new ArrayList<>();
+
+ private static final ClientLogger LOGGER = new ClientLogger(ConfigErrorTracker.class);
+
+ public void addError(String message, String eTag, String id, boolean isDerivedMetricId) {
+ CollectionConfigurationError error = new CollectionConfigurationError();
+ error.setMessage(message);
+ error.setCollectionConfigurationErrorType(setErrorType(message));
+
+ KeyValuePairString keyValuePair1 = new KeyValuePairString();
+ keyValuePair1.setKey("ETag");
+ keyValuePair1.setValue(eTag);
+
+ KeyValuePairString keyValuePair2 = new KeyValuePairString();
+ keyValuePair2.setKey(isDerivedMetricId ? "DerivedMetricInfoId" : "DocumentStreamInfoId");
+ keyValuePair2.setValue(id);
+
+ List data = new ArrayList<>();
+ data.add(keyValuePair1);
+ data.add(keyValuePair2);
+
+ error.setData(data);
+
+ errors.add(error);
+ // This message gets logged once for every error we see on config validation. Config validation
+ // only happens once per config change.
+ LOGGER.verbose("{}. Due to this misconfiguration the {} rule with id {} will be ignored by the SDK.", message,
+ isDerivedMetricId ? "derived metric" : "document filter conjunction", id);
+ }
+
+ private CollectionConfigurationErrorType setErrorType(String message) {
+ if (message.contains("telemetry type")) {
+ return CollectionConfigurationErrorType.METRIC_TELEMETRY_TYPE_UNSUPPORTED;
+ } else if (message.contains("duplicate metric id")) {
+ return CollectionConfigurationErrorType.METRIC_DUPLICATE_IDS;
+ }
+ return CollectionConfigurationErrorType.FILTER_FAILURE_TO_CREATE_UNEXPECTED;
+ }
+
+ public List getErrors() {
+ return new ArrayList<>(errors);
+ }
+}
diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filtering/CustomDimensions.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filtering/CustomDimensions.java
index 6d90d17f1baa..ee5cc5781675 100644
--- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filtering/CustomDimensions.java
+++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filtering/CustomDimensions.java
@@ -2,6 +2,7 @@
// Licensed under the MIT License.
package com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.filtering;
+import com.azure.core.util.logging.ClientLogger;
import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.FilterInfo;
import java.util.HashMap;
@@ -9,6 +10,7 @@
public class CustomDimensions {
private final Map customDimensions;
+ private static final ClientLogger LOGGER = new ClientLogger(CustomDimensions.class);
public CustomDimensions(Map customDimensions, Map customMeasurements) {
Map resultMap = new HashMap<>();
@@ -47,9 +49,14 @@ public double getCustomDimValueForProjection(String key) {
try {
return Double.parseDouble(value);
} catch (NumberFormatException e) {
-
+ LOGGER.verbose(
+ "The value \"{}\" for the custom dimension \"{}\" could not be converted to a numeric value for a derived metric projection",
+ value, key);
}
+ return Double.NaN;
}
+ LOGGER.verbose(
+ "The custom dimension could not be found in this telemetry item when calculating a derived metric.");
return Double.NaN;
}
diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filtering/DependencyDataColumns.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filtering/DependencyDataColumns.java
index 896a84f63a23..84e22b60f47d 100644
--- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filtering/DependencyDataColumns.java
+++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filtering/DependencyDataColumns.java
@@ -3,6 +3,7 @@
package com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.filtering;
+import com.azure.core.util.logging.ClientLogger;
import com.azure.monitor.opentelemetry.autoconfigure.implementation.models.RemoteDependencyData;
import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.FilterInfo;
import com.azure.monitor.opentelemetry.autoconfigure.implementation.utils.FormattedDuration;
@@ -15,17 +16,26 @@ public class DependencyDataColumns implements TelemetryColumns {
private final CustomDimensions customDims;
private final Map mapping = new HashMap<>();
+ private static final ClientLogger LOGGER = new ClientLogger(DependencyDataColumns.class);
+
public DependencyDataColumns(RemoteDependencyData rdData) {
customDims = new CustomDimensions(rdData.getProperties(), rdData.getMeasurements());
mapping.put(KnownDependencyColumns.TARGET, rdData.getTarget());
- mapping.put(KnownDependencyColumns.DURATION,
- FormattedDuration.getDurationFromTelemetryItemDurationString(rdData.getDuration()));
+
+ long durationMicroSec = FormattedDuration.getDurationFromTelemetryItemDurationString(rdData.getDuration());
+ if (durationMicroSec == -1) {
+ LOGGER.verbose("The provided timestamp {} could not be converted to microseconds", rdData.getDuration());
+ }
+ mapping.put(KnownDependencyColumns.DURATION, durationMicroSec);
+
mapping.put(KnownDependencyColumns.SUCCESS, rdData.isSuccess());
mapping.put(KnownDependencyColumns.NAME, rdData.getName());
int resultCode;
try {
resultCode = Integer.parseInt(rdData.getResultCode());
} catch (NumberFormatException e) {
+ LOGGER.verbose("The provided result code {} could not be converted to a numeric value",
+ rdData.getResultCode());
resultCode = -1;
}
mapping.put(KnownDependencyColumns.RESULT_CODE, resultCode);
diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filtering/DerivedMetricProjections.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filtering/DerivedMetricProjections.java
index fb9efa6253b9..9c341ce12a6b 100644
--- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filtering/DerivedMetricProjections.java
+++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filtering/DerivedMetricProjections.java
@@ -3,6 +3,7 @@
package com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.filtering;
+import com.azure.core.util.logging.ClientLogger;
import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.AggregationType;
import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.DerivedMetricInfo;
@@ -14,6 +15,8 @@ public class DerivedMetricProjections {
public static final String COUNT = "Count()";
private final Map derivedMetricValues = new HashMap<>();
+ private static final ClientLogger LOGGER = new ClientLogger(DerivedMetricProjections.class);
+
public DerivedMetricProjections(Map projectionInfo) {
for (Map.Entry entry : projectionInfo.entrySet()) {
AggregationType aggregationType = entry.getValue();
@@ -61,7 +64,10 @@ public void calculateProjection(DerivedMetricInfo derivedMetricInfo, TelemetryCo
// For now, such cases produce Double.Nan and get skipped when calculating projection.
}
- if (!Double.isNaN(incrementBy)) {
+ if (Double.isNaN(incrementBy)) {
+ LOGGER.verbose(
+ "This telemetry item will not be counted in derived metric projections because the Duration or a CustomDimension column could not be interpreted as a numeric value.");
+ } else {
calculateAggregation(derivedMetricInfo.getId(), incrementBy);
}
}
diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filtering/FilteringConfiguration.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filtering/FilteringConfiguration.java
index 2b621bb4c398..1fe643ed1485 100644
--- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filtering/FilteringConfiguration.java
+++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filtering/FilteringConfiguration.java
@@ -2,6 +2,7 @@
// Licensed under the MIT License.
package com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.filtering;
+import com.azure.core.util.logging.ClientLogger;
import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.DerivedMetricInfo;
import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.FilterConjunctionGroupInfo;
import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.CollectionConfigurationInfo;
@@ -9,7 +10,7 @@
import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.DocumentFilterConjunctionGroupInfo;
import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.AggregationType;
import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.TelemetryType;
-import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.CollectionConfigurationErrorType;
+import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.CollectionConfigurationError;
import java.util.Set;
import java.util.List;
@@ -17,6 +18,7 @@
import java.util.Map;
import java.util.HashSet;
import java.util.HashMap;
+import java.util.Optional;
public class FilteringConfiguration {
@@ -33,14 +35,22 @@ public class FilteringConfiguration {
private final Validator validator = new Validator();
+ private final ConfigErrorTracker errorTracker = new ConfigErrorTracker();
+
+ private static final ClientLogger logger = new ClientLogger(FilteringConfiguration.class);
+
public FilteringConfiguration() {
validDerivedMetricInfos = new HashMap<>();
validDocumentFilterConjunctionGroupInfos = new HashMap<>();
etag = "";
validProjectionInfo = new HashMap<>();
+ logger.verbose(
+ "Initializing an empty live metrics filtering configuration - did not yet receive a configuration from ping or post.");
}
public FilteringConfiguration(CollectionConfigurationInfo configuration) {
+ logger.verbose("About to parse and validate a new live metrics filtering configuration with etag {}",
+ configuration.getETag());
validDerivedMetricInfos = parseMetricFilterConfiguration(configuration);
validDocumentFilterConjunctionGroupInfos = parseDocumentFilterConfiguration(configuration);
etag = configuration.getETag();
@@ -73,6 +83,10 @@ public Map getValidProjectionInitInfo() {
return new HashMap<>(validProjectionInfo);
}
+ public List getErrors() {
+ return errorTracker.getErrors();
+ }
+
private Map>>
parseDocumentFilterConfiguration(CollectionConfigurationInfo configuration) {
Map>> result = new HashMap<>();
@@ -82,7 +96,13 @@ public Map getValidProjectionInitInfo() {
.getDocumentFilterGroups()) {
TelemetryType telemetryType = documentFilterGroupInfo.getTelemetryType();
FilterConjunctionGroupInfo filterGroup = documentFilterGroupInfo.getFilters();
- if (validator.isValidDocConjunctionGroupInfo(documentFilterGroupInfo)) {
+
+ Optional docFilterGroupError
+ = validator.validateDocConjunctionGroupInfo(documentFilterGroupInfo);
+
+ if (docFilterGroupError.isPresent()) {
+ errorTracker.addError(docFilterGroupError.get(), configuration.getETag(), documentStreamId, false);
+ } else { // passed validation, store valid docFilterGroupInfo
if (!result.containsKey(telemetryType)) {
result.put(telemetryType, new HashMap<>());
}
@@ -96,6 +116,7 @@ public Map getValidProjectionInitInfo() {
innerMap.put(documentStreamId, filterGroups);
}
}
+
}
}
return result;
@@ -111,7 +132,11 @@ public Map getValidProjectionInitInfo() {
if (!seenMetricIds.contains(id)) {
seenMetricIds.add(id);
- if (validator.isValidDerivedMetricInfo(derivedMetricInfo)) {
+ Optional dmiError = validator.validateDerivedMetricInfo(derivedMetricInfo);
+ if (dmiError.isPresent()) {
+ errorTracker.addError(dmiError.get(), configuration.getETag(), id, true);
+
+ } else { // validation passed, store valid dmi
if (result.containsKey(telemetryType)) {
result.get(telemetryType).add(derivedMetricInfo);
} else {
@@ -121,9 +146,8 @@ public Map getValidProjectionInitInfo() {
}
}
} else {
- validator.constructAndTrackCollectionConfigurationError(
- CollectionConfigurationErrorType.METRIC_DUPLICATE_IDS,
- "A duplicate metric id was found in this configuration", configuration.getETag(), id, true);
+ errorTracker.addError("A duplicate metric id was found in this configuration", configuration.getETag(),
+ id, true);
}
}
diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filtering/RequestDataColumns.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filtering/RequestDataColumns.java
index d575d945c1ac..cfa30b9edd70 100644
--- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filtering/RequestDataColumns.java
+++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filtering/RequestDataColumns.java
@@ -3,6 +3,7 @@
package com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.filtering;
+import com.azure.core.util.logging.ClientLogger;
import com.azure.monitor.opentelemetry.autoconfigure.implementation.models.RequestData;
import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.FilterInfo;
import com.azure.monitor.opentelemetry.autoconfigure.implementation.utils.FormattedDuration;
@@ -16,18 +17,28 @@ public class RequestDataColumns implements TelemetryColumns {
private final Map mapping = new HashMap<>();
private final CustomDimensions customDims;
+ private static final ClientLogger LOGGER = new ClientLogger(RequestDataColumns.class);
+
public RequestDataColumns(RequestData requestData) {
customDims = new CustomDimensions(requestData.getProperties(), requestData.getMeasurements());
mapping.put(KnownRequestColumns.URL, requestData.getUrl());
mapping.put(KnownRequestColumns.SUCCESS, requestData.isSuccess());
- mapping.put(KnownRequestColumns.DURATION,
- FormattedDuration.getDurationFromTelemetryItemDurationString(requestData.getDuration()));
+
+ long durationMicroSec = FormattedDuration.getDurationFromTelemetryItemDurationString(requestData.getDuration());
+ if (durationMicroSec == -1) {
+ LOGGER.verbose("The provided timestamp {} could not be converted to microseconds",
+ requestData.getDuration());
+ }
+
+ mapping.put(KnownRequestColumns.DURATION, durationMicroSec);
mapping.put(KnownRequestColumns.NAME, requestData.getName());
int responseCode;
try {
responseCode = Integer.parseInt(requestData.getResponseCode());
} catch (NumberFormatException e) {
responseCode = -1;
+ LOGGER.verbose("The provided response code {} could not be converted to a numeric value",
+ requestData.getResponseCode());
}
mapping.put(KnownRequestColumns.RESPONSE_CODE, responseCode);
}
diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filtering/Validator.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filtering/Validator.java
index c73b0097a52f..b863191d1df0 100644
--- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filtering/Validator.java
+++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/main/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filtering/Validator.java
@@ -8,14 +8,10 @@
import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.FilterConjunctionGroupInfo;
import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.DocumentFilterConjunctionGroupInfo;
import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.FilterInfo;
-import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.CollectionConfigurationError;
-import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.CollectionConfigurationErrorType;
-import com.azure.monitor.opentelemetry.autoconfigure.implementation.quickpulse.swagger.models.KeyValuePairString;
-import java.util.ArrayList;
import java.util.HashSet;
-import java.util.List;
import java.util.Set;
+import java.util.Optional;
import static java.util.Arrays.asList;
@@ -31,77 +27,63 @@ public class Validator {
private final Set validStringPredicates = new HashSet<>(
asList(PredicateType.CONTAINS, PredicateType.DOES_NOT_CONTAIN, PredicateType.EQUAL, PredicateType.NOT_EQUAL));
- // TODO (harskaur): In ErrorTracker PR, track a list of configuration validation errors here
- private final List errors = new ArrayList<>();
-
- public boolean isValidDerivedMetricInfo(DerivedMetricInfo derivedMetricInfo) {
+ // The string in the return Optional represents an error encountered when validating the derived metric info.
+ // If the Optional is empty, that means validation passed.
+ public Optional validateDerivedMetricInfo(DerivedMetricInfo derivedMetricInfo) {
TelemetryType telemetryType = TelemetryType.fromString(derivedMetricInfo.getTelemetryType());
if (!isValidTelemetryType(telemetryType)) {
- return false;
+ return Optional
+ .of("The user selected a telemetry type that the SDK does not support for Live Metrics Filtering. "
+ + "Telemetry type: " + telemetryType);
}
if (!isNotCustomMetricProjection(derivedMetricInfo.getProjection())) {
- return false;
+ return Optional.of("The user selected a projection of Custom Metric, which this SDK does not support.");
}
for (FilterConjunctionGroupInfo conjunctionGroupInfo : derivedMetricInfo.getFilterGroups()) {
for (FilterInfo filter : conjunctionGroupInfo.getFilters()) {
- if (!isValidFieldName(filter.getFieldName(), telemetryType)) {
- return false;
+ Optional error = validateFieldName(filter.getFieldName());
+ if (error.isPresent()) {
+ return error;
}
- if (!isValidPredicateAndComparand(filter)) {
- return false;
+
+ error = validatePredicateAndComparand(filter);
+ if (error.isPresent()) {
+ return error;
}
}
}
- return true;
+ return Optional.empty();
}
- public boolean
- isValidDocConjunctionGroupInfo(DocumentFilterConjunctionGroupInfo documentFilterConjunctionGroupInfo) {
+ // The string in the return Optional represents an error encountered when validating the DocumentFilterConjunctionGroupInfo.
+ // If the Optional is empty, that means validation passed.
+ public Optional
+ validateDocConjunctionGroupInfo(DocumentFilterConjunctionGroupInfo documentFilterConjunctionGroupInfo) {
TelemetryType telemetryType = documentFilterConjunctionGroupInfo.getTelemetryType();
if (!isValidTelemetryType(telemetryType)) {
- return false;
+ return Optional
+ .of("The user selected a telemetry type that the SDK does not support for Live Metrics Filtering. "
+ + "Telemetry type: " + telemetryType);
}
FilterConjunctionGroupInfo conjunctionGroupInfo = documentFilterConjunctionGroupInfo.getFilters();
for (FilterInfo filter : conjunctionGroupInfo.getFilters()) {
- if (!isValidFieldName(filter.getFieldName(), telemetryType)) {
- return false;
+ Optional error = validateFieldName(filter.getFieldName());
+ if (error.isPresent()) {
+ return error;
}
- if (!isValidPredicateAndComparand(filter)) {
- return false;
+
+ error = validatePredicateAndComparand(filter);
+ if (error.isPresent()) {
+ return error;
}
}
- return true;
- }
-
- public void constructAndTrackCollectionConfigurationError(CollectionConfigurationErrorType errorType,
- String message, String eTag, String id, boolean isDerivedMetricId) {
- CollectionConfigurationError error = new CollectionConfigurationError();
- error.setMessage(message);
- error.setCollectionConfigurationErrorType(errorType);
-
- KeyValuePairString keyValuePair1 = new KeyValuePairString();
- keyValuePair1.setKey("ETag");
- keyValuePair1.setValue(eTag);
-
- KeyValuePairString keyValuePair2 = new KeyValuePairString();
- keyValuePair2.setKey(isDerivedMetricId ? "DerivedMetricInfoId" : "DocumentStreamInfoId");
- keyValuePair2.setValue(id);
-
- List data = new ArrayList<>();
- data.add(keyValuePair1);
- data.add(keyValuePair2);
-
- error.setData(data);
-
- // TODO (harskaur): For ErrorTracker PR, add this error to list of tracked errors
- errors.add(error);
+ return Optional.empty();
}
private boolean isValidTelemetryType(TelemetryType telemetryType) {
- // TODO (harskaur): In ErrorTracker PR, create an error message & track an error for each false case
if (telemetryType.equals(TelemetryType.PERFORMANCE_COUNTER)) {
return false;
} else if (telemetryType.equals(TelemetryType.EVENT)) {
@@ -115,46 +97,53 @@ private boolean isValidTelemetryType(TelemetryType telemetryType) {
private boolean isNotCustomMetricProjection(String projection) {
if (projection.startsWith("CustomMetrics.")) {
- // TODO (harskaur): In ErrorTracker PR, create an error message & track an error for this case
return false;
}
return true;
}
- private boolean isValidFieldName(String fieldName, TelemetryType telemetryType) {
- // TODO (harskaur): In ErrorTracker PR, create an error message & track an error for each false case
+ // The string in the return Optional represents an error encountered when validating the field name.
+ // If the Optional is empty, that means validation passed.
+ private Optional validateFieldName(String fieldName) {
if (fieldName.isEmpty()) {
- return false;
+ return Optional.of("The user specified an empty field name for a filter.");
}
if (fieldName.startsWith("CustomMetrics.")) {
- return false;
+ return Optional.of(
+ "The user selected a custom metric field name, but this SDK does not support filtering of custom metrics.");
}
- return true;
+ return Optional.empty();
}
- private boolean isValidPredicateAndComparand(FilterInfo filter) {
- // TODO (harskaur): In ErrorTracker PR, create an error message & track an error for each false case
+ // The string in the return Optional represents an error encountered when validating the predicate/comparand.
+ // If the Optional is empty, that means validation passed.
+ private Optional validatePredicateAndComparand(FilterInfo filter) {
if (filter.getComparand().isEmpty()) {
// It is possible to not type in a comparand and the service side to send us empty string.
- return false;
+ return Optional.of("The user specified an empty comparand value for a filter.");
} else if (Filter.ANY_FIELD.equals(filter.getFieldName())
&& !(filter.getPredicate().equals(PredicateType.CONTAINS)
|| filter.getPredicate().equals(PredicateType.DOES_NOT_CONTAIN))) {
// While the UI allows != and == for the ANY_FIELD fieldName, .net classic code only allows contains/not contains & the spec follows
// .net classic behavior for this particular condition.
- return false;
+ return Optional.of("The specified predicate is not supported for the fieldName * (Any field): "
+ + filter.getPredicate().getValue());
} else if (knownNumericColumns.contains(filter.getFieldName())) {
// Just in case a strange timestamp value is passed from the service side. The service side should send a duration with a specific
// format ([days].[hours]:[minutes]:[seconds] - the seconds may be a whole number or something like 7.89).
if (KnownDependencyColumns.DURATION.equals(filter.getFieldName())) {
if (Filter.getMicroSecondsFromFilterTimestampString(filter.getComparand()) == Long.MIN_VALUE) {
- return false;
+ return Optional
+ .of("The duration string provided by the user could not be parsed to a numeric value: "
+ + filter.getComparand());
}
} else { // The service side not does not validate if resultcode or responsecode is a numeric value
try {
Long.parseLong(filter.getComparand());
} catch (NumberFormatException e) {
- return false;
+ return Optional
+ .of("The result/response code specified by the user did not parse to a numeric value: "
+ + filter.getComparand());
}
}
} else if (knownStringColumns.contains(filter.getFieldName())
@@ -162,9 +151,10 @@ private boolean isValidPredicateAndComparand(FilterInfo filter) {
// While the UI allows a user to select any predicate for a custom dimension filter, .net classic treats all custom dimensions like
// String values. therefore we validate for predicates applicable to String. This is called out in the spec as well.
if (!validStringPredicates.contains(filter.getPredicate())) {
- return false;
+ return Optional.of("The user selected a predicate (" + filter.getPredicate().getValue()
+ + ") that is not supported for the field name " + filter.getFieldName());
}
}
- return true;
+ return Optional.empty();
}
}
diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/QuickPulseDataCollectorTests.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/QuickPulseDataCollectorTests.java
index e97835cfc13b..aa28c718bdb9 100644
--- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/QuickPulseDataCollectorTests.java
+++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/QuickPulseDataCollectorTests.java
@@ -253,6 +253,14 @@ void honorDefaultConfig() {
createTelemetryItemsForFiltering(collector);
QuickPulseDataCollector.FinalCounters counters = collector.peek();
+
+ // The default documents config asks to collect documents of the "Event" telemetry type
+ // As the SDK does not collect the Event telemetry type for live metrics, we consider that part of the config invalid
+ List errors = counters.configErrors;
+ assertThat(errors.size()).isEqualTo(1);
+ assertThat(errors.get(0).getCollectionConfigurationErrorType())
+ .isEqualTo(CollectionConfigurationErrorType.METRIC_TELEMETRY_TYPE_UNSUPPORTED);
+
List documents = counters.documentList;
assertThat(documents.size()).isEqualTo(4);
diff --git a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filteringTest/ValidatorTests.java b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filteringTest/ValidatorTests.java
index d1b0f75adee2..e79a79355264 100644
--- a/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filteringTest/ValidatorTests.java
+++ b/sdk/monitor/azure-monitor-opentelemetry-autoconfigure/src/test/java/com/azure/monitor/opentelemetry/autoconfigure/implementation/quickpulse/filteringTest/ValidatorTests.java
@@ -27,9 +27,7 @@ void rejectInvalidTelemetryTypesForDmi(TelemetryType telemetryType) {
List filterGroups = createListWithOneFilterConjunctionGroupAndNoFilters();
DerivedMetricInfo dmi = createDerivedMetricInfo("random-id", telemetryType.getValue(), AggregationType.SUM,
AggregationType.SUM, DerivedMetricProjections.COUNT, filterGroups);
- assertFalse(validator.isValidDerivedMetricInfo(dmi));
- DocumentFilterConjunctionGroupInfo docGroup = createDocGroupWithNoFilters(telemetryType);
- assertFalse(validator.isValidDocConjunctionGroupInfo(docGroup));
+ assertTrue(validator.validateDerivedMetricInfo(dmi).isPresent());
}
@ParameterizedTest
@@ -37,7 +35,7 @@ void rejectInvalidTelemetryTypesForDmi(TelemetryType telemetryType) {
void rejectInvalidTelemetryTypesForDocs(TelemetryType telemetryType) {
Validator validator = new Validator();
DocumentFilterConjunctionGroupInfo docGroup = createDocGroupWithNoFilters(telemetryType);
- assertFalse(validator.isValidDocConjunctionGroupInfo(docGroup));
+ assertTrue(validator.validateDocConjunctionGroupInfo(docGroup).isPresent());
}
@ParameterizedTest
@@ -47,9 +45,7 @@ void acceptValidTelemetryTypeForDmi(TelemetryType telemetryType) {
List filterGroups = createListWithOneFilterConjunctionGroupAndNoFilters();
DerivedMetricInfo dmi = createDerivedMetricInfo("random-id", telemetryType.getValue(), AggregationType.SUM,
AggregationType.SUM, DerivedMetricProjections.COUNT, filterGroups);
- assertTrue(validator.isValidDerivedMetricInfo(dmi));
- DocumentFilterConjunctionGroupInfo docGroup = createDocGroupWithNoFilters(telemetryType);
- assertTrue(validator.isValidDocConjunctionGroupInfo(docGroup));
+ assertFalse(validator.validateDerivedMetricInfo(dmi).isPresent());
}
@ParameterizedTest
@@ -57,7 +53,7 @@ void acceptValidTelemetryTypeForDmi(TelemetryType telemetryType) {
void acceptValidTelemetryTypeForDocs(TelemetryType telemetryType) {
Validator validator = new Validator();
DocumentFilterConjunctionGroupInfo docGroup = createDocGroupWithNoFilters(telemetryType);
- assertTrue(validator.isValidDocConjunctionGroupInfo(docGroup));
+ assertFalse(validator.validateDocConjunctionGroupInfo(docGroup).isPresent());
}
@Test
@@ -66,7 +62,7 @@ void rejectCustomMetricProjection() {
Validator validator = new Validator();
DerivedMetricInfo dmi = createDerivedMetricInfo("random-id", TelemetryType.TRACE.getValue(),
AggregationType.SUM, AggregationType.SUM, "CustomMetrics.property", filterGroups);
- assertFalse(validator.isValidDerivedMetricInfo(dmi));
+ assertTrue(validator.validateDerivedMetricInfo(dmi).isPresent());
}
@Test
@@ -76,7 +72,7 @@ void rejectCustomMetricFieldName() {
Validator validator = new Validator();
DerivedMetricInfo dmi = createDerivedMetricInfo("random-id", TelemetryType.TRACE.getValue(),
AggregationType.SUM, AggregationType.SUM, DerivedMetricProjections.COUNT, filterGroups);
- assertFalse(validator.isValidDerivedMetricInfo(dmi));
+ assertTrue(validator.validateDerivedMetricInfo(dmi).isPresent());
}
@ParameterizedTest
@@ -86,10 +82,7 @@ void rejectInvalidFiltersForDmi(FilterInfo filter) {
DerivedMetricInfo dmi = createDerivedMetricInfo("random-id", TelemetryType.REQUEST.getValue(),
AggregationType.SUM, AggregationType.SUM, DerivedMetricProjections.COUNT, filterGroups);
Validator validator = new Validator();
- assertFalse(validator.isValidDerivedMetricInfo(dmi));
-
- DocumentFilterConjunctionGroupInfo docGroup = createDocGroupWithOneFilter(TelemetryType.REQUEST, filter);
- assertFalse(validator.isValidDocConjunctionGroupInfo(docGroup));
+ assertTrue(validator.validateDerivedMetricInfo(dmi).isPresent());
}
@ParameterizedTest
@@ -97,7 +90,7 @@ void rejectInvalidFiltersForDmi(FilterInfo filter) {
void rejectInvalidFiltersForDocs(FilterInfo filter) {
Validator validator = new Validator();
DocumentFilterConjunctionGroupInfo docGroup = createDocGroupWithOneFilter(TelemetryType.REQUEST, filter);
- assertFalse(validator.isValidDocConjunctionGroupInfo(docGroup));
+ assertTrue(validator.validateDocConjunctionGroupInfo(docGroup).isPresent());
}
@Test
@@ -114,12 +107,12 @@ void rejectInvalidGroupWithMultipleFilters() {
DerivedMetricInfo dmi = createDerivedMetricInfo("random-id", TelemetryType.REQUEST.getValue(),
AggregationType.SUM, AggregationType.SUM, DerivedMetricProjections.COUNT, filterGroups);
- assertFalse(validator.isValidDerivedMetricInfo(dmi));
+ assertTrue(validator.validateDerivedMetricInfo(dmi).isPresent());
DocumentFilterConjunctionGroupInfo docGroup = new DocumentFilterConjunctionGroupInfo();
docGroup.setFilters(filterGroup);
docGroup.setTelemetryType(TelemetryType.REQUEST);
- assertFalse(validator.isValidDocConjunctionGroupInfo(docGroup));
+ assertTrue(validator.validateDocConjunctionGroupInfo(docGroup).isPresent());
}
@ParameterizedTest
@@ -129,10 +122,7 @@ void acceptValidFiltersForDmi(FilterInfo filter) {
DerivedMetricInfo dmi = createDerivedMetricInfo("random-id", TelemetryType.REQUEST.getValue(),
AggregationType.SUM, AggregationType.SUM, DerivedMetricProjections.COUNT, filterGroups);
Validator validator = new Validator();
- assertTrue(validator.isValidDerivedMetricInfo(dmi));
-
- DocumentFilterConjunctionGroupInfo docGroup = createDocGroupWithOneFilter(TelemetryType.REQUEST, filter);
- assertTrue(validator.isValidDocConjunctionGroupInfo(docGroup));
+ assertFalse(validator.validateDerivedMetricInfo(dmi).isPresent());
}
@ParameterizedTest
@@ -140,7 +130,7 @@ void acceptValidFiltersForDmi(FilterInfo filter) {
void acceptValidFiltersForDocs(FilterInfo filter) {
Validator validator = new Validator();
DocumentFilterConjunctionGroupInfo docGroup = createDocGroupWithOneFilter(TelemetryType.REQUEST, filter);
- assertTrue(validator.isValidDocConjunctionGroupInfo(docGroup));
+ assertFalse(validator.validateDocConjunctionGroupInfo(docGroup).isPresent());
}
private static List invalidTelemetryTypes() {