diff --git a/inputs/gnmi/gnmi.go b/inputs/gnmi/gnmi.go index 695f6040..8480eed8 100644 --- a/inputs/gnmi/gnmi.go +++ b/inputs/gnmi/gnmi.go @@ -94,7 +94,8 @@ type Subscription struct { // Mark this subscription as a tag-only lookup source, not emitting any metric TagOnly bool `toml:"tag_only" deprecated:"1.25.0;2.0.0;please use 'tag_subscription's instead"` - DisableConcatenation bool `toml:"disable_concatenation"` + DisableConcatenation bool `toml:"disable_concatenation"` + Conversion string `toml:"conversion"` } // Tag Subscription for a gNMI client diff --git a/inputs/gnmi/handler.go b/inputs/gnmi/handler.go index 084dd09b..41803559 100644 --- a/inputs/gnmi/handler.go +++ b/inputs/gnmi/handler.go @@ -261,19 +261,38 @@ func (h *handler) handleSubscribeResponseUpdate(slist *types.SampleList, respons if strings.HasPrefix(name, inputName) { prefix = "" } + value := field.value disableConcatenating := false for _, sub := range h.subs { - if strings.HasSuffix(field.path.String(), sub.Path) { + base, _ := field.path.split() + if strings.HasSuffix(base, sub.Path) { // field.path => origin:path // sub.path => path disableConcatenating = sub.DisableConcatenation + switch sub.Conversion { + case "ieeefloat32": + switch val := field.value.(type) { + case string: + v, err := string2float32(val) + if err != nil { + } + + value = v + case []uint8: + v, err := bytes2float32(val) + if err != nil { + + } + value = v + } + } } } if !disableConcatenating { name = name + "_" + key } - sample := types.NewSample(prefix, name, field.value, tags).SetTime(timestamp) + sample := types.NewSample(prefix, name, value, tags).SetTime(timestamp) slist.PushFront(sample) } diff --git a/inputs/gnmi/ieeefloat32.go b/inputs/gnmi/ieeefloat32.go new file mode 100644 index 00000000..6c9ecc7a --- /dev/null +++ b/inputs/gnmi/ieeefloat32.go @@ -0,0 +1,39 @@ +package gnmi + +import ( + "encoding/base64" + "encoding/binary" + "fmt" + "math" +) + +func string2float32(base64Str string) (float32, error) { + // 解码Base64字符串 + decodedBytes, err := base64.StdEncoding.DecodeString(base64Str) + if err != nil { + return 0.0, fmt.Errorf("base64 string %s decode error: %v", base64Str, err) + } + + // 确保解码后的字节切片长度为4(32位) + if len(decodedBytes) != 4 { + return 0.0, fmt.Errorf("length after decoding is not 4 bytes, data type is not float32") + } + + // 将字节切片转换为uint32 + bits := binary.BigEndian.Uint32(decodedBytes) + + // 将uint32转换为float32 + return math.Float32frombits(bits), nil +} + +func bytes2float32(bytes []uint8) (float32, error) { + if len(bytes) != 4 { + return 0.0, fmt.Errorf("length after decoding is not 4 bytes, data type is not float32") + } + + // 将字节切片转换为uint32 + bits := binary.BigEndian.Uint32(bytes) + + // 将uint32转换为float32 + return math.Float32frombits(bits), nil +}