|
31 | 31 | import com.arpnetworking.tsdcore.model.MetricType;
|
32 | 32 | import com.arpnetworking.tsdcore.model.Quantity;
|
33 | 33 | import com.google.common.base.MoreObjects;
|
| 34 | +import com.google.common.base.Splitter; |
34 | 35 | import com.google.common.collect.ImmutableList;
|
35 | 36 | import com.google.common.collect.ImmutableMap;
|
36 | 37 | import com.google.common.collect.Maps;
|
|
40 | 41 | import java.util.Map;
|
41 | 42 | import java.util.regex.Matcher;
|
42 | 43 | import java.util.regex.Pattern;
|
| 44 | +import java.util.stream.Collectors; |
43 | 45 |
|
44 | 46 | /**
|
45 | 47 | * Implementation of <code>Source</code> which wraps another <code>Source</code>
|
@@ -95,6 +97,7 @@ private MappingSource(final Builder builder) {
|
95 | 97 | private final Map<Pattern, List<String>> _findAndReplace;
|
96 | 98 |
|
97 | 99 | private static final Logger LOGGER = LoggerFactory.getLogger(MappingSource.class);
|
| 100 | + private static final Splitter.MapSplitter TAG_SPLITTER = Splitter.on(';').omitEmptyStrings().trimResults().withKeyValueSeparator('='); |
98 | 101 |
|
99 | 102 | // NOTE: Package private for testing
|
100 | 103 | /* package private */ static final class MappingObserver implements Observer {
|
@@ -123,7 +126,27 @@ public void notify(final Observable observable, final Object event) {
|
123 | 126 | final Matcher matcher = findAndReplace.getKey().matcher(metric.getKey());
|
124 | 127 | if (matcher.find()) {
|
125 | 128 | for (final String replacement : findAndReplace.getValue()) {
|
126 |
| - merge(metric.getValue(), matcher.replaceAll(replacement), mergedMetrics); |
| 129 | + final String replacedString = matcher.replaceAll(replacement); |
| 130 | + |
| 131 | + final int tagsStart = replacedString.indexOf(';'); |
| 132 | + if (tagsStart == -1) { |
| 133 | + // We just have a metric name. Optimize for this common case |
| 134 | + merge(metric.getValue(), replacedString, mergedMetrics); |
| 135 | + } else { |
| 136 | + final Map<String, String> parsedTags = TAG_SPLITTER.split(replacedString.substring(tagsStart + 1)); |
| 137 | + final Map<String, String> finalTags = Maps.newTreeMap(); |
| 138 | + finalTags.putAll(record.getDimensions()); |
| 139 | + finalTags.putAll(parsedTags); |
| 140 | + final StringBuilder keyBuilder = new StringBuilder(); |
| 141 | + keyBuilder.append(replacedString.substring(0, tagsStart + 1)); |
| 142 | + keyBuilder.append( |
| 143 | + finalTags.entrySet() |
| 144 | + .stream() |
| 145 | + .map(entry -> String.format("%s=%s", entry.getKey(), entry.getValue())) |
| 146 | + .collect(Collectors.joining(";"))); |
| 147 | + |
| 148 | + merge(metric.getValue(), keyBuilder.toString(), mergedMetrics); |
| 149 | + } |
127 | 150 | }
|
128 | 151 | //Having "found" set here means that mapping a metric to an empty list suppresses that metric
|
129 | 152 | found = true;
|
|
0 commit comments