diff --git a/pkg/exporter/exporter.go b/pkg/exporter/exporter.go index e2f202d..7967b8d 100644 --- a/pkg/exporter/exporter.go +++ b/pkg/exporter/exporter.go @@ -146,7 +146,7 @@ func (b *Exporter) handleEvent(thisEvent event.Event) { t = mapping.ObserverType } if t == mapper.ObserverTypeDefault { - t = b.Mapper.Defaults.ObsereverType + t = b.Mapper.Defaults.ObserverType } switch t { diff --git a/pkg/exporter/exporter_test.go b/pkg/exporter/exporter_test.go index 2802ac1..c92221b 100644 --- a/pkg/exporter/exporter_test.go +++ b/pkg/exporter/exporter_test.go @@ -711,7 +711,7 @@ func TestHistogramUnits(t *testing.T) { testMapper := mapper.MetricMapper{} testMapper.InitCache(0) ex := NewExporter(&testMapper, log.NewNopLogger(), eventsActions, eventsUnmapped, errorEventStats, eventStats, conflictingEventStats, metricsCount) - ex.Mapper.Defaults.ObsereverType = mapper.ObserverTypeHistogram + ex.Mapper.Defaults.ObserverType = mapper.ObserverTypeHistogram ex.Listen(events) }() diff --git a/pkg/mapper/mapper.go b/pkg/mapper/mapper.go index dc9a17b..3638b1f 100644 --- a/pkg/mapper/mapper.go +++ b/pkg/mapper/mapper.go @@ -36,7 +36,8 @@ var ( ) type mapperConfigDefaults struct { - ObsereverType ObserverType `yaml:"observer_type"` + ObserverType ObserverType `yaml:"observer_type"` + TimerType ObserverType `yaml:"timer_type,omitempty"` // DEPRECATED - field only present to preserve backwards compatibility in configs. Always empty Buckets []float64 `yaml:"buckets"` Quantiles []metricObjective `yaml:"quantiles"` MatchType MatchType `yaml:"match_type"` @@ -64,7 +65,8 @@ type MetricMapping struct { Labels prometheus.Labels `yaml:"labels"` labelKeys []string labelFormatters []*fsm.TemplateFormatter - ObserverType ObserverType `yaml:"observer_type"` + ObserverType ObserverType `yaml:"observer_type,omitempty"` + TimerType ObserverType `yaml:"timer_type,omitempty"` // DEPRECATED - field only present to preserve backwards compatibility in configs. Always empty LegacyBuckets []float64 `yaml:"buckets"` LegacyQuantiles []metricObjective `yaml:"quantiles"` MatchType MatchType `yaml:"match_type"` @@ -98,6 +100,63 @@ var defaultQuantiles = []metricObjective{ {Quantile: 0.99, Error: 0.001}, } +// UnmarshalYAML is a custom unmarshal function to allow use of deprecated config keys +// observer_type will override timer_type +func (d *mapperConfigDefaults) UnmarshalYAML(unmarshal func(interface{}) error) error { + type mapperConfigDefaultsAlias mapperConfigDefaults + var tmp mapperConfigDefaultsAlias + if err := unmarshal(&tmp); err != nil { + return err + } + + // Copy defaults + d.ObserverType = tmp.ObserverType + d.Buckets = tmp.Buckets + d.Quantiles = tmp.Quantiles + d.MatchType = tmp.MatchType + d.GlobDisableOrdering = tmp.GlobDisableOrdering + d.Ttl = tmp.Ttl + + // Use deprecated TimerType if necessary + if tmp.ObserverType == "" { + d.ObserverType = tmp.TimerType + } + + return nil +} + +// UnmarshalYAML is a custom unmarshal function to allow use of deprecated config keys +// observer_type will override timer_type +func (m *MetricMapping) UnmarshalYAML(unmarshal func(interface{}) error) error { + type MetricMappingAlias MetricMapping + var tmp MetricMappingAlias + if err := unmarshal(&tmp); err != nil { + return err + } + + // Copy defaults + m.Match = tmp.Match + m.Name = tmp.Name + m.Labels = tmp.Labels + m.ObserverType = tmp.ObserverType + m.LegacyBuckets = tmp.LegacyBuckets + m.LegacyQuantiles = tmp.LegacyQuantiles + m.MatchType = tmp.MatchType + m.HelpText = tmp.HelpText + m.Action = tmp.Action + m.MatchMetricType = tmp.MatchMetricType + m.Ttl = tmp.Ttl + m.SummaryOptions = tmp.SummaryOptions + m.HistogramOptions = tmp.HistogramOptions + + // Use deprecated TimerType if necessary + if tmp.ObserverType == "" { + m.ObserverType = tmp.TimerType + } + + return nil +} + func (m *MetricMapper) InitFromYAMLString(fileContents string, cacheSize int, options ...CacheOption) error { var n MetricMapper @@ -182,7 +241,7 @@ func (m *MetricMapper) InitFromYAMLString(fileContents string, cacheSize int, op } if currentMapping.ObserverType == "" { - currentMapping.ObserverType = n.Defaults.ObsereverType + currentMapping.ObserverType = n.Defaults.ObserverType } if currentMapping.LegacyQuantiles != nil && diff --git a/pkg/mapper/mapper_test.go b/pkg/mapper/mapper_test.go index f4de0b6..e00ae8f 100644 --- a/pkg/mapper/mapper_test.go +++ b/pkg/mapper/mapper_test.go @@ -449,6 +449,33 @@ mappings: observer_type: summary name: "foo" labels: {} + quantiles: + - quantile: 0.42 + error: 0.04 + - quantile: 0.7 + error: 0.002 + `, + mappings: mappings{ + { + statsdMetric: "test.*.*", + name: "foo", + labels: map[string]string{}, + quantiles: []metricObjective{ + {Quantile: 0.42, Error: 0.04}, + {Quantile: 0.7, Error: 0.002}, + }, + }, + }, + }, + // Config with good observer type and unused timer type + { + config: `--- +mappings: +- match: test.*.* + observer_type: summary + timer_type: histogram + name: "foo" + labels: {} quantiles: - quantile: 0.42 error: 0.04 @@ -474,6 +501,28 @@ mappings: observer_type: summary name: "foo" labels: {} + `, + mappings: mappings{ + { + statsdMetric: "test1.*.*", + name: "foo", + labels: map[string]string{}, + quantiles: []metricObjective{ + {Quantile: 0.5, Error: 0.05}, + {Quantile: 0.9, Error: 0.01}, + {Quantile: 0.99, Error: 0.001}, + }, + }, + }, + }, + // Config with good deprecated timer type + { + config: `--- +mappings: +- match: test1.*.* + timer_type: summary + name: "foo" + labels: {} `, mappings: mappings{ { @@ -495,6 +544,17 @@ mappings: - match: test.*.* observer_type: wrong name: "foo" + labels: {} + `, + configBad: true, + }, + // Config with bad deprecated timer type. + { + config: `--- +mappings: +- match: test.*.* + timer_type: wrong + name: "foo" labels: {} `, configBad: true, diff --git a/pkg/mapper/metric_type.go b/pkg/mapper/metric_type.go index d98d80a..920c16e 100644 --- a/pkg/mapper/metric_type.go +++ b/pkg/mapper/metric_type.go @@ -21,6 +21,7 @@ const ( MetricTypeCounter MetricType = "counter" MetricTypeGauge MetricType = "gauge" MetricTypeObserver MetricType = "observer" + MetricTypeTimer MetricType = "timer" // DEPRECATED ) func (m *MetricType) UnmarshalYAML(unmarshal func(interface{}) error) error { @@ -36,6 +37,8 @@ func (m *MetricType) UnmarshalYAML(unmarshal func(interface{}) error) error { *m = MetricTypeGauge case MetricTypeObserver: *m = MetricTypeObserver + case MetricTypeTimer: + *m = MetricTypeObserver default: return fmt.Errorf("invalid metric type '%s'", v) }