From bcdabf4fbdc38168a2e03604f974b1cd98202c5e Mon Sep 17 00:00:00 2001 From: Albin Kerouanton Date: Wed, 19 Feb 2020 16:14:22 +0100 Subject: [PATCH] Add a flag to publish metrics with high resolution (#32) So far, this tool is only publishing metrics with high resolution when the original prometheus metrics have the label __cw_high_res. However, in our case we're running exporters and prom-to-cloudwatch as sidecars of ECS tasks. This tool being directly connected to the exporters, we can't add the high res label. --- main.go | 4 ++++ prometheus_to_cloudwatch.go | 14 +++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/main.go b/main.go index 05daf70..6958e8f 100644 --- a/main.go +++ b/main.go @@ -15,6 +15,8 @@ import ( "github.com/gobwas/glob" ) +var defaultForceHighRes, _ = strconv.ParseBool(os.Getenv("FORCE_HIGH_RES")) + var ( awsAccessKeyId = flag.String("aws_access_key_id", os.Getenv("AWS_ACCESS_KEY_ID"), "AWS access key Id with permissions to publish CloudWatch metrics") awsSecretAccessKey = flag.String("aws_secret_access_key", os.Getenv("AWS_SECRET_ACCESS_KEY"), "AWS secret access key with permissions to publish CloudWatch metrics") @@ -33,6 +35,7 @@ var ( excludeMetrics = flag.String("exclude_metrics", os.Getenv("EXCLUDE_METRICS"), "Never publish the specified metrics (comma-separated list of glob patterns, e.g. 'tomcat_*')") includeDimensionsForMetrics = flag.String("include_dimensions_for_metrics", os.Getenv("INCLUDE_DIMENSIONS_FOR_METRICS"), "Only publish the specified dimensions for metrics (semi-colon-separated key values of comma-separated dimensions of METRIC=dim1,dim2;, e.g. 'flink_jobmanager=job_id')") excludeDimensionsForMetrics = flag.String("exclude_dimensions_for_metrics", os.Getenv("EXCLUDE_DIMENSIONS_FOR_METRICS"), "Never publish the specified dimensions for metrics (semi-colon-separated key values of comma-separated dimensions of METRIC=dim1,dim2;, e.g. 'flink_jobmanager=job,host;zk_up=host,pod;')") + forceHighRes = flag.Bool("force_high_res", defaultForceHighRes, "Publish all metrics with high resolution, even when original metrics don't have the label "+cwHighResLabel) ) // kevValMustParse takes a string and exits with a message if it cannot parse as KEY=VALUE @@ -180,6 +183,7 @@ func main() { ExcludeMetrics: excludeMetricsList, ExcludeDimensionsForMetrics: excludeDimensionsForMetricsList, IncludeDimensionsForMetrics: includeDimensionsForMetricsList, + ForceHighRes: *forceHighRes, } if *prometheusScrapeInterval != "" { diff --git a/prometheus_to_cloudwatch.go b/prometheus_to_cloudwatch.go index 5a97c38..6db0e25 100644 --- a/prometheus_to_cloudwatch.go +++ b/prometheus_to_cloudwatch.go @@ -108,6 +108,9 @@ type Config struct { // Exclude certain dimensions from the specified metrics ExcludeDimensionsForMetrics []MatcherWithStringSet + + // ForceHighRes forces all exported metrics to be sent as custom high-resolution metrics. + ForceHighRes bool } // Bridge pushes metrics to AWS CloudWatch @@ -125,6 +128,7 @@ type Bridge struct { excludeMetrics []glob.Glob includeDimensionsForMetrics []MatcherWithStringSet excludeDimensionsForMetrics []MatcherWithStringSet + forceHighRes bool } // NewBridge initializes and returns a pointer to a Bridge using the @@ -151,6 +155,7 @@ func NewBridge(c *Config) (*Bridge, error) { b.excludeMetrics = c.ExcludeMetrics b.includeDimensionsForMetrics = c.IncludeDimensionsForMetrics b.excludeDimensionsForMetrics = c.ExcludeDimensionsForMetrics + b.forceHighRes = c.ForceHighRes if c.CloudWatchPublishInterval > 0 { b.cloudWatchPublishInterval = c.CloudWatchPublishInterval @@ -327,7 +332,7 @@ func appendDatum(data []*cloudwatch.MetricDatum, name string, s *model.Sample, b SetValue(value). SetTimestamp(s.Timestamp.Time()). SetDimensions(append(kubeStateDimensions, getAdditionalDimensions(b)...)). - SetStorageResolution(getResolution(metric)). + SetStorageResolution(b.getResolution(metric)). SetUnit(getUnit(metric)) data = append(data, datum) @@ -338,7 +343,7 @@ func appendDatum(data []*cloudwatch.MetricDatum, name string, s *model.Sample, b SetValue(value). SetTimestamp(s.Timestamp.Time()). SetDimensions(append(replacedDimensions, getAdditionalDimensions(b)...)). - SetStorageResolution(getResolution(metric)). + SetStorageResolution(b.getResolution(metric)). SetUnit(getUnit(metric)) data = append(data, replacedDimensionDatum) } @@ -465,7 +470,10 @@ func getAdditionalDimensions(b *Bridge) []*cloudwatch.Dimension { } // Returns 1 if the metric contains a __cw_high_res label, otherwise returns 60 -func getResolution(m model.Metric) int64 { +func (b *Bridge) getResolution(m model.Metric) int64 { + if b.forceHighRes { + return 1 + } if _, ok := m[cwHighResLabel]; ok { return 1 }