Skip to content

Commit

Permalink
v1 (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeromer authored Feb 24, 2021
1 parent a20549f commit d8748a1
Show file tree
Hide file tree
Showing 13 changed files with 1,545 additions and 922 deletions.
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,20 @@ GO_TEST_TIMEOUT ?= 15s

GO_BENCH=go test -bench=. -benchmem

all: test
all: lint test benchmark

test:
$(GO) test \
-race \
-timeout $(GO_TEST_TIMEOUT) \
$(GO_TEST_PKGS)

#XXX: ugly
#FIXME
benchmark:
$(GO_BENCH)
cd rfc3164 && $(GO_BENCH)
cd rfc5424 && $(GO_BENCH)
cd parsercommon && $(GO_BENCH)

lint:
golangci-lint run ./...
31 changes: 16 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ Syslogparser

This is a syslog parser for the Go programming language.

https://pkg.go.dev/github.com/jeromer/syslogparser

Installing
----------

Expand Down Expand Up @@ -112,34 +114,33 @@ Run `make benchmark`
goos: linux
goarch: amd64
pkg: github.com/jeromer/syslogparser
BenchmarkParsePriority-8 41772079 31.2 ns/op 0 B/op 0 allocs/op
BenchmarkParseVersion-8 270007530 4.45 ns/op 0 B/op 0 allocs/op
BenchmarkDetectRFC-8 78742269 16.2 ns/op 0 B/op 0 allocs/op
BenchmarkDetectRFC-8 81994480 14.7 ns/op 0 B/op 0 allocs/op
PASS
ok github.com/jeromer/syslogparser 5.257s
ok github.com/jeromer/syslogparser 2.145s

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

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


[RFC 5424]: https://tools.ietf.org/html/rfc5424
[RFC 3164]: https://tools.ietf.org/html/rfc3164
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
196 changes: 196 additions & 0 deletions parsercommon/parsercommon.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
package parsercommon

import (
"fmt"
"strconv"
"strings"
)

const (
NO_VERSION = -1
)

var (
ErrEOL = &ParserError{"End of log line"}
ErrNoSpace = &ParserError{"No space found"}

ErrPriorityNoStart = &ParserError{"No start char found for priority"}
ErrPriorityEmpty = &ParserError{"Priority field empty"}
ErrPriorityNoEnd = &ParserError{"No end char found for priority"}
ErrPriorityTooShort = &ParserError{"Priority field too short"}
ErrPriorityTooLong = &ParserError{"Priority field too long"}
ErrPriorityNonDigit = &ParserError{"Non digit found in priority"}

ErrVersionNotFound = &ParserError{"Can not find version"}

ErrTimestampUnknownFormat = &ParserError{"Timestamp format unknown"}

ErrHostnameNotFound = &ParserError{"Hostname not found"}
)

type ParserError struct {
ErrorString string
}

type Priority struct {
P int
F Facility
S Severity
}

type Facility struct {
Value int
}

type Severity struct {
Value int
}

// https://tools.ietf.org/html/rfc3164#section-4.1
func ParsePriority(buff []byte, cursor *int, l int) (*Priority, error) {
if l <= 0 {
return nil, ErrPriorityEmpty
}

if buff[*cursor] != '<' {
return nil, ErrPriorityNoStart
}

i := 1
priDigit := 0

for i < l {
if i >= 5 {
return nil, ErrPriorityTooLong
}

c := buff[i]

if c == '>' {
if i == 1 {
return nil, ErrPriorityTooShort
}

*cursor = i + 1

return NewPriority(priDigit), nil
}

if IsDigit(c) {
v, e := strconv.Atoi(string(c))
if e != nil {
return nil, e
}

priDigit = (priDigit * 10) + v
} else {
return nil, ErrPriorityNonDigit
}

i++
}

return nil, ErrPriorityNoEnd
}

// https://tools.ietf.org/html/rfc5424#section-6.2.2
func ParseVersion(buff []byte, cursor *int, l int) (int, error) {
if *cursor >= l {
return NO_VERSION, ErrVersionNotFound
}

c := buff[*cursor]
*cursor++

// XXX : not a version, not an error though as RFC 3164 does not support it
if !IsDigit(c) {
return NO_VERSION, nil
}

v, e := strconv.Atoi(string(c))
if e != nil {
*cursor--
return NO_VERSION, e
}

return v, nil

}

func IsDigit(c byte) bool {
return c >= '0' && c <= '9'
}

func NewPriority(p int) *Priority {
// The Priority value is calculated by first multiplying the Facility
// number by 8 and then adding the numerical value of the Severity.

return &Priority{
P: p,
F: Facility{Value: p / 8},
S: Severity{Value: p % 8},
}
}

func FindNextSpace(buff []byte, from int, l int) (int, error) {
var to int

for to = from; to < l; to++ {
if buff[to] == ' ' {
to++
return to, nil
}
}

return 0, ErrNoSpace
}

func Parse2Digits(buff []byte, cursor *int, l int, min int, max int, e error) (int, error) {
digitLen := 2

if *cursor+digitLen > l {
return 0, ErrEOL
}

sub := string(buff[*cursor : *cursor+digitLen])

*cursor += digitLen

i, err := strconv.Atoi(sub)
if err != nil {
return 0, e
}

if i >= min && i <= max {
return i, nil
}

return 0, e
}

func ParseHostname(buff []byte, cursor *int, l int) (string, error) {
from := *cursor
var to int

for to = from; to < l; to++ {
if buff[to] == ' ' {
break
}
}

hostname := buff[from:to]

*cursor = to

return string(hostname), nil
}

func ShowCursorPos(buff []byte, cursor int) {
fmt.Println(string(buff))
padding := strings.Repeat("-", cursor)
fmt.Println(padding + "↑\n")
}

func (err *ParserError) Error() string {
return err.ErrorString
}
Loading

0 comments on commit d8748a1

Please sign in to comment.