Like Prometheus, but for logs.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
loki/vendor/github.com/heroku/x/logplex/encoding/parser.go

58 lines
1.6 KiB

package encoding
import (
"bufio"
"bytes"
"strconv"
"github.com/pkg/errors"
)
// SyslogSplitFunc splits the data based on the defined length prefix.
// format:
//nolint:lll
// 64 <190>1 2019-07-20T17:50:10.879238Z shuttle token shuttle - - 99\n65 <190>1 2019-07-20T17:50:10.879238Z shuttle token shuttle - - 100\n
// ^ frame size ^ boundary
func SyslogSplitFunc(data []byte, atEOF bool) (advance int, token []byte, err error) {
// first space gives us the frame size
sp := bytes.IndexByte(data, ' ')
if sp == -1 {
if atEOF && len(data) > 0 {
return 0, nil, errors.Wrap(ErrBadFrame, "missing frame length")
}
return 0, nil, nil
}
if sp == 0 {
return 0, nil, errors.Wrap(ErrBadFrame, "invalid frame length")
}
msgSize, err := strconv.ParseUint(string(data[0:sp]), 10, 64)
if err != nil {
return 0, nil, errors.Wrap(ErrBadFrame, "couldnt parse frame length")
}
// 1 here is the 'space' itself, used in the framing above
dataBoundary := sp + int(msgSize) + 1
if dataBoundary > len(data) {
if atEOF {
return 0, nil, errors.Wrapf(ErrBadFrame, "message boundary (%d) not respected length (%d)", dataBoundary, len(data))
}
return 0, nil, nil
}
return dataBoundary, data[sp+1 : dataBoundary], nil
}
// TruncatingSyslogSplitFunc enforces a maximum line length after parsing.
func TruncatingSyslogSplitFunc(maxLength int) bufio.SplitFunc {
return func(data []byte, atEOF bool) (advance int, token []byte, err error) {
advance, token, err = SyslogSplitFunc(data, atEOF)
if len(token) > maxLength {
token = token[0:maxLength]
}
return
}
}