Skip to content

Instantly share code, notes, and snippets.

@aerostitch
Created January 18, 2018 20:12
Show Gist options
  • Save aerostitch/36e20c56fbf98b3a2d04b2417a50a789 to your computer and use it in GitHub Desktop.
Save aerostitch/36e20c56fbf98b3a2d04b2417a50a789 to your computer and use it in GitHub Desktop.
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(&params)
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