Skip to content
This repository was archived by the owner on Dec 29, 2025. It is now read-only.

Commit 40b369b

Browse files
authored
Support for rfc3164 section 4.3.3 (no priority field) (#1)
* update to support no priority * support for automatic format detection with rfc3164 section 4.3.3
1 parent ed13815 commit 40b369b

File tree

5 files changed

+83
-15
lines changed

5 files changed

+83
-15
lines changed

format/automatic.go

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package format
33
import (
44
"bufio"
55
"bytes"
6-
"errors"
76
"strconv"
87

98
"github.com/demisto/go-syslog/internal/syslogparser/rfc3164"
@@ -31,33 +30,40 @@ const (
3130
detectedRFC6587 = iota
3231
)
3332

34-
func detect(data []byte) (detected int, err error) {
33+
/*
34+
* Will always fallback to rfc3164 (see section 4.3.3)
35+
*/
36+
func detect(data []byte) int {
3537
// all formats have a sapce somewhere
3638
if i := bytes.IndexByte(data, ' '); i > 0 {
3739
pLength := data[0:i]
3840
if _, err := strconv.Atoi(string(pLength)); err == nil {
39-
return detectedRFC6587, nil
41+
return detectedRFC6587
42+
}
43+
// are we starting with <
44+
if data[0] != '<' {
45+
return detectedRFC3164
4046
}
41-
4247
// is there a close angle bracket before the ' '? there should be
4348
angle := bytes.IndexByte(data, '>')
4449
if (angle < 0) || (angle >= i) {
45-
return detectedUnknown, errors.New("No close angle bracket before space")
50+
return detectedRFC3164
4651
}
4752

4853
// if a single digit immediately follows the angle bracket, then a space
4954
// it is RFC5424, as RFC3164 must begin with a letter (month name)
5055
if (angle+2 == i) && (data[angle+1] >= '0') && (data[angle+1] <= '9') {
51-
return detectedRFC5424, nil
56+
return detectedRFC5424
5257
} else {
53-
return detectedRFC3164, nil
58+
return detectedRFC3164
5459
}
5560
}
56-
return detectedUnknown, nil
61+
// fallback to rfc 3164 section 4.3.3
62+
return detectedRFC3164
5763
}
5864

5965
func (f *Automatic) GetParser(line []byte) LogParser {
60-
switch format, _ := detect(line); format {
66+
switch format := detect(line); format {
6167
case detectedRFC3164:
6268
return &parserWrapper{rfc3164.NewParser(line)}
6369
case detectedRFC5424:
@@ -82,7 +88,7 @@ func (f *Automatic) automaticScannerSplit(data []byte, atEOF bool) (advance int,
8288
return 0, nil, nil
8389
}
8490

85-
switch format, err := detect(data); format {
91+
switch format := detect(data); format {
8692
case detectedRFC6587:
8793
return rfc6587ScannerSplit(data, atEOF)
8894
case detectedRFC3164, detectedRFC5424:

internal/syslogparser/rfc3164/rfc3164.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,21 @@ func (p *Parser) Location(location *time.Location) {
4343
}
4444

4545
func (p *Parser) Parse() error {
46+
tcursor := p.cursor
4647
pri, err := p.parsePriority()
4748
if err != nil {
48-
return err
49+
// RFC3164 sec 4.3.3
50+
p.priority = syslogparser.Priority{13, syslogparser.Facility{Value: 1}, syslogparser.Severity{Value: 5}}
51+
p.cursor = tcursor
52+
content, err := p.parseContent()
53+
if err != syslogparser.ErrEOL {
54+
return err
55+
}
56+
p.message = rfc3164message{content: content}
57+
return nil
4958
}
5059

51-
tcursor := p.cursor
60+
tcursor = p.cursor
5261
hdr, err := p.parseHeader()
5362
if err == syslogparser.ErrTimestampUnknownFormat {
5463
// RFC3164 sec 4.3.2.

internal/syslogparser/rfc3164/rfc3164_test.go

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import (
55
"testing"
66
"time"
77

8-
. "gopkg.in/check.v1"
98
"github.com/demisto/go-syslog/internal/syslogparser"
9+
. "gopkg.in/check.v1"
1010
)
1111

1212
// Hooks up gocheck into the gotest runner.
@@ -121,6 +121,40 @@ func (s *Rfc3164TestSuite) TestParser_NoTimestamp(c *C) {
121121
c.Assert(obtained, DeepEquals, expected)
122122
}
123123

124+
// RFC 3164 section 4.3.3
125+
func (s *Rfc3164TestSuite) TestParser_NoPriority(c *C) {
126+
buff := []byte("Oct 11 22:14:15 Testing no priority")
127+
128+
p := NewParser(buff)
129+
expectedP := &Parser{
130+
buff: buff,
131+
cursor: 0,
132+
l: len(buff),
133+
location: time.UTC,
134+
}
135+
136+
c.Assert(p, DeepEquals, expectedP)
137+
138+
err := p.Parse()
139+
c.Assert(err, IsNil)
140+
141+
now := time.Now()
142+
143+
obtained := p.Dump()
144+
obtained["timestamp"] = now // XXX: Need to mock out time to test this fully
145+
expected := syslogparser.LogParts{
146+
"timestamp": now,
147+
"hostname": "",
148+
"tag": "",
149+
"content": "Oct 11 22:14:15 Testing no priority",
150+
"priority": 13,
151+
"facility": 1,
152+
"severity": 5,
153+
}
154+
155+
c.Assert(obtained, DeepEquals, expected)
156+
}
157+
124158
func (s *Rfc3164TestSuite) TestParseHeader_Valid(c *C) {
125159
buff := []byte("Oct 11 22:14:15 mymachine ")
126160
now := time.Now()

server.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ func (s *Server) parser(line []byte, client string, tlsPeer string) {
258258

259259
logParts := parser.Dump()
260260
logParts["client"] = client
261-
if logParts["hostname"] == "" && s.format == RFC3164 {
261+
if logParts["hostname"] == "" && (s.format == RFC3164 || s.format == Automatic) {
262262
if i := strings.Index(client, ":"); i > 1 {
263263
logParts["hostname"] = client[:i]
264264
} else {

server_test.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import (
77
"testing"
88
"time"
99

10-
. "gopkg.in/check.v1"
1110
"github.com/demisto/go-syslog/format"
11+
. "gopkg.in/check.v1"
1212
)
1313

1414
func Test(t *testing.T) { TestingT(t) }
@@ -19,6 +19,7 @@ type ServerSuite struct {
1919
var _ = Suite(&ServerSuite{})
2020
var exampleSyslog = "<31>Dec 26 05:08:46 hostname tag[296]: content"
2121
var exampleSyslogNoTSTagHost = "<14>INFO leaving (1) step postscripts"
22+
var exampleSyslogNoPriority = "Dec 26 05:08:46 hostname test with no priority - see rfc 3164 section 4.3.3"
2223
var exampleRFC5424Syslog = "<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 - 'su root' failed for lonvick on /dev/pts/8"
2324

2425
func (s *ServerSuite) TestTailFile(c *C) {
@@ -184,6 +185,24 @@ func (s *ServerSuite) TestUDP3164NoTag(c *C) {
184185
c.Check(handler.LastError, IsNil)
185186
}
186187

188+
func (s *ServerSuite) TestUDPAutomatic3164NoPriority(c *C) {
189+
handler := new(HandlerMock)
190+
server := NewServer()
191+
server.SetFormat(Automatic)
192+
server.SetHandler(handler)
193+
server.SetTimeout(10)
194+
server.goParseDatagrams()
195+
server.datagramChannel <- DatagramMessage{[]byte(exampleSyslogNoPriority), "127.0.0.1:45789"}
196+
close(server.datagramChannel)
197+
server.Wait()
198+
c.Check(handler.LastLogParts["hostname"], Equals, "127.0.0.1")
199+
c.Check(handler.LastLogParts["tag"], Equals, "")
200+
c.Check(handler.LastLogParts["priority"], Equals, 13)
201+
c.Check(handler.LastLogParts["content"], Equals, exampleSyslogNoPriority)
202+
c.Check(handler.LastMessageLength, Equals, int64(len(exampleSyslogNoPriority)))
203+
c.Check(handler.LastError, IsNil)
204+
}
205+
187206
func (s *ServerSuite) TestUDP6587(c *C) {
188207
handler := new(HandlerMock)
189208
server := NewServer()

0 commit comments

Comments
 (0)