11package syslogacquisition
22
33import (
4+ "bytes"
45 "context"
56 "errors"
67 "fmt"
@@ -27,6 +28,7 @@ type SyslogConfiguration struct {
2728 Port int `yaml:"listen_port,omitempty"`
2829 Addr string `yaml:"listen_addr,omitempty"`
2930 MaxMessageLen int `yaml:"max_message_len,omitempty"`
31+ DisableRFCParser bool `yaml:"disable_rfc_parser,omitempty"` // if true, we don't try to be smart and just remove the PRI
3032 configuration.DataSourceCommonCfg `yaml:",inline"`
3133}
3234
@@ -182,6 +184,66 @@ func (s *SyslogSource) buildLogFromSyslog(ts time.Time, hostname string,
182184 return ret
183185}
184186
187+ func (s * SyslogSource ) parseLine (syslogLine syslogserver.SyslogMessage ) string {
188+ var line string
189+
190+ logger := s .logger .WithField ("client" , syslogLine .Client )
191+ logger .Tracef ("raw: %s" , syslogLine )
192+ if s .metricsLevel != configuration .METRICS_NONE {
193+ linesReceived .With (prometheus.Labels {"source" : syslogLine .Client }).Inc ()
194+ }
195+ if ! s .config .DisableRFCParser {
196+ p := rfc3164 .NewRFC3164Parser (rfc3164 .WithCurrentYear ())
197+ err := p .Parse (syslogLine .Message )
198+ if err != nil {
199+ logger .Debugf ("could not parse as RFC3164 (%s)" , err )
200+ p2 := rfc5424 .NewRFC5424Parser ()
201+ err = p2 .Parse (syslogLine .Message )
202+ if err != nil {
203+ logger .Errorf ("could not parse message: %s" , err )
204+ logger .Debugf ("could not parse as RFC5424 (%s) : %s" , err , syslogLine .Message )
205+ return ""
206+ }
207+ line = s .buildLogFromSyslog (p2 .Timestamp , p2 .Hostname , p2 .Tag , p2 .PID , p2 .Message )
208+ if s .metricsLevel != configuration .METRICS_NONE {
209+ linesParsed .With (prometheus.Labels {"source" : syslogLine .Client , "type" : "rfc5424" }).Inc ()
210+ }
211+ } else {
212+ line = s .buildLogFromSyslog (p .Timestamp , p .Hostname , p .Tag , p .PID , p .Message )
213+ if s .metricsLevel != configuration .METRICS_NONE {
214+ linesParsed .With (prometheus.Labels {"source" : syslogLine .Client , "type" : "rfc3164" }).Inc ()
215+ }
216+ }
217+ } else {
218+ if len (syslogLine .Message ) < 3 {
219+ logger .Errorf ("malformated message, missing PRI (message too short)" )
220+ return ""
221+ }
222+ if syslogLine .Message [0 ] != '<' {
223+ logger .Errorf ("malformated message, missing PRI beginning" )
224+ return ""
225+ }
226+ priEnd := bytes .Index (syslogLine .Message , []byte (">" ))
227+ if priEnd == - 1 {
228+ logger .Errorf ("malformated message, missing PRI end" )
229+ return ""
230+ }
231+ if priEnd > 4 {
232+ logger .Errorf ("malformated message, PRI too long" )
233+ return ""
234+ }
235+ for i := 1 ; i < priEnd ; i ++ {
236+ if syslogLine .Message [i ] < '0' || syslogLine .Message [i ] > '9' {
237+ logger .Errorf ("malformated message, PRI not a number" )
238+ return ""
239+ }
240+ }
241+ line = string (syslogLine .Message [priEnd + 1 :])
242+ }
243+
244+ return strings .TrimSuffix (line , "\n " )
245+ }
246+
185247func (s * SyslogSource ) handleSyslogMsg (out chan types.Event , t * tomb.Tomb , c chan syslogserver.SyslogMessage ) error {
186248 killed := false
187249 for {
@@ -196,37 +258,12 @@ func (s *SyslogSource) handleSyslogMsg(out chan types.Event, t *tomb.Tomb, c cha
196258 s .logger .Info ("Syslog server has exited" )
197259 return nil
198260 case syslogLine := <- c :
199- var line string
200- var ts time.Time
201-
202- logger := s .logger .WithField ("client" , syslogLine .Client )
203- logger .Tracef ("raw: %s" , syslogLine )
204- if s .metricsLevel != configuration .METRICS_NONE {
205- linesReceived .With (prometheus.Labels {"source" : syslogLine .Client }).Inc ()
206- }
207- p := rfc3164 .NewRFC3164Parser (rfc3164 .WithCurrentYear ())
208- err := p .Parse (syslogLine .Message )
209- if err != nil {
210- logger .Debugf ("could not parse as RFC3164 (%s)" , err )
211- p2 := rfc5424 .NewRFC5424Parser ()
212- err = p2 .Parse (syslogLine .Message )
213- if err != nil {
214- logger .Errorf ("could not parse message: %s" , err )
215- logger .Debugf ("could not parse as RFC5424 (%s) : %s" , err , syslogLine .Message )
216- continue
217- }
218- line = s .buildLogFromSyslog (p2 .Timestamp , p2 .Hostname , p2 .Tag , p2 .PID , p2 .Message )
219- if s .metricsLevel != configuration .METRICS_NONE {
220- linesParsed .With (prometheus.Labels {"source" : syslogLine .Client , "type" : "rfc5424" }).Inc ()
221- }
222- } else {
223- line = s .buildLogFromSyslog (p .Timestamp , p .Hostname , p .Tag , p .PID , p .Message )
224- if s .metricsLevel != configuration .METRICS_NONE {
225- linesParsed .With (prometheus.Labels {"source" : syslogLine .Client , "type" : "rfc3164" }).Inc ()
226- }
261+ line := s .parseLine (syslogLine )
262+ if line == "" {
263+ continue
227264 }
228265
229- line = strings . TrimSuffix ( line , " \n " )
266+ var ts time. Time
230267
231268 l := types.Line {}
232269 l .Raw = line
0 commit comments