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
|