diff --git a/components/inspectit-ocelot-eum-server/src/main/java/rocks/inspectit/oce/eum/server/metrics/BeaconMetricManager.java b/components/inspectit-ocelot-eum-server/src/main/java/rocks/inspectit/oce/eum/server/metrics/BeaconMetricManager.java index 0696f35086..9a799b14cc 100644 --- a/components/inspectit-ocelot-eum-server/src/main/java/rocks/inspectit/oce/eum/server/metrics/BeaconMetricManager.java +++ b/components/inspectit-ocelot-eum-server/src/main/java/rocks/inspectit/oce/eum/server/metrics/BeaconMetricManager.java @@ -3,7 +3,6 @@ import io.opencensus.common.Scope; import io.opencensus.tags.TagContextBuilder; import io.opencensus.tags.TagKey; -import io.opencensus.tags.TagValue; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -14,6 +13,7 @@ import rocks.inspectit.oce.eum.server.configuration.model.BeaconMetricDefinitionSettings; import rocks.inspectit.oce.eum.server.configuration.model.BeaconRequirement; import rocks.inspectit.oce.eum.server.configuration.model.EumServerConfiguration; +import rocks.inspectit.oce.eum.server.utils.TagUtils; import java.util.HashMap; import java.util.List; @@ -104,7 +104,7 @@ private TagContextBuilder getTagContextForBeacon(Beacon beacon) { TagContextBuilder tagContextBuilder = measuresAndViewsManager.getTagContext(); for (String key : configuration.getTags().getBeacon().keySet()) { if (beacon.contains(key)) { - tagContextBuilder.putLocal(TagKey.create(key), TagValue.create(beacon.get(key))); + tagContextBuilder.putLocal(TagKey.create(key), TagUtils.createTagValue(beacon.get(key))); } } return tagContextBuilder; diff --git a/components/inspectit-ocelot-eum-server/src/main/java/rocks/inspectit/oce/eum/server/metrics/MeasuresAndViewsManager.java b/components/inspectit-ocelot-eum-server/src/main/java/rocks/inspectit/oce/eum/server/metrics/MeasuresAndViewsManager.java index 0029be5fd2..44ac14d62c 100644 --- a/components/inspectit-ocelot-eum-server/src/main/java/rocks/inspectit/oce/eum/server/metrics/MeasuresAndViewsManager.java +++ b/components/inspectit-ocelot-eum-server/src/main/java/rocks/inspectit/oce/eum/server/metrics/MeasuresAndViewsManager.java @@ -3,12 +3,12 @@ import io.opencensus.stats.*; import io.opencensus.tags.TagContextBuilder; import io.opencensus.tags.TagKey; -import io.opencensus.tags.TagValue; import io.opencensus.tags.Tags; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import rocks.inspectit.oce.eum.server.configuration.model.EumServerConfiguration; +import rocks.inspectit.oce.eum.server.utils.TagUtils; import rocks.inspectit.ocelot.config.model.metrics.definition.MetricDefinitionSettings; import rocks.inspectit.ocelot.config.model.metrics.definition.ViewDefinitionSettings; @@ -105,7 +105,6 @@ private void updateViews(String metricName, MetricDefinitionSettings metricDefin /** * Returns all tags, which are exposed for the given metricDefinition - * */ private Set getTagsForView(ViewDefinitionSettings viewDefinitionSettings) { Set tags = new HashSet<>(configuration.getTags().getDefineAsGlobal()); @@ -123,7 +122,7 @@ public TagContextBuilder getTagContext() { TagContextBuilder tagContextBuilder = Tags.getTagger().currentBuilder(); for (Map.Entry extraTag : configuration.getTags().getExtra().entrySet()) { - tagContextBuilder.putLocal(TagKey.create(extraTag.getKey()), TagValue.create(extraTag.getValue())); + tagContextBuilder.putLocal(TagKey.create(extraTag.getKey()), TagUtils.createTagValue(extraTag.getValue())); } return tagContextBuilder; @@ -139,7 +138,7 @@ public TagContextBuilder getTagContext(Map customTags) { TagContextBuilder tagContextBuilder = getTagContext(); for (Map.Entry customTag : customTags.entrySet()) { - tagContextBuilder.putLocal(TagKey.create(customTag.getKey()), TagValue.create(customTag.getValue())); + tagContextBuilder.putLocal(TagKey.create(customTag.getKey()), TagUtils.createTagValue(customTag.getValue())); } return tagContextBuilder; @@ -147,7 +146,6 @@ public TagContextBuilder getTagContext(Map customTags) { /** * Creates an aggregation depending on the given {@link Aggregation} - * */ private static Aggregation createAggregation(ViewDefinitionSettings viewDefinitionSettings) { switch (viewDefinitionSettings.getAggregation()) { diff --git a/components/inspectit-ocelot-eum-server/src/main/java/rocks/inspectit/oce/eum/server/utils/TagUtils.java b/components/inspectit-ocelot-eum-server/src/main/java/rocks/inspectit/oce/eum/server/utils/TagUtils.java new file mode 100644 index 0000000000..f38c1e099d --- /dev/null +++ b/components/inspectit-ocelot-eum-server/src/main/java/rocks/inspectit/oce/eum/server/utils/TagUtils.java @@ -0,0 +1,42 @@ +package rocks.inspectit.oce.eum.server.utils; + +import io.opencensus.internal.StringUtils; +import io.opencensus.tags.TagValue; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public final class TagUtils { + + private static boolean isWarningPrinted = false; + + private TagUtils() { + // empty private default constructor for util class + } + + /** + * Constructs a {@code io.opencensus.tags.TagValue} from the given string. + * If String is not valid an <invalid> TagName is created. + * + * @param v the tag value + * @return the created TagValue with 'v' or '<invalid>' + */ + public static TagValue createTagValue(String v) { + if (isTagValueValid(v)) { + return TagValue.create(v); + } + printWarningOnce(); + return TagValue.create(""); + } + + private static boolean isTagValueValid(String value) { + return value.length() <= TagValue.MAX_LENGTH && StringUtils.isPrintableString(value); + } + + private static void printWarningOnce() { + if (!isWarningPrinted) { + log.warn("illegal tag value converted to "); + isWarningPrinted = true; + } + } + +} diff --git a/components/inspectit-ocelot-eum-server/src/test/java/rocks/inspectit/oce/eum/server/utils/TagUtilsTest.java b/components/inspectit-ocelot-eum-server/src/test/java/rocks/inspectit/oce/eum/server/utils/TagUtilsTest.java new file mode 100644 index 0000000000..853e5232df --- /dev/null +++ b/components/inspectit-ocelot-eum-server/src/test/java/rocks/inspectit/oce/eum/server/utils/TagUtilsTest.java @@ -0,0 +1,27 @@ +package rocks.inspectit.oce.eum.server.utils; + +import io.opencensus.tags.TagValue; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class TagUtilsTest { + + @Test + public void createTagValue() { + assertThat(TagUtils.createTagValue("my-tag-value")).isEqualTo(TagValue.create("my-tag-value")); + } + + @Test + public void createTagValue_tooLong() { + assertThat(TagUtils.createTagValue("this-value-is-over-255-characters-long ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------")) + .isEqualTo(TagValue.create("")); + } + + @Test + public void createTagValue_nonPrintableCharacter() { + assertThat(TagUtils.createTagValue("non-printable-character-\u007f")) + .isEqualTo(TagValue.create("")); + } + +} diff --git a/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/instrumentation/context/InspectitContextImpl.java b/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/instrumentation/context/InspectitContextImpl.java index 8742c5f10d..83fdc3a9ca 100644 --- a/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/instrumentation/context/InspectitContextImpl.java +++ b/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/instrumentation/context/InspectitContextImpl.java @@ -12,6 +12,7 @@ import rocks.inspectit.ocelot.bootstrap.context.InternalInspectitContext; import rocks.inspectit.ocelot.config.model.instrumentation.data.PropagationMode; import rocks.inspectit.ocelot.core.instrumentation.config.model.propagation.PropagationMetaData; +import rocks.inspectit.ocelot.core.tags.TagUtils; import java.util.*; import java.util.stream.Stream; @@ -346,7 +347,7 @@ private boolean isInDifferentThreadThanParentOrIsParentClosed() { public Scope enterFullTagScope() { TagContextBuilder builder = Tags.getTagger().emptyBuilder(); dataTagsStream() - .forEach(e -> builder.putLocal(TagKey.create(e.getKey()), TagValue.create(e.getValue().toString()))); + .forEach(e -> builder.putLocal(TagKey.create(e.getKey()), TagUtils.createTagValue(e.getValue().toString()))); return builder.buildScoped(); } @@ -579,7 +580,7 @@ private Iterator getPostEntryPhaseTags() { return postEntryPhaseDownPropagatedData.entrySet().stream() .filter(e -> propagation.isTag(e.getKey())) .filter(e -> ALLOWED_TAG_TYPES.contains(e.getValue().getClass())) - .map(e -> Tag.create(TagKey.create(e.getKey()), TagValue.create(e.getValue().toString()), TagMetadata.create(TagMetadata.TagTtl.UNLIMITED_PROPAGATION))) + .map(e -> Tag.create(TagKey.create(e.getKey()), TagUtils.createTagValue(e.getValue().toString()), TagMetadata.create(TagMetadata.TagTtl.UNLIMITED_PROPAGATION))) .iterator(); } diff --git a/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/instrumentation/hook/actions/MetricsRecorder.java b/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/instrumentation/hook/actions/MetricsRecorder.java index c4bd910def..0c3624ce06 100644 --- a/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/instrumentation/hook/actions/MetricsRecorder.java +++ b/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/instrumentation/hook/actions/MetricsRecorder.java @@ -2,13 +2,17 @@ import io.opencensus.stats.MeasureMap; import io.opencensus.stats.StatsRecorder; -import io.opencensus.tags.*; +import io.opencensus.tags.TagContext; +import io.opencensus.tags.TagContextBuilder; +import io.opencensus.tags.TagKey; +import io.opencensus.tags.Tags; import lombok.Value; import lombok.extern.slf4j.Slf4j; import rocks.inspectit.ocelot.core.instrumentation.context.InspectitContextImpl; import rocks.inspectit.ocelot.core.instrumentation.hook.actions.model.MetricAccessor; import rocks.inspectit.ocelot.core.metrics.MeasuresAndViewsManager; import rocks.inspectit.ocelot.core.tags.CommonTagsManager; +import rocks.inspectit.ocelot.core.tags.TagUtils; import java.util.List; import java.util.Optional; @@ -67,17 +71,17 @@ private TagContext getTagContext(ExecutionContext context, MetricAccessor metric // first common tags to allow overwrite by constant or data tags commonTagsManager.getCommonTagKeys() .forEach(commonTagKey -> Optional.ofNullable(inspectitContext.getData(commonTagKey.getName())) - .ifPresent(value -> builder.putLocal(commonTagKey, TagValue.create(value.toString()))) + .ifPresent(value -> builder.putLocal(commonTagKey, TagUtils.createTagValue(value.toString()))) ); // then constant tags to allow overwrite by data metricAccessor.getConstantTags() - .forEach((key, value) -> builder.putLocal(TagKey.create(key), TagValue.create(value))); + .forEach((key, value) -> builder.putLocal(TagKey.create(key), TagUtils.createTagValue(value))); // go over data tags and match the value to the key from the contextTags (if available) metricAccessor.getDataTagAccessors() .forEach((key, accessor) -> Optional.ofNullable(accessor.get(context)) - .ifPresent(tagValue -> builder.putLocal(TagKey.create(key), TagValue.create(tagValue.toString())))); + .ifPresent(tagValue -> builder.putLocal(TagKey.create(key), TagUtils.createTagValue(tagValue.toString())))); // build and return return builder.build(); diff --git a/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/metrics/jmx/JmxMetricsRecorder.java b/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/metrics/jmx/JmxMetricsRecorder.java index e2b94f52ab..c132d7b5cb 100644 --- a/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/metrics/jmx/JmxMetricsRecorder.java +++ b/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/metrics/jmx/JmxMetricsRecorder.java @@ -7,7 +7,6 @@ import io.opencensus.stats.StatsRecorder; import io.opencensus.tags.TagContextBuilder; import io.opencensus.tags.TagKey; -import io.opencensus.tags.TagValue; import io.opencensus.tags.Tagger; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -20,6 +19,7 @@ import rocks.inspectit.ocelot.core.metrics.MeasuresAndViewsManager; import rocks.inspectit.ocelot.core.metrics.system.AbstractPollingMetricsRecorder; import rocks.inspectit.ocelot.core.tags.CommonTagsManager; +import rocks.inspectit.ocelot.core.tags.TagUtils; import javax.management.ObjectName; import java.time.Duration; @@ -72,9 +72,9 @@ public JmxMetricsRecorder(Tagger tagger) { JmxMetricsRecorder(Tagger tagger, MeasuresAndViewsManager measuresAndViewsManager, StatsRecorder statsRecorder, CommonTagsManager commonTagsManager) { super("metrics.jmx"); this.tagger = tagger; - this.measureManager = measuresAndViewsManager; - this.recorder = statsRecorder; - this.commonTags = commonTagsManager; + measureManager = measuresAndViewsManager; + recorder = statsRecorder; + commonTags = commonTagsManager; } /** @@ -85,8 +85,8 @@ public JmxMetricsRecorder(Tagger tagger) { @Override protected boolean doEnable(InspectitConfig configuration) { // create a new scraper, called on every update of every jmx setting - this.jmxScraper = createScraper(configuration.getMetrics().getJmx(), this); - this.lowerCaseMetricName = configuration.getMetrics().getJmx().isLowerCaseMetricName(); + jmxScraper = createScraper(configuration.getMetrics().getJmx(), this); + lowerCaseMetricName = configuration.getMetrics().getJmx().isLowerCaseMetricName(); // call super to handle scheduling return super.doEnable(configuration); @@ -137,7 +137,7 @@ public void recordBean(String domain, LinkedHashMap beanProperti TagContextBuilder tagContextBuilder = tagger.currentBuilder(); beanProperties.entrySet().stream() .skip(1) - .forEach(entry -> tagContextBuilder.putLocal(TagKey.create(entry.getKey()), TagValue.create(entry.getValue()))); + .forEach(entry -> tagContextBuilder.putLocal(TagKey.create(entry.getKey()), TagUtils.createTagValue(entry.getValue()))); MeasureMap measureMap = recorder.newMeasureMap(); measureMap.put(measure, metricValue); diff --git a/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/metrics/system/GCMetricsRecorder.java b/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/metrics/system/GCMetricsRecorder.java index 460469bbcf..e004674078 100644 --- a/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/metrics/system/GCMetricsRecorder.java +++ b/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/metrics/system/GCMetricsRecorder.java @@ -4,7 +4,6 @@ import com.sun.management.GcInfo; import io.opencensus.tags.TagContext; import io.opencensus.tags.TagKey; -import io.opencensus.tags.TagValue; import io.opencensus.tags.Tagger; import lombok.extern.slf4j.Slf4j; import lombok.val; @@ -14,6 +13,7 @@ import rocks.inspectit.ocelot.config.model.metrics.MetricsSettings; import rocks.inspectit.ocelot.config.model.metrics.StandardMetricsSettings; import rocks.inspectit.ocelot.core.selfmonitoring.SelfMonitoringService; +import rocks.inspectit.ocelot.core.tags.TagUtils; import javax.management.ListenerNotFoundException; import javax.management.Notification; @@ -203,8 +203,8 @@ private void recordConcurrentPhaseTime(GarbageCollectionNotificationInfo notific measureManager.getMeasureLong(CONCURRENT_PHASE_TIME_METRIC_FULL_NAME) .ifPresent(measure -> { TagContext tags = tagger.toBuilder(commonTags.getCommonTagContext()) - .putLocal(actionTagKey, TagValue.create(notificationInfo.getGcAction())) - .putLocal(causeTagKey, TagValue.create(notificationInfo.getGcCause())) + .putLocal(actionTagKey, TagUtils.createTagValue(notificationInfo.getGcAction())) + .putLocal(causeTagKey, TagUtils.createTagValue(notificationInfo.getGcCause())) .build(); recorder.newMeasureMap() @@ -217,8 +217,8 @@ private void recordGCPause(GarbageCollectionNotificationInfo notificationInfo) { measureManager.getMeasureLong(PAUSE_METRIC_FULL_NAME) .ifPresent(measure -> { TagContext tags = tagger.toBuilder(commonTags.getCommonTagContext()) - .putLocal(actionTagKey, TagValue.create(notificationInfo.getGcAction())) - .putLocal(causeTagKey, TagValue.create(notificationInfo.getGcCause())) + .putLocal(actionTagKey, TagUtils.createTagValue(notificationInfo.getGcAction())) + .putLocal(causeTagKey, TagUtils.createTagValue(notificationInfo.getGcCause())) .build(); recorder.newMeasureMap() diff --git a/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/metrics/system/MemoryMetricsRecorder.java b/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/metrics/system/MemoryMetricsRecorder.java index 78cc750efe..c31a9ef8d3 100644 --- a/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/metrics/system/MemoryMetricsRecorder.java +++ b/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/metrics/system/MemoryMetricsRecorder.java @@ -2,12 +2,12 @@ import io.opencensus.tags.TagContext; import io.opencensus.tags.TagKey; -import io.opencensus.tags.TagValue; import io.opencensus.tags.Tagger; import lombok.val; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import rocks.inspectit.ocelot.config.model.metrics.MetricsSettings; +import rocks.inspectit.ocelot.core.tags.TagUtils; import java.lang.management.BufferPoolMXBean; import java.lang.management.ManagementFactory; @@ -73,8 +73,8 @@ private void recordMemoryMetrics(Map enabledMetrics) { for (MemoryPoolMXBean memoryPoolBean : ManagementFactory.getPlatformMXBeans(MemoryPoolMXBean.class)) { String area = MemoryType.HEAP.equals(memoryPoolBean.getType()) ? "heap" : "nonheap"; TagContext tags = tagger.currentBuilder() - .putLocal(idTagKey, TagValue.create(memoryPoolBean.getName())) - .putLocal(areaTagKey, TagValue.create(area)) + .putLocal(idTagKey, TagUtils.createTagValue(memoryPoolBean.getName())) + .putLocal(areaTagKey, TagUtils.createTagValue(area)) .build(); val mm = recorder.newMeasureMap(); @@ -104,7 +104,7 @@ private void recordBufferMetrics(Map enabledMetrics) { if (bufferCountEnabled || bufferUsedEnabled || bufferCapacityEnabled) { for (BufferPoolMXBean bufferPoolBean : ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class)) { TagContext tags = tagger.currentBuilder() - .putLocal(idTagKey, TagValue.create(bufferPoolBean.getName())) + .putLocal(idTagKey, TagUtils.createTagValue(bufferPoolBean.getName())) .build(); val mm = recorder.newMeasureMap(); diff --git a/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/metrics/system/ThreadMetricsRecorder.java b/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/metrics/system/ThreadMetricsRecorder.java index 6408993805..5d0659166e 100644 --- a/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/metrics/system/ThreadMetricsRecorder.java +++ b/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/metrics/system/ThreadMetricsRecorder.java @@ -2,12 +2,12 @@ import io.opencensus.tags.TagContextBuilder; import io.opencensus.tags.TagKey; -import io.opencensus.tags.TagValue; import io.opencensus.tags.Tagger; import lombok.val; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import rocks.inspectit.ocelot.config.model.metrics.MetricsSettings; +import rocks.inspectit.ocelot.core.tags.TagUtils; import java.lang.management.ManagementFactory; import java.lang.management.ThreadInfo; @@ -80,7 +80,7 @@ private void recordStateMetric() { measureManager.getMeasureLong(METRIC_NAME_PREFIX + STATE_METRIC_NAME) .ifPresent(measure -> { for (val state : Thread.State.values()) { - TagContextBuilder contextBuilder = tagger.currentBuilder().putLocal(stateTag, TagValue.create(state.name())); + TagContextBuilder contextBuilder = tagger.currentBuilder().putLocal(stateTag, TagUtils.createTagValue(state.name())); try (val scope = contextBuilder.buildScoped()) { val mm = recorder.newMeasureMap(); val count = Arrays.stream(threadBean.getThreadInfo(threadBean.getAllThreadIds())) diff --git a/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/selfmonitoring/SelfMonitoringService.java b/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/selfmonitoring/SelfMonitoringService.java index 3bcbdf7b96..091ef663e7 100644 --- a/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/selfmonitoring/SelfMonitoringService.java +++ b/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/selfmonitoring/SelfMonitoringService.java @@ -3,7 +3,6 @@ import io.opencensus.common.Scope; import io.opencensus.stats.StatsRecorder; import io.opencensus.tags.TagKey; -import io.opencensus.tags.TagValue; import io.opencensus.tags.Tags; import lombok.Data; import lombok.extern.slf4j.Slf4j; @@ -17,6 +16,7 @@ import rocks.inspectit.ocelot.core.config.InspectitEnvironment; import rocks.inspectit.ocelot.core.metrics.MeasuresAndViewsManager; import rocks.inspectit.ocelot.core.tags.CommonTagsManager; +import rocks.inspectit.ocelot.core.tags.TagUtils; import java.util.Collections; import java.util.Map; @@ -161,7 +161,7 @@ public void close() { statsRecorder.newMeasureMap() .put(m, durationInMicros) .record(Tags.getTagger().toBuilder(commonTags.getCommonTagContext()) - .putLocal(COMPONENT_TAG_KEY, TagValue.create(componentName)).build()) + .putLocal(COMPONENT_TAG_KEY, TagUtils.createTagValue(componentName)).build()) ); if (log.isTraceEnabled()) { diff --git a/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/tags/CommonTagsManager.java b/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/tags/CommonTagsManager.java index a049f36d71..e2d015acc3 100644 --- a/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/tags/CommonTagsManager.java +++ b/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/tags/CommonTagsManager.java @@ -1,8 +1,12 @@ package rocks.inspectit.ocelot.core.tags; import io.opencensus.common.Scope; -import io.opencensus.tags.*; +import io.opencensus.tags.TagContext; +import io.opencensus.tags.TagContextBuilder; +import io.opencensus.tags.TagKey; +import io.opencensus.tags.Tags; import lombok.Getter; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.event.EventListener; import org.springframework.core.Ordered; @@ -20,6 +24,7 @@ * Component that provides tags that should be considered as common and used when ever a metric is recorded. */ @Component +@Slf4j public class CommonTagsManager { /** @@ -97,7 +102,7 @@ public Scope withCommonTagScope(Map customTagMap) { HashMap tags = new HashMap<>(commonTagValueMap); tags.putAll(customTagMap); tags.entrySet().stream() - .forEach(entry -> tagContextBuilder.putLocal(TagKey.create(entry.getKey()), TagValue.create(entry.getValue()))); + .forEach(entry -> tagContextBuilder.putLocal(TagKey.create(entry.getKey()), TagUtils.createTagValue(entry.getValue()))); return tagContextBuilder.buildScoped(); } @@ -123,7 +128,7 @@ private void update() { newCommonTagValueMap.forEach((k, v) -> { TagKey key = TagKey.create(k); newCommonTagKeys.add(key); - tagContextBuilder.putLocal(key, TagValue.create(v)); + tagContextBuilder.putLocal(key, TagUtils.createTagValue(v)); }); commonTagKeys = newCommonTagKeys; commonTagValueMap = newCommonTagValueMap; diff --git a/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/tags/TagUtils.java b/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/tags/TagUtils.java new file mode 100644 index 0000000000..43cb8481bb --- /dev/null +++ b/inspectit-ocelot-core/src/main/java/rocks/inspectit/ocelot/core/tags/TagUtils.java @@ -0,0 +1,41 @@ +package rocks.inspectit.ocelot.core.tags; + +import io.opencensus.internal.StringUtils; +import io.opencensus.tags.TagValue; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public final class TagUtils { + + private static boolean isWarningPrinted = false; + + private TagUtils() { + // empty private default constructor for util class + } + + /** + * Constructs a {@code io.opencensus.tags.TagValue} from the given string. + * If String is not valid an <invalid> TagName is created. + * + * @param v the tag value + * @return the created TagValue with 'v' or '<invalid>' + */ + public static TagValue createTagValue(String v) { + if (isTagValueValid(v)) { + return TagValue.create(v); + } + printWarningOnce(); + return TagValue.create(""); + } + + private static boolean isTagValueValid(String value) { + return value.length() <= TagValue.MAX_LENGTH && StringUtils.isPrintableString(value); + } + + private static void printWarningOnce() { + if (!isWarningPrinted) { + log.warn("illegal tag value converted to "); + isWarningPrinted = true; + } + } +} diff --git a/inspectit-ocelot-core/src/test/java/rocks/inspectit/ocelot/core/tags/CommonTagsManagerIntTest.java b/inspectit-ocelot-core/src/test/java/rocks/inspectit/ocelot/core/tags/CommonTagsManagerIntTest.java index 5eecc27f11..2925f18729 100644 --- a/inspectit-ocelot-core/src/test/java/rocks/inspectit/ocelot/core/tags/CommonTagsManagerIntTest.java +++ b/inspectit-ocelot-core/src/test/java/rocks/inspectit/ocelot/core/tags/CommonTagsManagerIntTest.java @@ -99,4 +99,27 @@ public void extraOverwritesProviders() { } } + @Nested + @DirtiesContext + @TestPropertySource(properties = { + "inspectit.tags.extra.service-name=this-value-is-over-255-characters-long ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------", + "inspectit.tags.extra.service-name2=non-printable-character-\u007f" + }) + class VeryLongTagValues extends SpringTestBase { + + @Autowired + CommonTagsManager provider; + + @Test + public void extraOverwritesProviders() { + TagContext commonTagContext = provider.getCommonTagContext(); + + assertThat(InternalUtils.getTags(commonTagContext)) + .anySatisfy(tag -> { + assertThat(tag.getKey()).isEqualTo(TagKey.create("service-name")); + assertThat(tag.getValue()).isEqualTo(TagValue.create("")); + }); + } + } + } \ No newline at end of file diff --git a/inspectit-ocelot-core/src/test/java/rocks/inspectit/ocelot/core/tags/TagUtilsTest.java b/inspectit-ocelot-core/src/test/java/rocks/inspectit/ocelot/core/tags/TagUtilsTest.java new file mode 100644 index 0000000000..6e87300f1b --- /dev/null +++ b/inspectit-ocelot-core/src/test/java/rocks/inspectit/ocelot/core/tags/TagUtilsTest.java @@ -0,0 +1,27 @@ +package rocks.inspectit.ocelot.core.tags; + +import io.opencensus.tags.TagValue; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class TagUtilsTest { + + @Test + public void createTagValue() { + assertThat(TagUtils.createTagValue("my-tag-value")).isEqualTo(TagValue.create("my-tag-value")); + } + + @Test + public void createTagValue_tooLong() { + assertThat(TagUtils.createTagValue("this-value-is-over-255-characters-long ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------")) + .isEqualTo(TagValue.create("")); + } + + @Test + public void createTagValue_nonPrintableCharacter() { + assertThat(TagUtils.createTagValue("non-printable-character-\u007f")) + .isEqualTo(TagValue.create("")); + } + +}