chore(processors.converter): Cleanup code (#14744)
This commit is contained in:
parent
ad9b771e50
commit
298a1d4396
|
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var ErrOutOfRange = strconv.ErrRange
|
||||
|
|
@ -103,6 +104,9 @@ func ToFloat32(value interface{}) (float32, error) {
|
|||
func ToUint64(value interface{}) (uint64, error) {
|
||||
switch v := value.(type) {
|
||||
case string:
|
||||
if strings.HasPrefix(v, "0x") {
|
||||
return strconv.ParseUint(strings.TrimPrefix(v, "0x"), 16, 64)
|
||||
}
|
||||
return strconv.ParseUint(v, 10, 64)
|
||||
case []byte:
|
||||
return strconv.ParseUint(string(v), 10, 64)
|
||||
|
|
@ -167,6 +171,10 @@ func ToUint64(value interface{}) (uint64, error) {
|
|||
func ToUint32(value interface{}) (uint32, error) {
|
||||
switch v := value.(type) {
|
||||
case string:
|
||||
if strings.HasPrefix(v, "0x") {
|
||||
x, err := strconv.ParseUint(strings.TrimPrefix(v, "0x"), 16, 32)
|
||||
return uint32(x), err
|
||||
}
|
||||
x, err := strconv.ParseUint(v, 10, 32)
|
||||
return uint32(x), err
|
||||
case []byte:
|
||||
|
|
@ -237,6 +245,10 @@ func ToUint32(value interface{}) (uint32, error) {
|
|||
func ToUint16(value interface{}) (uint16, error) {
|
||||
switch v := value.(type) {
|
||||
case string:
|
||||
if strings.HasPrefix(v, "0x") {
|
||||
x, err := strconv.ParseUint(strings.TrimPrefix(v, "0x"), 16, 16)
|
||||
return uint16(x), err
|
||||
}
|
||||
x, err := strconv.ParseUint(v, 10, 32)
|
||||
return uint16(x), err
|
||||
case []byte:
|
||||
|
|
@ -310,6 +322,10 @@ func ToUint16(value interface{}) (uint16, error) {
|
|||
func ToUint8(value interface{}) (uint8, error) {
|
||||
switch v := value.(type) {
|
||||
case string:
|
||||
if strings.HasPrefix(v, "0x") {
|
||||
x, err := strconv.ParseUint(strings.TrimPrefix(v, "0x"), 16, 8)
|
||||
return uint8(x), err
|
||||
}
|
||||
x, err := strconv.ParseUint(v, 10, 32)
|
||||
return uint8(x), err
|
||||
case []byte:
|
||||
|
|
@ -386,6 +402,9 @@ func ToUint8(value interface{}) (uint8, error) {
|
|||
func ToInt64(value interface{}) (int64, error) {
|
||||
switch v := value.(type) {
|
||||
case string:
|
||||
if strings.HasPrefix(v, "0x") {
|
||||
return strconv.ParseInt(strings.TrimPrefix(v, "0x"), 16, 64)
|
||||
}
|
||||
return strconv.ParseInt(v, 10, 64)
|
||||
case []byte:
|
||||
return strconv.ParseInt(string(v), 10, 64)
|
||||
|
|
@ -441,6 +460,10 @@ func ToInt64(value interface{}) (int64, error) {
|
|||
func ToInt32(value interface{}) (int32, error) {
|
||||
switch v := value.(type) {
|
||||
case string:
|
||||
if strings.HasPrefix(v, "0x") {
|
||||
x, err := strconv.ParseInt(strings.TrimPrefix(v, "0x"), 16, 32)
|
||||
return int32(x), err
|
||||
}
|
||||
x, err := strconv.ParseInt(v, 10, 32)
|
||||
return int32(x), err
|
||||
case []byte:
|
||||
|
|
@ -508,6 +531,10 @@ func ToInt32(value interface{}) (int32, error) {
|
|||
func ToInt16(value interface{}) (int16, error) {
|
||||
switch v := value.(type) {
|
||||
case string:
|
||||
if strings.HasPrefix(v, "0x") {
|
||||
x, err := strconv.ParseInt(strings.TrimPrefix(v, "0x"), 16, 16)
|
||||
return int16(x), err
|
||||
}
|
||||
x, err := strconv.ParseInt(v, 10, 32)
|
||||
return int16(x), err
|
||||
case []byte:
|
||||
|
|
@ -578,6 +605,10 @@ func ToInt16(value interface{}) (int16, error) {
|
|||
func ToInt8(value interface{}) (int8, error) {
|
||||
switch v := value.(type) {
|
||||
case string:
|
||||
if strings.HasPrefix(v, "0x") {
|
||||
x, err := strconv.ParseInt(strings.TrimPrefix(v, "0x"), 16, 8)
|
||||
return int8(x), err
|
||||
}
|
||||
x, err := strconv.ParseInt(v, 10, 32)
|
||||
return int8(x), err
|
||||
case []byte:
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import (
|
|||
"errors"
|
||||
"math"
|
||||
"math/big"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
|
|
@ -143,80 +142,46 @@ func (p *Converter) convertTags(metric telegraf.Metric) {
|
|||
}
|
||||
|
||||
for key, value := range metric.Tags() {
|
||||
if p.tagConversions.Measurement != nil && p.tagConversions.Measurement.Match(key) {
|
||||
metric.RemoveTag(key)
|
||||
switch {
|
||||
case p.tagConversions.Measurement != nil && p.tagConversions.Measurement.Match(key):
|
||||
metric.SetName(value)
|
||||
continue
|
||||
}
|
||||
|
||||
if p.tagConversions.String != nil && p.tagConversions.String.Match(key) {
|
||||
metric.RemoveTag(key)
|
||||
case p.tagConversions.String != nil && p.tagConversions.String.Match(key):
|
||||
metric.AddField(key, value)
|
||||
case p.tagConversions.Integer != nil && p.tagConversions.Integer.Match(key):
|
||||
if v, err := toInteger(value); err != nil {
|
||||
p.Log.Errorf("Converting to integer [%T] failed: %v", value, err)
|
||||
} else {
|
||||
metric.AddField(key, v)
|
||||
}
|
||||
case p.tagConversions.Unsigned != nil && p.tagConversions.Unsigned.Match(key):
|
||||
if v, err := toUnsigned(value); err != nil {
|
||||
p.Log.Errorf("Converting to unsigned [%T] failed: %v", value, err)
|
||||
} else {
|
||||
metric.AddField(key, v)
|
||||
}
|
||||
case p.tagConversions.Boolean != nil && p.tagConversions.Boolean.Match(key):
|
||||
if v, err := internal.ToBool(value); err != nil {
|
||||
p.Log.Errorf("Converting to boolean [%T] failed: %v", value, err)
|
||||
} else {
|
||||
metric.AddField(key, v)
|
||||
}
|
||||
case p.tagConversions.Float != nil && p.tagConversions.Float.Match(key):
|
||||
if v, err := toFloat(value); err != nil {
|
||||
p.Log.Errorf("Converting to float [%T] failed: %v", value, err)
|
||||
} else {
|
||||
metric.AddField(key, v)
|
||||
}
|
||||
case p.tagConversions.Timestamp != nil && p.tagConversions.Timestamp.Match(key):
|
||||
if time, err := internal.ParseTimestamp(p.Tags.TimestampFormat, value, nil); err != nil {
|
||||
p.Log.Errorf("Converting to timestamp [%T] failed: %v", value, err)
|
||||
continue
|
||||
} else {
|
||||
metric.SetTime(time)
|
||||
}
|
||||
default:
|
||||
continue
|
||||
}
|
||||
|
||||
if p.tagConversions.Integer != nil && p.tagConversions.Integer.Match(key) {
|
||||
v, ok := toInteger(value)
|
||||
if !ok {
|
||||
metric.RemoveTag(key)
|
||||
p.Log.Errorf("error converting to integer [%T]: %v", value, value)
|
||||
continue
|
||||
}
|
||||
|
||||
metric.RemoveTag(key)
|
||||
metric.AddField(key, v)
|
||||
}
|
||||
|
||||
if p.tagConversions.Unsigned != nil && p.tagConversions.Unsigned.Match(key) {
|
||||
v, ok := toUnsigned(value)
|
||||
if !ok {
|
||||
metric.RemoveTag(key)
|
||||
p.Log.Errorf("error converting to unsigned [%T]: %v", value, value)
|
||||
continue
|
||||
}
|
||||
|
||||
metric.RemoveTag(key)
|
||||
metric.AddField(key, v)
|
||||
continue
|
||||
}
|
||||
|
||||
if p.tagConversions.Boolean != nil && p.tagConversions.Boolean.Match(key) {
|
||||
v, ok := toBool(value)
|
||||
if !ok {
|
||||
metric.RemoveTag(key)
|
||||
p.Log.Errorf("error converting to boolean [%T]: %v", value, value)
|
||||
continue
|
||||
}
|
||||
|
||||
metric.RemoveTag(key)
|
||||
metric.AddField(key, v)
|
||||
continue
|
||||
}
|
||||
|
||||
if p.tagConversions.Float != nil && p.tagConversions.Float.Match(key) {
|
||||
v, ok := toFloat(value)
|
||||
if !ok {
|
||||
metric.RemoveTag(key)
|
||||
p.Log.Errorf("error converting to float [%T]: %v", value, value)
|
||||
continue
|
||||
}
|
||||
|
||||
metric.RemoveTag(key)
|
||||
metric.AddField(key, v)
|
||||
continue
|
||||
}
|
||||
|
||||
if p.tagConversions.Timestamp != nil && p.tagConversions.Timestamp.Match(key) {
|
||||
time, err := internal.ParseTimestamp(p.Tags.TimestampFormat, value, nil)
|
||||
if err != nil {
|
||||
p.Log.Errorf("error converting to timestamp [%T]: %v", value, value)
|
||||
continue
|
||||
}
|
||||
|
||||
metric.RemoveTag(key)
|
||||
metric.SetTime(time)
|
||||
continue
|
||||
}
|
||||
metric.RemoveTag(key)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -227,277 +192,157 @@ func (p *Converter) convertFields(metric telegraf.Metric) {
|
|||
}
|
||||
|
||||
for key, value := range metric.Fields() {
|
||||
if p.fieldConversions.Measurement != nil && p.fieldConversions.Measurement.Match(key) {
|
||||
v, ok := toString(value)
|
||||
if !ok {
|
||||
switch {
|
||||
case p.fieldConversions.Measurement != nil && p.fieldConversions.Measurement.Match(key):
|
||||
if v, err := internal.ToString(value); err != nil {
|
||||
p.Log.Errorf("Converting to measurement [%T] failed: %v", value, err)
|
||||
} else {
|
||||
metric.SetName(v)
|
||||
}
|
||||
metric.RemoveField(key)
|
||||
case p.fieldConversions.Tag != nil && p.fieldConversions.Tag.Match(key):
|
||||
if v, err := internal.ToString(value); err != nil {
|
||||
p.Log.Errorf("Converting to tag [%T] failed: %v", value, err)
|
||||
} else {
|
||||
metric.AddTag(key, v)
|
||||
}
|
||||
metric.RemoveField(key)
|
||||
case p.fieldConversions.Float != nil && p.fieldConversions.Float.Match(key):
|
||||
if v, err := toFloat(value); err != nil {
|
||||
p.Log.Errorf("Converting to float [%T] failed: %v", value, err)
|
||||
metric.RemoveField(key)
|
||||
p.Log.Errorf("error converting to measurement [%T]: %v", value, value)
|
||||
continue
|
||||
} else {
|
||||
metric.AddField(key, v)
|
||||
}
|
||||
|
||||
metric.RemoveField(key)
|
||||
metric.SetName(v)
|
||||
continue
|
||||
}
|
||||
|
||||
if p.fieldConversions.Tag != nil && p.fieldConversions.Tag.Match(key) {
|
||||
v, ok := toString(value)
|
||||
if !ok {
|
||||
case p.fieldConversions.Integer != nil && p.fieldConversions.Integer.Match(key):
|
||||
if v, err := toInteger(value); err != nil {
|
||||
p.Log.Errorf("Converting to integer [%T] failed: %v", value, err)
|
||||
metric.RemoveField(key)
|
||||
p.Log.Errorf("error converting to tag [%T]: %v", value, value)
|
||||
continue
|
||||
} else {
|
||||
metric.AddField(key, v)
|
||||
}
|
||||
|
||||
metric.RemoveField(key)
|
||||
metric.AddTag(key, v)
|
||||
continue
|
||||
}
|
||||
|
||||
if p.fieldConversions.Float != nil && p.fieldConversions.Float.Match(key) {
|
||||
v, ok := toFloat(value)
|
||||
if !ok {
|
||||
case p.fieldConversions.Unsigned != nil && p.fieldConversions.Unsigned.Match(key):
|
||||
if v, err := toUnsigned(value); err != nil {
|
||||
p.Log.Errorf("Converting to unsigned [%T] failed: %v", value, err)
|
||||
metric.RemoveField(key)
|
||||
p.Log.Errorf("error converting to float [%T]: %v", value, value)
|
||||
continue
|
||||
} else {
|
||||
metric.AddField(key, v)
|
||||
}
|
||||
|
||||
metric.RemoveField(key)
|
||||
metric.AddField(key, v)
|
||||
continue
|
||||
}
|
||||
|
||||
if p.fieldConversions.Integer != nil && p.fieldConversions.Integer.Match(key) {
|
||||
v, ok := toInteger(value)
|
||||
if !ok {
|
||||
case p.fieldConversions.Boolean != nil && p.fieldConversions.Boolean.Match(key):
|
||||
if v, err := internal.ToBool(value); err != nil {
|
||||
p.Log.Errorf("Converting to bool [%T] failed: %v", value, err)
|
||||
metric.RemoveField(key)
|
||||
p.Log.Errorf("error converting to integer [%T]: %v", value, value)
|
||||
continue
|
||||
} else {
|
||||
metric.AddField(key, v)
|
||||
}
|
||||
|
||||
metric.RemoveField(key)
|
||||
metric.AddField(key, v)
|
||||
continue
|
||||
}
|
||||
|
||||
if p.fieldConversions.Unsigned != nil && p.fieldConversions.Unsigned.Match(key) {
|
||||
v, ok := toUnsigned(value)
|
||||
if !ok {
|
||||
case p.fieldConversions.String != nil && p.fieldConversions.String.Match(key):
|
||||
if v, err := internal.ToString(value); err != nil {
|
||||
p.Log.Errorf("Converting to string [%T] failed: %v", value, err)
|
||||
metric.RemoveField(key)
|
||||
p.Log.Errorf("error converting to unsigned [%T]: %v", value, value)
|
||||
continue
|
||||
} else {
|
||||
metric.AddField(key, v)
|
||||
}
|
||||
|
||||
metric.RemoveField(key)
|
||||
metric.AddField(key, v)
|
||||
continue
|
||||
}
|
||||
|
||||
if p.fieldConversions.Boolean != nil && p.fieldConversions.Boolean.Match(key) {
|
||||
v, ok := toBool(value)
|
||||
if !ok {
|
||||
case p.fieldConversions.Timestamp != nil && p.fieldConversions.Timestamp.Match(key):
|
||||
if time, err := internal.ParseTimestamp(p.Fields.TimestampFormat, value, nil); err != nil {
|
||||
p.Log.Errorf("Converting to timestamp [%T] failed: %v", value, err)
|
||||
} else {
|
||||
metric.SetTime(time)
|
||||
metric.RemoveField(key)
|
||||
p.Log.Errorf("error converting to bool [%T]: %v", value, value)
|
||||
continue
|
||||
}
|
||||
|
||||
metric.RemoveField(key)
|
||||
metric.AddField(key, v)
|
||||
continue
|
||||
}
|
||||
|
||||
if p.fieldConversions.String != nil && p.fieldConversions.String.Match(key) {
|
||||
v, ok := toString(value)
|
||||
if !ok {
|
||||
metric.RemoveField(key)
|
||||
p.Log.Errorf("Error converting to string [%T]: %v", value, value)
|
||||
continue
|
||||
}
|
||||
|
||||
metric.RemoveField(key)
|
||||
metric.AddField(key, v)
|
||||
continue
|
||||
}
|
||||
|
||||
if p.fieldConversions.Timestamp != nil && p.fieldConversions.Timestamp.Match(key) {
|
||||
time, err := internal.ParseTimestamp(p.Fields.TimestampFormat, value, nil)
|
||||
if err != nil {
|
||||
p.Log.Errorf("error converting to timestamp [%T]: %v", value, value)
|
||||
continue
|
||||
}
|
||||
|
||||
metric.RemoveField(key)
|
||||
metric.SetTime(time)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func toBool(v interface{}) (val bool, ok bool) {
|
||||
func toInteger(v interface{}) (int64, error) {
|
||||
switch value := v.(type) {
|
||||
case int64:
|
||||
return value != 0, true
|
||||
case uint64:
|
||||
return value != 0, true
|
||||
case float64:
|
||||
return value != 0, true
|
||||
case bool:
|
||||
return value, true
|
||||
case string:
|
||||
result, err := strconv.ParseBool(value)
|
||||
return result, err == nil
|
||||
}
|
||||
return false, false
|
||||
}
|
||||
|
||||
func toInteger(v interface{}) (int64, bool) {
|
||||
switch value := v.(type) {
|
||||
case int64:
|
||||
return value, true
|
||||
case uint64:
|
||||
if value <= uint64(math.MaxInt64) {
|
||||
return int64(value), true
|
||||
case float32:
|
||||
if value < float32(math.MinInt64) {
|
||||
return math.MinInt64, nil
|
||||
}
|
||||
return math.MaxInt64, true
|
||||
if value > float32(math.MaxInt64) {
|
||||
return math.MaxInt64, nil
|
||||
}
|
||||
return int64(math.Round(float64(value))), nil
|
||||
case float64:
|
||||
if value < float64(math.MinInt64) {
|
||||
return math.MinInt64, true
|
||||
} else if value > float64(math.MaxInt64) {
|
||||
return math.MaxInt64, true
|
||||
} else {
|
||||
return int64(math.Round(value)), true
|
||||
return math.MinInt64, nil
|
||||
}
|
||||
case bool:
|
||||
if value {
|
||||
return 1, true
|
||||
if value > float64(math.MaxInt64) {
|
||||
return math.MaxInt64, nil
|
||||
}
|
||||
return int64(math.Round(value)), nil
|
||||
default:
|
||||
if v, err := internal.ToInt64(value); err == nil {
|
||||
return v, nil
|
||||
}
|
||||
return 0, true
|
||||
case string:
|
||||
result, err := strconv.ParseInt(value, 0, 64)
|
||||
|
||||
v, err := internal.ToFloat64(value)
|
||||
if err != nil {
|
||||
var result float64
|
||||
var err error
|
||||
|
||||
if isHexadecimal(value) {
|
||||
result, err = parseHexadecimal(value)
|
||||
} else {
|
||||
result, err = strconv.ParseFloat(value, 64)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return toInteger(result)
|
||||
return 0, err
|
||||
}
|
||||
return result, true
|
||||
|
||||
if v < float64(math.MinInt64) {
|
||||
return math.MinInt64, nil
|
||||
}
|
||||
if v > float64(math.MaxInt64) {
|
||||
return math.MaxInt64, nil
|
||||
}
|
||||
return int64(math.Round(v)), nil
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func toUnsigned(v interface{}) (uint64, bool) {
|
||||
func toUnsigned(v interface{}) (uint64, error) {
|
||||
switch value := v.(type) {
|
||||
case uint64:
|
||||
return value, true
|
||||
case int64:
|
||||
case float32:
|
||||
if value < 0 {
|
||||
return 0, true
|
||||
return 0, nil
|
||||
}
|
||||
return uint64(value), true
|
||||
if value > float32(math.MaxUint64) {
|
||||
return math.MaxUint64, nil
|
||||
}
|
||||
return uint64(math.Round(float64(value))), nil
|
||||
case float64:
|
||||
if value < 0.0 {
|
||||
return 0, true
|
||||
} else if value > float64(math.MaxUint64) {
|
||||
return math.MaxUint64, true
|
||||
} else {
|
||||
return uint64(math.Round(value)), true
|
||||
if value < 0 {
|
||||
return 0, nil
|
||||
}
|
||||
case bool:
|
||||
if value {
|
||||
return 1, true
|
||||
if value > float64(math.MaxUint64) {
|
||||
return math.MaxUint64, nil
|
||||
}
|
||||
return uint64(math.Round(value)), nil
|
||||
default:
|
||||
if v, err := internal.ToUint64(value); err == nil {
|
||||
return v, nil
|
||||
}
|
||||
return 0, true
|
||||
case string:
|
||||
result, err := strconv.ParseUint(value, 0, 64)
|
||||
|
||||
v, err := internal.ToFloat64(value)
|
||||
if err != nil {
|
||||
var result float64
|
||||
var err error
|
||||
|
||||
if isHexadecimal(value) {
|
||||
result, err = parseHexadecimal(value)
|
||||
} else {
|
||||
result, err = strconv.ParseFloat(value, 64)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return toUnsigned(result)
|
||||
}
|
||||
return result, true
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func toFloat(v interface{}) (float64, bool) {
|
||||
switch value := v.(type) {
|
||||
case int64:
|
||||
return float64(value), true
|
||||
case uint64:
|
||||
return float64(value), true
|
||||
case float64:
|
||||
return value, true
|
||||
case bool:
|
||||
if value {
|
||||
return 1.0, true
|
||||
}
|
||||
return 0.0, true
|
||||
case string:
|
||||
if isHexadecimal(value) {
|
||||
result, err := parseHexadecimal(value)
|
||||
return result, err == nil
|
||||
return 0, err
|
||||
}
|
||||
|
||||
result, err := strconv.ParseFloat(value, 64)
|
||||
return result, err == nil
|
||||
if v < 0 {
|
||||
return 0, nil
|
||||
}
|
||||
if v > float64(math.MaxUint64) {
|
||||
return math.MaxUint64, nil
|
||||
}
|
||||
return uint64(math.Round(v)), nil
|
||||
}
|
||||
return 0.0, false
|
||||
}
|
||||
|
||||
func toString(v interface{}) (string, bool) {
|
||||
switch value := v.(type) {
|
||||
case int64:
|
||||
return strconv.FormatInt(value, 10), true
|
||||
case uint64:
|
||||
return strconv.FormatUint(value, 10), true
|
||||
case float64:
|
||||
return strconv.FormatFloat(value, 'f', -1, 64), true
|
||||
case bool:
|
||||
return strconv.FormatBool(value), true
|
||||
case string:
|
||||
return value, true
|
||||
func toFloat(v interface{}) (float64, error) {
|
||||
if v, ok := v.(string); ok && strings.HasPrefix(v, "0x") {
|
||||
var i big.Int
|
||||
if _, success := i.SetString(v, 0); !success {
|
||||
return 0, errors.New("unable to parse string to big int")
|
||||
}
|
||||
|
||||
var f big.Float
|
||||
f.SetInt(&i)
|
||||
result, _ := f.Float64()
|
||||
|
||||
return result, nil
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
func parseHexadecimal(value string) (float64, error) {
|
||||
i := new(big.Int)
|
||||
|
||||
_, success := i.SetString(value, 0)
|
||||
if !success {
|
||||
return 0, errors.New("unable to parse string to big int")
|
||||
}
|
||||
|
||||
f := new(big.Float).SetInt(i)
|
||||
result, _ := f.Float64()
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func isHexadecimal(value string) bool {
|
||||
return len(value) >= 3 && strings.ToLower(value)[1] == 'x'
|
||||
return internal.ToFloat64(v)
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
|
|||
Loading…
Reference in New Issue