Created
January 18, 2018 20:12
-
-
Save aerostitch/36e20c56fbf98b3a2d04b2417a50a789 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
// Note: I initially wrote this script to delete old Cloudwatch metrics | |
// but I found out too late that it's not possible to do delete metrics from CloudWatch | |
// so just keeping this script as a usage example of the metrics statistics manipulations | |
import ( | |
"github.com/aws/aws-sdk-go/aws" | |
"github.com/aws/aws-sdk-go/aws/session" | |
"github.com/aws/aws-sdk-go/service/cloudwatch" | |
"github.com/aws/aws-sdk-go/service/cloudwatch/cloudwatchiface" | |
"fmt" | |
"time" | |
) | |
// CWProcessor is used to share the Cloudwatch client between functions | |
type CWProcessor struct { | |
svc cloudwatchiface.CloudWatchAPI | |
} | |
// newCWProcessor initiates a new cloudwatch client | |
func newCWProcessor() *CWProcessor { | |
sess := session.Must(session.NewSessionWithOptions(session.Options{ | |
SharedConfigState: session.SharedConfigEnable, | |
})) | |
return &CWProcessor{svc: cloudwatch.New(sess)} | |
} | |
// processMetrics pulls the list of metrics and check if the latest datapoint of | |
// each metric is older than the given number of days (must be within the last 2 | |
// years if yes, prints the informations | |
func (c *CWProcessor) processMetrics(daysLimit int) { | |
params := &cloudwatch.ListMetricsInput{} | |
timeLimit := time.Now().AddDate(0, 0, -daysLimit) | |
err := c.svc.ListMetricsPages(params, | |
func(page *cloudwatch.ListMetricsOutput, lastPage bool) bool { | |
for _, m := range page.Metrics { | |
last := c.getLatestMetricUpdate(m) | |
if last == nil || timeLimit.After(*last) { | |
fmt.Printf("%s / %s %v: %s\n", *m.Namespace, *m.MetricName, m.Dimensions, last) | |
} | |
} | |
return !lastPage | |
}) | |
if err != nil { | |
fmt.Println("Error", err) | |
return | |
} | |
} | |
// getLatestMetricUpdate returns the date of the latest datapoint in the given | |
// metric and nil if nothing was found over the last 3 months | |
func (c *CWProcessor) getLatestMetricUpdate(metric *cloudwatch.Metric) *time.Time { | |
end := time.Now() | |
start := end.AddDate(-2, 0, 0) | |
period := int64(24 * 3600) | |
params := cloudwatch.GetMetricStatisticsInput{ | |
Dimensions: metric.Dimensions, | |
MetricName: metric.MetricName, | |
Namespace: metric.Namespace, | |
StartTime: &start, | |
Period: &period, | |
EndTime: &end, | |
Statistics: []*string{aws.String("Sum")}, | |
} | |
result, err := c.svc.GetMetricStatistics(¶ms) | |
if err != nil { | |
fmt.Println(err) | |
} | |
latest := c.getLatestDatapoint(result.Datapoints) | |
return latest.Timestamp | |
} | |
// getLatestDatapoint returns the latest datapoint (timewise) found in an array of datapoints | |
func (c *CWProcessor) getLatestDatapoint(dps []*cloudwatch.Datapoint) *cloudwatch.Datapoint { | |
var latest *cloudwatch.Datapoint | |
for _, dp := range dps { | |
if latest == nil { | |
latest = dp | |
} else { | |
if latest.Timestamp != nil && (*dp.Timestamp).After(*latest.Timestamp) { | |
latest = dp | |
} | |
} | |
} | |
return latest | |
} | |
func main() { | |
p := newCWProcessor() | |
p.processMetrics(30) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment