Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(processors.converter): added support for base64 encoded ieee float32 types #16214

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/LICENSE_OF_DEPENDENCIES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ following works:
- collectd.org [ISC License](https://github.com/collectd/go-collectd/blob/master/LICENSE)
- dario.cat/mergo [BSD 3-Clause "New" or "Revised" License](https://github.com/imdario/mergo/blob/master/LICENSE)
- filippo.io/edwards25519 [BSD 3-Clause "New" or "Revised" License](https://github.com/FiloSottile/edwards25519/blob/main/LICENSE)
- github.com/99designs/go-keychain [MIT License](https://github.com/99designs/go-keychain/blob/master/LICENSE)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you remove these changes? They don't seem to be needed and are causing a linter test failure

- github.com/99designs/keyring [MIT License](https://github.com/99designs/keyring/blob/master/LICENSE)
- github.com/Azure/azure-amqp-common-go [MIT License](https://github.com/Azure/azure-amqp-common-go/blob/master/LICENSE)
- github.com/Azure/azure-event-hubs-go [MIT License](https://github.com/Azure/azure-event-hubs-go/blob/master/LICENSE)
Expand Down Expand Up @@ -139,6 +140,7 @@ following works:
- github.com/gabriel-vasile/mimetype [MIT License](https://github.com/gabriel-vasile/mimetype/blob/master/LICENSE)
- github.com/go-asn1-ber/asn1-ber [MIT License](https://github.com/go-asn1-ber/asn1-ber/blob/v1.3/LICENSE)
- github.com/go-chi/chi [MIT License](https://github.com/go-chi/chi/blob/master/LICENSE)
- github.com/go-darwin/apfs [BSD 3-Clause "New" or "Revised" License](https://github.com/go-darwin/apfs/blob/main/LICENSE)
- github.com/go-git/go-billy [Apache License 2.0](https://github.com/go-git/go-billy/blob/master/LICENSE)
- github.com/go-ldap/ldap [MIT License](https://github.com/go-ldap/ldap/blob/v3.4.1/LICENSE)
- github.com/go-logfmt/logfmt [MIT License](https://github.com/go-logfmt/logfmt/blob/master/LICENSE)
Expand Down
10 changes: 8 additions & 2 deletions plugins/processors/converter/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Converter Processor Plugin

The converter processor is used to change the type of tag or field values. In
The converter processor is used to change the type of tag or field values. In
addition to changing field types it can convert between fields and tags.

Values that cannot be converted are dropped.

**Note:** When converting tags to fields, take care to ensure the series is
still uniquely identifiable. Fields with the same series key (measurement +
still uniquely identifiable. Fields with the same series key (measurement +
tags) will overwrite one another.

**Note on large strings being converted to numeric types:** When converting a
Expand Down Expand Up @@ -67,6 +67,12 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
boolean = []
float = []

# Optional field to use for converting base64 encoding of IEEE 754 Float32 values
# i.e. data_json_content_state_openconfig-platform-psu:output-power":"RKeAAA=="
# into a float32 value 1340

# base64_ieee_float32 = []

## Optional field to use as metric timestamp
# timestamp = []

Expand Down
78 changes: 61 additions & 17 deletions plugins/processors/converter/converter.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ package converter

import (
_ "embed"
"encoding/base64"
"errors"
"fmt"
"math"
"math/big"
"strconv"
"strings"

"github.com/influxdata/telegraf"
Expand All @@ -18,15 +21,16 @@ import (
var sampleConfig string

type Conversion struct {
Measurement []string `toml:"measurement"`
Tag []string `toml:"tag"`
String []string `toml:"string"`
Integer []string `toml:"integer"`
Unsigned []string `toml:"unsigned"`
Boolean []string `toml:"boolean"`
Float []string `toml:"float"`
Timestamp []string `toml:"timestamp"`
TimestampFormat string `toml:"timestamp_format"`
Measurement []string `toml:"measurement"`
Tag []string `toml:"tag"`
String []string `toml:"string"`
Integer []string `toml:"integer"`
Unsigned []string `toml:"unsigned"`
Boolean []string `toml:"boolean"`
Float []string `toml:"float"`
Timestamp []string `toml:"timestamp"`
TimestampFormat string `toml:"timestamp_format"`
Base64IEEEFloat32 []string `toml:"base64_ieee_float32"`
}

type Converter struct {
Expand All @@ -39,14 +43,15 @@ type Converter struct {
}

type ConversionFilter struct {
Measurement filter.Filter
Tag filter.Filter
String filter.Filter
Integer filter.Filter
Unsigned filter.Filter
Boolean filter.Filter
Float filter.Filter
Timestamp filter.Filter
Measurement filter.Filter
Tag filter.Filter
String filter.Filter
Integer filter.Filter
Unsigned filter.Filter
Boolean filter.Filter
Float filter.Filter
Timestamp filter.Filter
Base64IEEEFloat32 filter.Filter
}

func (*Converter) SampleConfig() string {
Expand Down Expand Up @@ -132,6 +137,11 @@ func compileFilter(conv *Conversion) (*ConversionFilter, error) {
return nil, err
}

cf.Base64IEEEFloat32, err = filter.Compile(conv.Base64IEEEFloat32)
if err != nil {
return nil, err
}

return cf, nil
}

Expand Down Expand Up @@ -249,6 +259,14 @@ func (p *Converter) convertFields(metric telegraf.Metric) {
metric.SetTime(time)
metric.RemoveField(key)
}

case p.fieldConversions.Base64IEEEFloat32 != nil && p.fieldConversions.Base64IEEEFloat32.Match(key):
if v, err := base64ToFloat32(value.(string)); err != nil {
p.Log.Errorf("Converting to base64_ieee_float32 [%T] failed: %v", value, err)
metric.RemoveField(key)
} else {
metric.AddField(key, v)
}
}
}
}
Expand Down Expand Up @@ -345,6 +363,32 @@ func toFloat(v interface{}) (float64, error) {
return internal.ToFloat64(v)
}

func base64ToFloat32(encoded string) (float32, error) {
// Decode the Base64 string to bytes
decodedBytes, err := base64.StdEncoding.DecodeString(encoded)
if err != nil {
return 0, err
}

// Check if the byte length matches a float32 (4 bytes)
if len(decodedBytes) != 4 {
return 0, errors.New("decoded byte length is not 4 bytes")
}

// Convert the bytes to a string representation as per IEEE 754 of the bits
bitsStrRepresentation := fmt.Sprintf("%08b%08b%08b%08b", decodedBytes[0], decodedBytes[1], decodedBytes[2], decodedBytes[3])

// Convert the bits to a uint32
bits, err := strconv.ParseUint(bitsStrRepresentation, 2, 32)

if err != nil {
return 0, err
}

// Convert the uint32 (bits) to a float32 based on IEEE 754 binary representation
return math.Float32frombits(uint32(bits)), nil
}

func init() {
processors.Add("converter", func() telegraf.Processor {
return &Converter{}
Expand Down
28 changes: 28 additions & 0 deletions plugins/processors/converter/converter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -770,6 +770,34 @@ func TestMeasurement(t *testing.T) {
),
},
},
{
name: "float32 from ieee754 float32 encoded as base64",
converter: &Converter{
Fields: &Conversion{
Base64IEEEFloat32: []string{"a", "b"},
},
},
input: testutil.MustMetric(
"cpu",
map[string]string{},
map[string]interface{}{
"a": "QlAAAA==",
"b": "QlgAAA==",
},
time.Unix(0, 0),
),
expected: []telegraf.Metric{
testutil.MustMetric(
"cpu",
map[string]string{},
map[string]interface{}{
"a": float32(52),
"b": float32(54),
},
time.Unix(0, 0),
),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
6 changes: 6 additions & 0 deletions plugins/processors/converter/sample.conf
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@
boolean = []
float = []

# Optional field to use for converting base64 encoding of IEEE 754 Float32 values
# i.e. data_json_content_state_openconfig-platform-psu:output-power":"RKeAAA=="
# into a float32 value 1340

# base64_ieee_float32 = []

## Optional field to use as metric timestamp
# timestamp = []

Expand Down
Loading