Add Glob / Wildcard support to Cloudwatch input for 'Dimensions' configuration (#9136)
I believe this will resolve #4046
This commit is contained in:
parent
243488c266
commit
e29bca7419
|
|
@ -101,6 +101,7 @@ API endpoint. In the following order the plugin will attempt to authenticate.
|
||||||
#
|
#
|
||||||
# ## Dimension filters for Metric. All dimensions defined for the metric names
|
# ## Dimension filters for Metric. All dimensions defined for the metric names
|
||||||
# ## must be specified in order to retrieve the metric statistics.
|
# ## must be specified in order to retrieve the metric statistics.
|
||||||
|
# ## 'value' has wildcard / 'glob' matching support such as `p-*`.
|
||||||
# [[inputs.cloudwatch.metrics.dimensions]]
|
# [[inputs.cloudwatch.metrics.dimensions]]
|
||||||
# name = "LoadBalancerName"
|
# name = "LoadBalancerName"
|
||||||
# value = "p-example"
|
# value = "p-example"
|
||||||
|
|
|
||||||
|
|
@ -66,8 +66,9 @@ type Metric struct {
|
||||||
|
|
||||||
// Dimension defines a simplified Cloudwatch dimension (provides metric filtering).
|
// Dimension defines a simplified Cloudwatch dimension (provides metric filtering).
|
||||||
type Dimension struct {
|
type Dimension struct {
|
||||||
Name string `toml:"name"`
|
Name string `toml:"name"`
|
||||||
Value string `toml:"value"`
|
Value string `toml:"value"`
|
||||||
|
valueMatcher filter.Filter
|
||||||
}
|
}
|
||||||
|
|
||||||
// metricCache caches metrics, their filters, and generated queries.
|
// metricCache caches metrics, their filters, and generated queries.
|
||||||
|
|
@ -170,6 +171,7 @@ func (c *CloudWatch) SampleConfig() string {
|
||||||
#
|
#
|
||||||
# ## Dimension filters for Metric. All dimensions defined for the metric names
|
# ## Dimension filters for Metric. All dimensions defined for the metric names
|
||||||
# ## must be specified in order to retrieve the metric statistics.
|
# ## must be specified in order to retrieve the metric statistics.
|
||||||
|
# ## 'value' has wildcard / 'glob' matching support. such as 'p-*'.
|
||||||
# [[inputs.cloudwatch.metrics.dimensions]]
|
# [[inputs.cloudwatch.metrics.dimensions]]
|
||||||
# name = "LoadBalancerName"
|
# name = "LoadBalancerName"
|
||||||
# value = "p-example"
|
# value = "p-example"
|
||||||
|
|
@ -294,6 +296,18 @@ func (c *CloudWatch) initializeCloudWatch() error {
|
||||||
loglevel := aws.LogOff
|
loglevel := aws.LogOff
|
||||||
c.client = cloudwatch.New(configProvider, cfg.WithLogLevel(loglevel))
|
c.client = cloudwatch.New(configProvider, cfg.WithLogLevel(loglevel))
|
||||||
|
|
||||||
|
// Initialize regex matchers for each Dimension value.
|
||||||
|
for _, m := range c.Metrics {
|
||||||
|
for _, dimension := range m.Dimensions {
|
||||||
|
matcher, err := filter.NewIncludeExcludeFilter([]string{dimension.Value}, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
dimension.valueMatcher = matcher
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -633,7 +647,7 @@ func (f *metricCache) isValid() bool {
|
||||||
|
|
||||||
func hasWildcard(dimensions []*Dimension) bool {
|
func hasWildcard(dimensions []*Dimension) bool {
|
||||||
for _, d := range dimensions {
|
for _, d := range dimensions {
|
||||||
if d.Value == "" || d.Value == "*" {
|
if d.Value == "" || strings.ContainsAny(d.Value, "*?[") {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -651,7 +665,7 @@ func isSelected(name string, metric *cloudwatch.Metric, dimensions []*Dimension)
|
||||||
selected := false
|
selected := false
|
||||||
for _, d2 := range metric.Dimensions {
|
for _, d2 := range metric.Dimensions {
|
||||||
if d.Name == *d2.Name {
|
if d.Name == *d2.Name {
|
||||||
if d.Value == "" || d.Value == "*" || d.Value == *d2.Value {
|
if d.Value == "" || d.valueMatcher.Match(*d2.Value) {
|
||||||
selected = true
|
selected = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -201,16 +201,18 @@ func TestSelectMetrics(t *testing.T) {
|
||||||
Dimensions: []*Dimension{
|
Dimensions: []*Dimension{
|
||||||
{
|
{
|
||||||
Name: "LoadBalancerName",
|
Name: "LoadBalancerName",
|
||||||
Value: "*",
|
Value: "lb*",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "AvailabilityZone",
|
Name: "AvailabilityZone",
|
||||||
Value: "*",
|
Value: "us-east*",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
err := c.initializeCloudWatch()
|
||||||
|
assert.NoError(t, err)
|
||||||
c.client = &mockSelectMetricsCloudWatchClient{}
|
c.client = &mockSelectMetricsCloudWatchClient{}
|
||||||
filtered, err := getFilteredMetrics(c)
|
filtered, err := getFilteredMetrics(c)
|
||||||
// We've asked for 2 (out of 4) metrics, over all 3 load balancers in all 2
|
// We've asked for 2 (out of 4) metrics, over all 3 load balancers in all 2
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue