|
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