|
24 | 24 | import com.arpnetworking.tsdcore.model.Quantity;
|
25 | 25 | import com.arpnetworking.tsdcore.model.Unit;
|
26 | 26 | import com.google.common.base.Charsets;
|
| 27 | +import com.google.common.base.Splitter; |
27 | 28 | import com.google.common.base.Strings;
|
| 29 | +import com.google.common.collect.ImmutableList; |
28 | 30 | import com.google.common.collect.ImmutableMap;
|
29 | 31 | import com.google.common.collect.ImmutableSet;
|
30 | 32 | import com.google.common.collect.Maps;
|
@@ -77,38 +79,43 @@ public final class StatsdToRecordParser implements Parser<List<Record>, ByteBuff
|
77 | 79 | public List<Record> parse(final ByteBuffer datagram) throws ParsingException {
|
78 | 80 | // CHECKSTYLE.OFF: IllegalInstantiation - This is the recommended way
|
79 | 81 | final String datagramAsString = new String(datagram.array(), Charsets.UTF_8);
|
80 |
| - // CHECKSTYLE.ON: IllegalInstantiation |
81 |
| - final Matcher matcher = STATSD_PATTERN.matcher(datagramAsString); |
82 |
| - if (!matcher.matches()) { |
83 |
| - throw new ParsingException("Invalid statsd datagram", datagram.array()); |
84 |
| - } |
| 82 | + final ImmutableList.Builder<Record> recordListBuilder = ImmutableList.builder(); |
| 83 | + for (final String line : LINE_SPLITTER.split(datagramAsString)) { |
| 84 | + // CHECKSTYLE.ON: IllegalInstantiation |
| 85 | + final Matcher matcher = STATSD_PATTERN.matcher(line); |
| 86 | + if (!matcher.matches()) { |
| 87 | + throw new ParsingException("Invalid statsd line", line.getBytes(Charsets.UTF_8)); |
| 88 | + } |
85 | 89 |
|
86 |
| - // Parse the name |
87 |
| - final String name = parseName(datagram, matcher.group("NAME")); |
| 90 | + // Parse the name |
| 91 | + final String name = parseName(datagram, matcher.group("NAME")); |
88 | 92 |
|
89 |
| - // Parse the _metricType |
90 |
| - final StatsdType type = parseStatsdType(datagram, matcher.group("TYPE")); |
| 93 | + // Parse the _metricType |
| 94 | + final StatsdType type = parseStatsdType(datagram, matcher.group("TYPE")); |
91 | 95 |
|
92 |
| - // Parse the value |
93 |
| - final Number value = parseValue(datagram, matcher.group("VALUE"), type); |
| 96 | + // Parse the value |
| 97 | + final Number value = parseValue(datagram, matcher.group("VALUE"), type); |
94 | 98 |
|
95 |
| - // Parse the value |
96 |
| - final Optional<Double> sampleRate = parseSampleRate(datagram, matcher.group("SAMPLERATE"), type); |
| 99 | + // Parse the value |
| 100 | + final Optional<Double> sampleRate = parseSampleRate(datagram, matcher.group("SAMPLERATE"), type); |
97 | 101 |
|
98 |
| - // Parse the tags |
99 |
| - final ImmutableMap<String, String> annotations = parseTags(matcher.group("TAGS")); |
| 102 | + // Parse the tags |
| 103 | + final ImmutableMap<String, String> annotations = parseTags(matcher.group("TAGS")); |
100 | 104 |
|
101 |
| - // Enforce sampling |
102 |
| - if (sampleRate.isPresent() && sampleRate.get().compareTo(1.0) != 0) { |
103 |
| - if (sampleRate.get().compareTo(0.0) == 0) { |
104 |
| - return Collections.emptyList(); |
105 |
| - } |
106 |
| - if (Double.compare(_randomSupplier.get().nextDouble(), sampleRate.get()) > 0) { |
107 |
| - return Collections.emptyList(); |
| 105 | + // Enforce sampling |
| 106 | + if (sampleRate.isPresent() && sampleRate.get().compareTo(1.0) != 0) { |
| 107 | + if (sampleRate.get().compareTo(0.0) == 0) { |
| 108 | + return Collections.emptyList(); |
| 109 | + } |
| 110 | + if (Double.compare(_randomSupplier.get().nextDouble(), sampleRate.get()) > 0) { |
| 111 | + return Collections.emptyList(); |
| 112 | + } |
108 | 113 | }
|
| 114 | + |
| 115 | + recordListBuilder.add(createRecord(name, value, type, annotations)); |
109 | 116 | }
|
110 | 117 |
|
111 |
| - return Collections.singletonList(createRecord(name, value, type, annotations)); |
| 118 | + return recordListBuilder.build(); |
112 | 119 | }
|
113 | 120 |
|
114 | 121 | private StatsdType parseStatsdType(final ByteBuffer datagram, final @Nullable String statsdTypeAsString) throws ParsingException {
|
@@ -225,6 +232,7 @@ public StatsdToRecordParser() {
|
225 | 232 | StatsdType.COUNTER,
|
226 | 233 | StatsdType.HISTOGRAM,
|
227 | 234 | StatsdType.TIMER);
|
| 235 | + private static final Splitter LINE_SPLITTER = Splitter.on('\n').omitEmptyStrings(); |
228 | 236 | private static final ThreadLocal<NumberFormat> NUMBER_FORMAT = ThreadLocal.withInitial(NumberFormat::getInstance);
|
229 | 237 | private static final Pattern STATSD_PATTERN = Pattern.compile(
|
230 | 238 | "^(?<NAME>[^:@|]+):(?<VALUE>[^|]+)\\|(?<TYPE>[^|]+)(\\|@(?<SAMPLERATE>[^|]+))?(\\|#(?<TAGS>.+))?$");
|
|
0 commit comments