diff --git a/api/src/main/java/io/opentelemetry/internal/StringUtils.java b/api/src/main/java/io/opentelemetry/internal/StringUtils.java index 1d8141767d..8679f55ecf 100644 --- a/api/src/main/java/io/opentelemetry/internal/StringUtils.java +++ b/api/src/main/java/io/opentelemetry/internal/StringUtils.java @@ -45,5 +45,19 @@ public final class StringUtils { return value == null || value.length() == 0; } + /** + * Determines whether the metric name contains a valid metric name. + * + * @param metricName the metric name to be validated. + * @return whether the metricName contains a valid name. + */ + public static boolean isValidMetricName(String metricName) { + if (metricName.isEmpty()) { + return false; + } + String pattern = "[aA-zZ][aA-zZ0-9_\\-.]*"; + return metricName.matches(pattern); + } + private StringUtils() {} } diff --git a/api/src/main/java/io/opentelemetry/metrics/DefaultMeter.java b/api/src/main/java/io/opentelemetry/metrics/DefaultMeter.java index 26df992293..aa494861ec 100644 --- a/api/src/main/java/io/opentelemetry/metrics/DefaultMeter.java +++ b/api/src/main/java/io/opentelemetry/metrics/DefaultMeter.java @@ -51,7 +51,7 @@ public final class DefaultMeter implements Meter { public DoubleCounter.Builder doubleCounterBuilder(String name) { Utils.checkNotNull(name, "name"); Utils.checkArgument( - StringUtils.isPrintableString(name) && name.length() <= NAME_MAX_LENGTH, + StringUtils.isValidMetricName(name) && name.length() <= NAME_MAX_LENGTH, ERROR_MESSAGE_INVALID_NAME); return new NoopDoubleCounter.NoopBuilder(); } @@ -60,7 +60,7 @@ public final class DefaultMeter implements Meter { public LongCounter.Builder longCounterBuilder(String name) { Utils.checkNotNull(name, "name"); Utils.checkArgument( - StringUtils.isPrintableString(name) && name.length() <= NAME_MAX_LENGTH, + StringUtils.isValidMetricName(name) && name.length() <= NAME_MAX_LENGTH, ERROR_MESSAGE_INVALID_NAME); return new NoopLongCounter.NoopBuilder(); } @@ -69,7 +69,7 @@ public final class DefaultMeter implements Meter { public DoubleMeasure.Builder doubleMeasureBuilder(String name) { Utils.checkNotNull(name, "name"); Utils.checkArgument( - StringUtils.isPrintableString(name) && name.length() <= NAME_MAX_LENGTH, + StringUtils.isValidMetricName(name) && name.length() <= NAME_MAX_LENGTH, ERROR_MESSAGE_INVALID_NAME); return new NoopDoubleMeasure.NoopBuilder(); } @@ -78,7 +78,7 @@ public final class DefaultMeter implements Meter { public LongMeasure.Builder longMeasureBuilder(String name) { Utils.checkNotNull(name, "name"); Utils.checkArgument( - StringUtils.isPrintableString(name) && name.length() <= NAME_MAX_LENGTH, + StringUtils.isValidMetricName(name) && name.length() <= NAME_MAX_LENGTH, ERROR_MESSAGE_INVALID_NAME); return new NoopLongMeasure.NoopBuilder(); } @@ -87,7 +87,7 @@ public final class DefaultMeter implements Meter { public DoubleObserver.Builder doubleObserverBuilder(String name) { Utils.checkNotNull(name, "name"); Utils.checkArgument( - StringUtils.isPrintableString(name) && name.length() <= NAME_MAX_LENGTH, + StringUtils.isValidMetricName(name) && name.length() <= NAME_MAX_LENGTH, ERROR_MESSAGE_INVALID_NAME); return new NoopDoubleObserver.NoopBuilder(); } @@ -96,7 +96,7 @@ public final class DefaultMeter implements Meter { public LongObserver.Builder longObserverBuilder(String name) { Utils.checkNotNull(name, "name"); Utils.checkArgument( - StringUtils.isPrintableString(name) && name.length() <= NAME_MAX_LENGTH, + StringUtils.isValidMetricName(name) && name.length() <= NAME_MAX_LENGTH, ERROR_MESSAGE_INVALID_NAME); return new NoopLongObserver.NoopBuilder(); } diff --git a/api/src/test/java/io/opentelemetry/metrics/DefaultMeterTest.java b/api/src/test/java/io/opentelemetry/metrics/DefaultMeterTest.java index 591807265f..ff26db3a9d 100644 --- a/api/src/test/java/io/opentelemetry/metrics/DefaultMeterTest.java +++ b/api/src/test/java/io/opentelemetry/metrics/DefaultMeterTest.java @@ -56,6 +56,48 @@ public final class DefaultMeterTest { defaultMeter.longMeasureBuilder(null); } + @Test + public void noopAddDoubleCumulative_EmptyName() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Name"); + defaultMeter.doubleCounterBuilder(""); + } + + @Test + public void noopAddLongCumulative_EmptyName() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Name"); + defaultMeter.longCounterBuilder(""); + } + + @Test + public void noopAddMeasureDouble_EmptyName() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Name"); + defaultMeter.doubleMeasureBuilder(""); + } + + @Test + public void noopAddMeasureLong_EmptyName() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Name"); + defaultMeter.longMeasureBuilder(""); + } + + @Test + public void noopAddObserverDouble_EmptyName() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Name"); + defaultMeter.doubleObserverBuilder(""); + } + + @Test + public void noopAddObserverLong_EmptyName() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Name"); + defaultMeter.longObserverBuilder(""); + } + @Test public void testVarargsLabelSetValidation_UnmatchedKeysAndValues() throws Exception { thrown.expect(IllegalArgumentException.class); diff --git a/sdk/src/main/java/io/opentelemetry/sdk/metrics/AbstractInstrumentBuilder.java b/sdk/src/main/java/io/opentelemetry/sdk/metrics/AbstractInstrumentBuilder.java index 514cb2fe2e..4bc2545c7d 100644 --- a/sdk/src/main/java/io/opentelemetry/sdk/metrics/AbstractInstrumentBuilder.java +++ b/sdk/src/main/java/io/opentelemetry/sdk/metrics/AbstractInstrumentBuilder.java @@ -48,7 +48,7 @@ abstract class AbstractInstrumentBuilder, V> InstrumentationLibraryInfo instrumentationLibraryInfo) { Utils.checkNotNull(name, "name"); Utils.checkArgument( - StringUtils.isPrintableString(name) && name.length() <= NAME_MAX_LENGTH, + StringUtils.isValidMetricName(name) && name.length() <= NAME_MAX_LENGTH, ERROR_MESSAGE_INVALID_NAME); this.name = name; this.meterSharedState = meterSharedState; diff --git a/sdk/src/test/java/io/opentelemetry/sdk/metrics/AbstractInstrumentBuilderTest.java b/sdk/src/test/java/io/opentelemetry/sdk/metrics/AbstractInstrumentBuilderTest.java index 37a12c6fa7..cb6528aded 100644 --- a/sdk/src/test/java/io/opentelemetry/sdk/metrics/AbstractInstrumentBuilderTest.java +++ b/sdk/src/test/java/io/opentelemetry/sdk/metrics/AbstractInstrumentBuilderTest.java @@ -55,6 +55,25 @@ public class AbstractInstrumentBuilderTest { new TestInstrumentBuilder(null, METER_SHARED_STATE, INSTRUMENTATION_LIBRARY_INFO); } + @Test + public void preventEmpty_Name() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Name"); + new TestInstrumentBuilder("", METER_SHARED_STATE, INSTRUMENTATION_LIBRARY_INFO); + } + + @Test + public void checkCorrect_Name() { + new TestInstrumentBuilder("a", METER_SHARED_STATE, INSTRUMENTATION_LIBRARY_INFO); + new TestInstrumentBuilder("METRIC_name", METER_SHARED_STATE, INSTRUMENTATION_LIBRARY_INFO); + new TestInstrumentBuilder("metric.name_01", METER_SHARED_STATE, INSTRUMENTATION_LIBRARY_INFO); + new TestInstrumentBuilder("metric_name.01", METER_SHARED_STATE, INSTRUMENTATION_LIBRARY_INFO); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Name"); + new TestInstrumentBuilder( + "01.metric_name_01", METER_SHARED_STATE, INSTRUMENTATION_LIBRARY_INFO); + } + @Test public void preventNonPrintableName() { thrown.expect(IllegalArgumentException.class);