Skip to content

Commit 1ef3e54

Browse files
committed
Merge pull request #36 from Zariel/parse-message-remove-regexp
Parse message remove regexp
2 parents 3aa2ddb + eab8ccb commit 1ef3e54

File tree

2 files changed

+94
-22
lines changed

2 files changed

+94
-22
lines changed

statsdaemon.go

Lines changed: 67 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"net"
1111
"os"
1212
"os/signal"
13-
"regexp"
1413
"runtime"
1514
"sort"
1615
"strconv"
@@ -278,48 +277,94 @@ func processTimers(buffer *bytes.Buffer, now int64, pctls Percentiles) int64 {
278277
return num
279278
}
280279

281-
var packetRegexp = regexp.MustCompile("^([^:]+):(-?[0-9]+)\\|(g|c|ms)(\\|@([0-9\\.]+))?\n?$")
282-
283280
func parseMessage(data []byte) []*Packet {
284-
var output []*Packet
281+
var (
282+
output []*Packet
283+
input []byte
284+
)
285+
285286
for _, line := range bytes.Split(data, []byte("\n")) {
286287
if len(line) == 0 {
287288
continue
288289
}
290+
input = line
289291

290-
item := packetRegexp.FindSubmatch(line)
291-
if len(item) == 0 {
292+
index := bytes.IndexByte(input, ':')
293+
if index < 0 {
294+
if *debug {
295+
log.Printf("ERROR: failed to parse line: %s\n", string(line))
296+
}
292297
continue
293298
}
294299

295-
var err error
296-
var value interface{}
297-
modifier := string(item[3])
298-
switch modifier {
299-
case "c":
300-
value, err = strconv.ParseInt(string(item[2]), 10, 64)
300+
name := input[:index]
301+
302+
index++
303+
input = input[index:]
304+
305+
index = bytes.IndexByte(input, '|')
306+
if index < 0 {
307+
if *debug {
308+
log.Printf("ERROR: failed to parse line: %s\n", string(line))
309+
}
310+
continue
311+
}
312+
313+
val := input[:index]
314+
index++
315+
316+
var mtypeStr string
317+
318+
if input[index] == 'm' {
319+
index++
320+
if index >= len(input) || input[index] != 's' {
321+
if *debug {
322+
log.Printf("ERROR: failed to parse line: %s\n", string(line))
323+
}
324+
continue
325+
}
326+
mtypeStr = "ms"
327+
} else {
328+
mtypeStr = string(input[index])
329+
}
330+
331+
index++
332+
input = input[index:]
333+
334+
var (
335+
value interface{}
336+
err error
337+
)
338+
339+
if mtypeStr[0] == 'c' {
340+
value, err = strconv.ParseInt(string(val), 10, 64)
301341
if err != nil {
302-
log.Printf("ERROR: failed to ParseInt %s - %s", item[2], err)
342+
log.Printf("ERROR: failed to ParseInt %s - %s", string(val), err)
303343
continue
304344
}
305-
default:
306-
value, err = strconv.ParseUint(string(item[2]), 10, 64)
345+
} else {
346+
value, err = strconv.ParseUint(string(val), 10, 64)
307347
if err != nil {
308-
log.Printf("ERROR: failed to ParseUint %s - %s", item[2], err)
348+
log.Printf("ERROR: failed to ParseUint %s - %s", string(val), err)
309349
continue
310350
}
311351
}
312352

313-
sampleRate, err := strconv.ParseFloat(string(item[5]), 32)
314-
if err != nil {
315-
sampleRate = 1
353+
var sampleRate float32 = 1
354+
355+
if len(input) > 0 && bytes.HasPrefix(input, []byte("|@")) {
356+
input = input[2:]
357+
rate, err := strconv.ParseFloat(string(input), 32)
358+
if err == nil {
359+
sampleRate = float32(rate)
360+
}
316361
}
317362

318363
packet := &Packet{
319-
Bucket: *prefix + string(item[1]),
364+
Bucket: *prefix + string(name),
320365
Value: value,
321-
Modifier: modifier,
322-
Sampling: float32(sampleRate),
366+
Modifier: mtypeStr,
367+
Sampling: sampleRate,
323368
}
324369
output = append(output, packet)
325370
}

statsdaemon_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,26 @@ func TestPacketParse(t *testing.T) {
9494
d = []byte("a.key.with-0.dash:4")
9595
packets = parseMessage(d)
9696
assert.Equal(t, len(packets), 0)
97+
98+
d = []byte("gorets:5m")
99+
packets = parseMessage(d)
100+
assert.Equal(t, len(packets), 0)
101+
102+
d = []byte("gorets")
103+
packets = parseMessage(d)
104+
assert.Equal(t, len(packets), 0)
105+
106+
d = []byte("gorets:")
107+
packets = parseMessage(d)
108+
assert.Equal(t, len(packets), 0)
109+
110+
d = []byte("gorets:5|mg")
111+
packets = parseMessage(d)
112+
assert.Equal(t, len(packets), 0)
113+
114+
d = []byte("gorets:5|ms|@")
115+
packets = parseMessage(d)
116+
assert.Equal(t, len(packets), 1)
97117
}
98118

99119
func TestMean(t *testing.T) {
@@ -232,3 +252,10 @@ func BenchmarkLotsOfTimers(t *testing.B) {
232252
t.ResetTimer()
233253
processTimers(&buff, time.Now().Unix(), commonPercentiles)
234254
}
255+
256+
func BenchmarkParseMessage(b *testing.B) {
257+
d := []byte("a.key.with-0.dash:4|c|@0.5")
258+
for i := 0; i < b.N; i++ {
259+
parseMessage(d)
260+
}
261+
}

0 commit comments

Comments
 (0)