in exporter/signalfxexporter/internal/translation/translator.go [247:349]
func validateTranslationRules(rules []Rule) error {
var renameDimensionKeysFound bool
for _, tr := range rules {
switch tr.Action {
case ActionRenameDimensionKeys:
if tr.Mapping == nil {
return fmt.Errorf("field \"mapping\" is required for %q translation rule", tr.Action)
}
if len(tr.MetricNames) == 0 {
if renameDimensionKeysFound {
return fmt.Errorf("only one %q translation rule without \"metric_names\" can be specified", tr.Action)
}
renameDimensionKeysFound = true
}
case ActionRenameMetrics:
if tr.Mapping == nil {
return fmt.Errorf("field \"mapping\" is required for %q translation rule", tr.Action)
}
if tr.CopyDimensions != nil {
for k, v := range tr.CopyDimensions {
if k == "" || v == "" {
return fmt.Errorf("mapping \"copy_dimensions\" for %q translation rule must not contain empty string keys or values", tr.Action)
}
}
}
case ActionMultiplyInt:
if tr.ScaleFactorsInt == nil {
return fmt.Errorf("field \"scale_factors_int\" is required for %q translation rule", tr.Action)
}
case ActionDivideInt:
if tr.ScaleFactorsInt == nil {
return fmt.Errorf("field \"scale_factors_int\" is required for %q translation rule", tr.Action)
}
for k, v := range tr.ScaleFactorsInt {
if v == 0 {
return fmt.Errorf("\"scale_factors_int\" for %q translation rule has 0 value for %q metric", tr.Action, k)
}
}
case ActionMultiplyFloat:
if tr.ScaleFactorsFloat == nil {
return fmt.Errorf("field \"scale_factors_float\" is required for %q translation rule", tr.Action)
}
case ActionCopyMetrics:
if tr.Mapping == nil {
return fmt.Errorf("field \"mapping\" is required for %q translation rule", tr.Action)
}
if tr.DimensionKey != "" && len(tr.DimensionValues) == 0 {
return fmt.Errorf(
"\"dimension_values_filer\" has to be provided if \"dimension_key\" is set for %q translation rule",
tr.Action)
}
case ActionSplitMetric:
if tr.MetricName == "" || tr.DimensionKey == "" || tr.Mapping == nil {
return fmt.Errorf(
"fields \"metric_name\", \"dimension_key\", and \"mapping\" are required for %q translation rule",
tr.Action)
}
case ActionConvertValues:
if tr.TypesMapping == nil {
return fmt.Errorf("field \"types_mapping\" are required for %q translation rule", tr.Action)
}
for k, v := range tr.TypesMapping {
if v != MetricValueTypeInt && v != MetricValueTypeDouble {
return fmt.Errorf("invalid value type %q set for metric %q in \"types_mapping\"", v, k)
}
}
case ActionAggregateMetric:
if tr.MetricName == "" || tr.AggregationMethod == "" || len(tr.WithoutDimensions) == 0 {
return fmt.Errorf("fields \"metric_name\", \"without_dimensions\", and \"aggregation_method\" "+
"are required for %q translation rule", tr.Action)
}
if tr.AggregationMethod != AggregationMethodCount &&
tr.AggregationMethod != AggregationMethodSum &&
tr.AggregationMethod != AggregationMethodAvg {
return fmt.Errorf("invalid \"aggregation_method\": %q provided for %q translation rule",
tr.AggregationMethod, tr.Action)
}
case ActionCalculateNewMetric:
if tr.MetricName == "" || tr.Operand1Metric == "" || tr.Operand2Metric == "" || tr.Operator == "" {
return fmt.Errorf(`fields "metric_name", "operand1_metric", "operand2_metric", and "operator" are `+
"required for %q translation rule", tr.Action)
}
if tr.Operator != MetricOperatorDivision {
return fmt.Errorf("invalid operator %q for %q translation rule", tr.Operator, tr.Action)
}
case ActionDropMetrics:
if len(tr.MetricNames) == 0 {
return fmt.Errorf(`field "metric_names" is required for %q translation rule`, tr.Action)
}
case ActionDeltaMetric:
if len(tr.Mapping) == 0 {
return fmt.Errorf(`field "mapping" is required for %q translation rule`, tr.Action)
}
case ActionDropDimensions:
if len(tr.DimensionPairs) == 0 {
return fmt.Errorf(`field "dimension_pairs" is required for %q translation rule`, tr.Action)
}
default:
return fmt.Errorf("unknown \"action\" value: %q", tr.Action)
}
}
return nil
}