diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-05 11:19:16 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-07-24 09:53:24 +0000 |
commit | b5f8ee61a7f7e9bd291dd26b0585d03eb686c941 (patch) | |
tree | d4d31289c39fc00da064a825df13a0b98ce95b10 /src/go/collectors/go.d.plugin/pkg/logs/ltsv.go | |
parent | Adding upstream version 1.44.3. (diff) | |
download | netdata-b5f8ee61a7f7e9bd291dd26b0585d03eb686c941.tar.xz netdata-b5f8ee61a7f7e9bd291dd26b0585d03eb686c941.zip |
Adding upstream version 1.46.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | src/go/collectors/go.d.plugin/pkg/logs/ltsv.go | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/src/go/collectors/go.d.plugin/pkg/logs/ltsv.go b/src/go/collectors/go.d.plugin/pkg/logs/ltsv.go new file mode 100644 index 000000000..b7fbceb14 --- /dev/null +++ b/src/go/collectors/go.d.plugin/pkg/logs/ltsv.go @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +package logs + +import ( + "bufio" + "errors" + "fmt" + "io" + "strconv" + "unsafe" + + "github.com/Wing924/ltsv" +) + +type ( + LTSVConfig struct { + FieldDelimiter string `yaml:"field_delimiter" json:"field_delimiter"` + ValueDelimiter string `yaml:"value_delimiter" json:"value_delimiter"` + Mapping map[string]string `yaml:"mapping" json:"mapping"` + } + + LTSVParser struct { + r *bufio.Reader + parser ltsv.Parser + mapping map[string]string + } +) + +func NewLTSVParser(config LTSVConfig, in io.Reader) (*LTSVParser, error) { + p := ltsv.Parser{ + FieldDelimiter: ltsv.DefaultParser.FieldDelimiter, + ValueDelimiter: ltsv.DefaultParser.ValueDelimiter, + StrictMode: false, + } + if config.FieldDelimiter != "" { + if d, err := parseLTSVDelimiter(config.FieldDelimiter); err == nil { + p.FieldDelimiter = d + } + } + if config.ValueDelimiter != "" { + if d, err := parseLTSVDelimiter(config.ValueDelimiter); err == nil { + p.ValueDelimiter = d + } + } + parser := <SVParser{ + r: bufio.NewReader(in), + parser: p, + mapping: config.Mapping, + } + return parser, nil +} + +func (p *LTSVParser) ReadLine(line LogLine) error { + row, err := p.r.ReadSlice('\n') + if err != nil && len(row) == 0 { + return err + } + if len(row) > 0 && row[len(row)-1] == '\n' { + row = row[:len(row)-1] + } + return p.Parse(row, line) +} + +func (p *LTSVParser) Parse(row []byte, line LogLine) error { + err := p.parser.ParseLine(row, func(label []byte, value []byte) error { + s := *(*string)(unsafe.Pointer(&label)) // no alloc, same as in fmt.Builder.String() + if v, ok := p.mapping[s]; ok { + s = v + } + return line.Assign(s, string(value)) + }) + if err != nil { + return &ParseError{msg: fmt.Sprintf("ltsv parse: %v", err), err: err} + } + return nil +} + +func (p LTSVParser) Info() string { + return fmt.Sprintf("ltsv: %q", p.mapping) +} + +func parseLTSVDelimiter(s string) (byte, error) { + if isNumber(s) { + d, err := strconv.ParseUint(s, 10, 8) + if err != nil { + return 0, fmt.Errorf("invalid LTSV delimiter: %v", err) + } + return byte(d), nil + } + if len(s) != 1 { + return 0, errors.New("invalid LTSV delimiter: must be a single character") + } + return s[0], nil +} |