diff --git a/micrometer-core/src/main/java/io/micrometer/core/instrument/Tags.java b/micrometer-core/src/main/java/io/micrometer/core/instrument/Tags.java index b82f88f947..1239bd056f 100644 --- a/micrometer-core/src/main/java/io/micrometer/core/instrument/Tags.java +++ b/micrometer-core/src/main/java/io/micrometer/core/instrument/Tags.java @@ -112,7 +112,7 @@ public Tags and(@Nullable Tag... tags) { * @return a new {@code Tags} instance */ public Tags and(@Nullable Iterable tags) { - if (tags == null || !tags.iterator().hasNext()) { + if (tags == null || tags == EMPTY || !tags.iterator().hasNext()) { return this; } @@ -216,7 +216,7 @@ public static Tags concat(@Nullable Iterable tags, @Nullable Stri * @return a new {@code Tags} instance */ public static Tags of(@Nullable Iterable tags) { - if (tags == null || !tags.iterator().hasNext()) { + if (tags == null || tags == EMPTY || !tags.iterator().hasNext()) { return Tags.empty(); } else if (tags instanceof Tags) { diff --git a/micrometer-core/src/test/java/io/micrometer/core/instrument/TagsTest.java b/micrometer-core/src/test/java/io/micrometer/core/instrument/TagsTest.java index e3191e8c59..b943880010 100644 --- a/micrometer-core/src/test/java/io/micrometer/core/instrument/TagsTest.java +++ b/micrometer-core/src/test/java/io/micrometer/core/instrument/TagsTest.java @@ -15,12 +15,13 @@ */ package io.micrometer.core.instrument; +import com.sun.management.ThreadMXBean; +import io.micrometer.core.Issue; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.DisabledIfSystemProperty; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Iterator; +import java.lang.management.ManagementFactory; +import java.util.*; import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; @@ -36,6 +37,9 @@ */ class TagsTest { + // Should match "Eclipse OpenJ9 VM" and "IBM J9 VM" + private static final String JAVA_VM_NAME_J9_REGEX = ".*J9 VM$"; + @Test void dedup() { assertThat(Tags.of("k1", "v1", "k2", "v2")).containsExactly(Tag.of("k1", "v1"), Tag.of("k2", "v2")); @@ -285,6 +289,41 @@ void emptyShouldNotContainTags() { assertThat(Tags.empty().iterator()).isExhausted(); } + @Test + @Issue("#3313") + @DisabledIfSystemProperty(named = "java.vm.name", matches = JAVA_VM_NAME_J9_REGEX, + disabledReason = "Sun ThreadMXBean with allocation counter not available") + void andEmptyDoesNotAllocate() { + ThreadMXBean threadMXBean = (ThreadMXBean) ManagementFactory.getThreadMXBean(); + long currentThreadId = Thread.currentThread().getId(); + Tags tags = Tags.of("a", "b"); + Tags extraTags = Tags.empty(); + + long allocatedBytesBefore = threadMXBean.getThreadAllocatedBytes(currentThreadId); + Tags combined = tags.and(extraTags); + long allocatedBytes = threadMXBean.getThreadAllocatedBytes(currentThreadId) - allocatedBytesBefore; + + assertThat(combined).isEqualTo(tags); + assertThat(allocatedBytes).isZero(); + } + + @Test + @Issue("#3313") + @DisabledIfSystemProperty(named = "java.vm.name", matches = JAVA_VM_NAME_J9_REGEX, + disabledReason = "Sun ThreadMXBean with allocation counter not available") + void ofEmptyDoesNotAllocate() { + ThreadMXBean threadMXBean = (ThreadMXBean) ManagementFactory.getThreadMXBean(); + long currentThreadId = Thread.currentThread().getId(); + Tags extraTags = Tags.empty(); + + long allocatedBytesBefore = threadMXBean.getThreadAllocatedBytes(currentThreadId); + Tags of = Tags.of(extraTags); + long allocatedBytes = threadMXBean.getThreadAllocatedBytes(currentThreadId) - allocatedBytesBefore; + + assertThat(of).isEqualTo(Tags.empty()); + assertThat(allocatedBytes).isZero(); + } + private void assertTags(Tags tags, String... keyValues) { Iterator actual = tags.iterator(); Iterator expected = Arrays.asList(keyValues).iterator();