Skip to content

Commit d8748a1

Browse files
authored
v1 (#22)
1 parent a20549f commit d8748a1

13 files changed

+1545
-922
lines changed

Makefile

+6-2
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,20 @@ GO_TEST_TIMEOUT ?= 15s
1010

1111
GO_BENCH=go test -bench=. -benchmem
1212

13-
all: test
13+
all: lint test benchmark
1414

1515
test:
1616
$(GO) test \
1717
-race \
1818
-timeout $(GO_TEST_TIMEOUT) \
1919
$(GO_TEST_PKGS)
2020

21-
#XXX: ugly
21+
#FIXME
2222
benchmark:
2323
$(GO_BENCH)
2424
cd rfc3164 && $(GO_BENCH)
2525
cd rfc5424 && $(GO_BENCH)
26+
cd parsercommon && $(GO_BENCH)
27+
28+
lint:
29+
golangci-lint run ./...

README.md

+16-15
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ Syslogparser
33

44
This is a syslog parser for the Go programming language.
55

6+
https://pkg.go.dev/github.com/jeromer/syslogparser
7+
68
Installing
79
----------
810

@@ -112,34 +114,33 @@ Run `make benchmark`
112114
goos: linux
113115
goarch: amd64
114116
pkg: github.com/jeromer/syslogparser
115-
BenchmarkParsePriority-8 41772079 31.2 ns/op 0 B/op 0 allocs/op
116-
BenchmarkParseVersion-8 270007530 4.45 ns/op 0 B/op 0 allocs/op
117-
BenchmarkDetectRFC-8 78742269 16.2 ns/op 0 B/op 0 allocs/op
117+
BenchmarkDetectRFC-8 81994480 14.7 ns/op 0 B/op 0 allocs/op
118118
PASS
119-
ok github.com/jeromer/syslogparser 5.257s
119+
ok github.com/jeromer/syslogparser 2.145s
120120

121121
cd rfc3164 && go test -bench=. -benchmem
122122
goos: linux
123123
goarch: amd64
124124
pkg: github.com/jeromer/syslogparser/rfc3164
125-
BenchmarkParseTimestamp-8 2693362 467 ns/op 16 B/op 1 allocs/op
126-
BenchmarkParseHostname-8 34919636 32.8 ns/op 16 B/op 1 allocs/op
127-
BenchmarkParseTag-8 20970715 56.0 ns/op 8 B/op 1 allocs/op
128-
BenchmarkParseHeader-8 2549106 478 ns/op 32 B/op 2 allocs/op
129-
BenchmarkParsemessage-8 8280796 143 ns/op 72 B/op 3 allocs/op
130-
BenchmarkParseFull-8 8070195 139 ns/op 120 B/op 3 allocs/op
125+
BenchmarkParseTimestamp-8 2823901 416 ns/op 16 B/op 1 allocs/op
126+
BenchmarkParseHostname-8 34796552 35.4 ns/op 16 B/op 1 allocs/op
127+
BenchmarkParseTag-8 20954252 59.3 ns/op 8 B/op 1 allocs/op
128+
BenchmarkParseHeader-8 2276569 596 ns/op 80 B/op 3 allocs/op
129+
BenchmarkParsemessage-8 6751579 192 ns/op 104 B/op 4 allocs/op
130+
BenchmarkParseFull-8 1445076 838 ns/op 336 B/op 10 allocs/op
131131
PASS
132-
ok github.com/jeromer/syslogparser/rfc3164 8.428s
133132

133+
ok github.com/jeromer/syslogparser/rfc3164 9.601s
134134
cd rfc5424 && go test -bench=. -benchmem
135135
goos: linux
136136
goarch: amd64
137137
pkg: github.com/jeromer/syslogparser/rfc5424
138-
BenchmarkParseTimestamp-8 846019 1385 ns/op 352 B/op 18 allocs/op
139-
BenchmarkParseHeader-8 1424103 840 ns/op 106 B/op 12 allocs/op
140-
BenchmarkParseFull-8 1444834 825 ns/op 112 B/op 12 allocs/op
138+
BenchmarkParseTimestamp-8 790478 1488 ns/op 432 B/op 21 allocs/op
139+
BenchmarkParseHeader-8 1000000 1043 ns/op 336 B/op 18 allocs/op
140+
BenchmarkParseFull-8 980828 1306 ns/op 672 B/op 21 allocs/op
141141
PASS
142-
ok github.com/jeromer/syslogparser/rfc5424 6.195s
142+
ok github.com/jeromer/syslogparser/rfc5424 4.356s
143+
143144

144145
[RFC 5424]: https://tools.ietf.org/html/rfc5424
145146
[RFC 3164]: https://tools.ietf.org/html/rfc3164

go.sum

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
55
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
66
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
77
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
8+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
89
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
910
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
1011
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

parsercommon/parsercommon.go

+196
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
package parsercommon
2+
3+
import (
4+
"fmt"
5+
"strconv"
6+
"strings"
7+
)
8+
9+
const (
10+
NO_VERSION = -1
11+
)
12+
13+
var (
14+
ErrEOL = &ParserError{"End of log line"}
15+
ErrNoSpace = &ParserError{"No space found"}
16+
17+
ErrPriorityNoStart = &ParserError{"No start char found for priority"}
18+
ErrPriorityEmpty = &ParserError{"Priority field empty"}
19+
ErrPriorityNoEnd = &ParserError{"No end char found for priority"}
20+
ErrPriorityTooShort = &ParserError{"Priority field too short"}
21+
ErrPriorityTooLong = &ParserError{"Priority field too long"}
22+
ErrPriorityNonDigit = &ParserError{"Non digit found in priority"}
23+
24+
ErrVersionNotFound = &ParserError{"Can not find version"}
25+
26+
ErrTimestampUnknownFormat = &ParserError{"Timestamp format unknown"}
27+
28+
ErrHostnameNotFound = &ParserError{"Hostname not found"}
29+
)
30+
31+
type ParserError struct {
32+
ErrorString string
33+
}
34+
35+
type Priority struct {
36+
P int
37+
F Facility
38+
S Severity
39+
}
40+
41+
type Facility struct {
42+
Value int
43+
}
44+
45+
type Severity struct {
46+
Value int
47+
}
48+
49+
// https://tools.ietf.org/html/rfc3164#section-4.1
50+
func ParsePriority(buff []byte, cursor *int, l int) (*Priority, error) {
51+
if l <= 0 {
52+
return nil, ErrPriorityEmpty
53+
}
54+
55+
if buff[*cursor] != '<' {
56+
return nil, ErrPriorityNoStart
57+
}
58+
59+
i := 1
60+
priDigit := 0
61+
62+
for i < l {
63+
if i >= 5 {
64+
return nil, ErrPriorityTooLong
65+
}
66+
67+
c := buff[i]
68+
69+
if c == '>' {
70+
if i == 1 {
71+
return nil, ErrPriorityTooShort
72+
}
73+
74+
*cursor = i + 1
75+
76+
return NewPriority(priDigit), nil
77+
}
78+
79+
if IsDigit(c) {
80+
v, e := strconv.Atoi(string(c))
81+
if e != nil {
82+
return nil, e
83+
}
84+
85+
priDigit = (priDigit * 10) + v
86+
} else {
87+
return nil, ErrPriorityNonDigit
88+
}
89+
90+
i++
91+
}
92+
93+
return nil, ErrPriorityNoEnd
94+
}
95+
96+
// https://tools.ietf.org/html/rfc5424#section-6.2.2
97+
func ParseVersion(buff []byte, cursor *int, l int) (int, error) {
98+
if *cursor >= l {
99+
return NO_VERSION, ErrVersionNotFound
100+
}
101+
102+
c := buff[*cursor]
103+
*cursor++
104+
105+
// XXX : not a version, not an error though as RFC 3164 does not support it
106+
if !IsDigit(c) {
107+
return NO_VERSION, nil
108+
}
109+
110+
v, e := strconv.Atoi(string(c))
111+
if e != nil {
112+
*cursor--
113+
return NO_VERSION, e
114+
}
115+
116+
return v, nil
117+
118+
}
119+
120+
func IsDigit(c byte) bool {
121+
return c >= '0' && c <= '9'
122+
}
123+
124+
func NewPriority(p int) *Priority {
125+
// The Priority value is calculated by first multiplying the Facility
126+
// number by 8 and then adding the numerical value of the Severity.
127+
128+
return &Priority{
129+
P: p,
130+
F: Facility{Value: p / 8},
131+
S: Severity{Value: p % 8},
132+
}
133+
}
134+
135+
func FindNextSpace(buff []byte, from int, l int) (int, error) {
136+
var to int
137+
138+
for to = from; to < l; to++ {
139+
if buff[to] == ' ' {
140+
to++
141+
return to, nil
142+
}
143+
}
144+
145+
return 0, ErrNoSpace
146+
}
147+
148+
func Parse2Digits(buff []byte, cursor *int, l int, min int, max int, e error) (int, error) {
149+
digitLen := 2
150+
151+
if *cursor+digitLen > l {
152+
return 0, ErrEOL
153+
}
154+
155+
sub := string(buff[*cursor : *cursor+digitLen])
156+
157+
*cursor += digitLen
158+
159+
i, err := strconv.Atoi(sub)
160+
if err != nil {
161+
return 0, e
162+
}
163+
164+
if i >= min && i <= max {
165+
return i, nil
166+
}
167+
168+
return 0, e
169+
}
170+
171+
func ParseHostname(buff []byte, cursor *int, l int) (string, error) {
172+
from := *cursor
173+
var to int
174+
175+
for to = from; to < l; to++ {
176+
if buff[to] == ' ' {
177+
break
178+
}
179+
}
180+
181+
hostname := buff[from:to]
182+
183+
*cursor = to
184+
185+
return string(hostname), nil
186+
}
187+
188+
func ShowCursorPos(buff []byte, cursor int) {
189+
fmt.Println(string(buff))
190+
padding := strings.Repeat("-", cursor)
191+
fmt.Println(padding + "↑\n")
192+
}
193+
194+
func (err *ParserError) Error() string {
195+
return err.ErrorString
196+
}

0 commit comments

Comments
 (0)