VictoriaMetrics/lib/logstorage/logfmt_parser.go
2024-06-04 01:49:02 +02:00

90 lines
1.3 KiB
Go

package logstorage
import (
"strings"
"sync"
)
type logfmtParser struct {
fields []Field
}
func (p *logfmtParser) reset() {
clear(p.fields)
p.fields = p.fields[:0]
}
func (p *logfmtParser) addField(name, value string) {
name = strings.TrimSpace(name)
if name == "" && value == "" {
return
}
p.fields = append(p.fields, Field{
Name: name,
Value: value,
})
}
func (p *logfmtParser) parse(s string) {
p.reset()
for {
// Search for field name
n := strings.IndexAny(s, "= ")
if n < 0 {
// empty value
p.addField(s, "")
return
}
name := s[:n]
ch := s[n]
s = s[n+1:]
if ch == ' ' {
// empty value
p.addField(name, "")
continue
}
if len(s) == 0 {
p.addField(name, "")
return
}
// Search for field value
value, nOffset := tryUnquoteString(s, "")
if nOffset >= 0 {
p.addField(name, value)
s = s[nOffset:]
if len(s) == 0 {
return
}
if s[0] != ' ' {
return
}
s = s[1:]
} else {
n := strings.IndexByte(s, ' ')
if n < 0 {
p.addField(name, s)
return
}
p.addField(name, s[:n])
s = s[n+1:]
}
}
}
func getLogfmtParser() *logfmtParser {
v := logfmtParserPool.Get()
if v == nil {
return &logfmtParser{}
}
return v.(*logfmtParser)
}
func putLogfmtParser(p *logfmtParser) {
p.reset()
logfmtParserPool.Put(p)
}
var logfmtParserPool sync.Pool