VictoriaMetrics/lib/logstorage/logfmt_parser.go

90 lines
1.3 KiB
Go
Raw Normal View History

2024-05-22 19:01:20 +00:00
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) {
2024-06-03 22:59:25 +00:00
name = strings.TrimSpace(name)
if name == "" && value == "" {
return
}
2024-05-22 19:01:20 +00:00
p.fields = append(p.fields, Field{
Name: name,
Value: value,
})
}
func (p *logfmtParser) parse(s string) {
2024-06-03 22:59:25 +00:00
p.reset()
2024-05-22 19:01:20 +00:00
for {
// Search for field name
2024-06-03 22:59:25 +00:00
n := strings.IndexAny(s, "= ")
2024-05-22 19:01:20 +00:00
if n < 0 {
2024-06-03 22:59:25 +00:00
// empty value
p.addField(s, "")
2024-05-22 19:01:20 +00:00
return
}
2024-06-03 22:59:25 +00:00
name := s[:n]
ch := s[n]
2024-05-22 19:01:20 +00:00
s = s[n+1:]
2024-06-03 22:59:25 +00:00
if ch == ' ' {
// empty value
p.addField(name, "")
continue
}
2024-05-22 19:01:20 +00:00
if len(s) == 0 {
p.addField(name, "")
return
}
// Search for field value
2024-05-24 01:06:55 +00:00
value, nOffset := tryUnquoteString(s, "")
2024-05-22 19:01:20 +00:00
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