feat(parsers.xpath): Add option to store fields as base64 (#13690)

This commit is contained in:
Lucas Chiesa 2023-07-28 16:09:23 +02:00 committed by GitHub
parent 1f3b7e86ef
commit 3f8e916455
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 51 additions and 2 deletions

View File

@ -162,6 +162,11 @@ XPath expressions.
## By default, all byte-array-fields are converted to string.
# fields_bytes_as_hex = []
## Optional: List of fields to convert to base64-strings if they
## contain byte-arrays. Resulting string will generally be shorter
## than using hex encoding. Base64 encoding is RFC4648 compliant.
# fields_bytes_as_base64 = []
## Tag definitions using the given XPath queries.
[inputs.file.xpath.tags]
name = "substring-after(Sensor/@name, ' ')"

View File

@ -1,6 +1,7 @@
package xpath
import (
"encoding/base64"
"encoding/hex"
"errors"
"fmt"
@ -66,6 +67,7 @@ type Config struct {
Fields map[string]string `toml:"fields"`
FieldsInt map[string]string `toml:"fields_int"`
FieldsHex []string `toml:"fields_bytes_as_hex"`
FieldsBase64 []string `toml:"fields_bytes_as_base64"`
FieldSelection string `toml:"field_selection"`
FieldNameQuery string `toml:"field_name"`
@ -77,8 +79,9 @@ type Config struct {
TagValueQuery string `toml:"tag_value"`
TagNameExpand bool `toml:"tag_name_expansion"`
FieldsHexFilter filter.Filter
Location *time.Location
FieldsHexFilter filter.Filter
FieldsBase64Filter filter.Filter
Location *time.Location
}
func (p *Parser) Init() error {
@ -175,6 +178,12 @@ func (p *Parser) Init() error {
}
config.FieldsHexFilter = f
bf, err := filter.Compile(config.FieldsBase64)
if err != nil {
return fmt.Errorf("creating base64-fields filter failed: %w", err)
}
config.FieldsBase64Filter = bf
p.Configs[i] = config
}
@ -420,6 +429,9 @@ func (p *Parser) parseQuery(starttime time.Time, doc, selected dataNode, config
if config.FieldsHexFilter != nil && config.FieldsHexFilter.Match(name) {
v = hex.EncodeToString(b)
}
if config.FieldsBase64Filter != nil && config.FieldsBase64Filter.Match(name) {
v = base64.StdEncoding.EncodeToString(b)
}
} else {
v = fmt.Sprintf("%v", v)
}
@ -477,6 +489,9 @@ func (p *Parser) parseQuery(starttime time.Time, doc, selected dataNode, config
if config.FieldsHexFilter != nil && config.FieldsHexFilter.Match(name) {
v = hex.EncodeToString(b)
}
if config.FieldsBase64Filter != nil && config.FieldsBase64Filter.Match(name) {
v = base64.StdEncoding.EncodeToString(b)
}
} else {
v = fmt.Sprintf("%v", v)
}

View File

@ -0,0 +1 @@
data str_a="this is a test",str_b="foobar",bytes_a="0001020304050607",fielda="AAECAwQFBgc=",bytes_b="Zm9vYmFy",timestamp=1687852514u 1687852514000000000

View File

@ -0,0 +1,28 @@
# Example data:
# [
# {
# "str_a": bytearray("this is a test"),
# "str_b": bytearray("foobar"),
# "bytes_a": bytearray([0, 1, 2, 3, 4, 5, 6, 7]),
# "bytes_b": bytearray("foobar"),
# "timestamp": 1687852514
# }
# ]
[[inputs.file]]
files = ["./testcases/cbor_base64_encoding/data.bin"]
data_format = "xpath_cbor"
xpath_native_types = true
[[inputs.file.xpath]]
metric_name = "'data'"
metric_selection = "child::*"
timestamp = "timestamp"
timestamp_format = "unix"
field_selection = "child::*"
fields_bytes_as_base64 = ["bytes_b", "field*"]
fields_bytes_as_hex = ["bytes_a"]
[inputs.file.xpath.fields]
fielda = "bytes_a"