Cloudwatch input plugin
This commit is contained in:
parent
b1cfb1afe4
commit
bd4843d5f2
5
Godeps
5
Godeps
|
@ -3,6 +3,7 @@ github.com/Shopify/sarama 8aadb476e66ca998f2f6bb3c993e9a2daa3666b9
|
|||
github.com/Sirupsen/logrus 219c8cb75c258c552e999735be6df753ffc7afdc
|
||||
github.com/amir/raidman 53c1b967405155bfc8758557863bf2e14f814687
|
||||
github.com/aws/aws-sdk-go 13a12060f716145019378a10e2806c174356b857
|
||||
github.com/azer/snakecase 7a41237eda4ca971bdcbba00d459901be8221a19
|
||||
github.com/beorn7/perks 3ac7bf7a47d159a033b107610db8a1b6575507a4
|
||||
github.com/cenkalti/backoff 4dc77674aceaabba2c7e3da25d4c823edfb73f99
|
||||
github.com/couchbase/go-couchbase cb664315a324d87d19c879d9cc67fda6be8c2ac1
|
||||
|
@ -13,6 +14,7 @@ github.com/davecgh/go-spew 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d
|
|||
github.com/eapache/go-resiliency b86b1ec0dd4209a588dc1285cdd471e73525c0b3
|
||||
github.com/eapache/queue ded5959c0d4e360646dc9e9908cff48666781367
|
||||
github.com/fsouza/go-dockerclient a49c8269a6899cae30da1f8a4b82e0ce945f9967
|
||||
github.com/go-ini/ini 776aa739ce9373377cd16f526cdf06cb4c89b40f
|
||||
github.com/go-sql-driver/mysql 1fca743146605a172a266e1654e01e5cd5669bee
|
||||
github.com/golang/protobuf 552c7b9542c194800fd493123b3798ef0a832032
|
||||
github.com/golang/snappy 427fb6fc07997f43afa32f35e850833760e489a7
|
||||
|
@ -23,6 +25,7 @@ github.com/hailocab/go-hostpool e80d13ce29ede4452c43dea11e79b9bc8a15b478
|
|||
github.com/influxdata/config b79f6829346b8d6e78ba73544b1e1038f1f1c9da
|
||||
github.com/influxdata/influxdb e3fef5593c21644f2b43af55d6e17e70910b0e48
|
||||
github.com/influxdata/toml af4df43894b16e3fd2b788d01bd27ad0776ef2d0
|
||||
github.com/jmespath/go-jmespath 0b12d6b521d83fc7f755e7cfc1b1fbdd35a01a74
|
||||
github.com/klauspost/crc32 19b0b332c9e4516a6370a0456e6182c3b5036720
|
||||
github.com/lib/pq e182dc4027e2ded4b19396d638610f2653295f36
|
||||
github.com/matttproud/golang_protobuf_extensions d0c3fe89de86839aecf2e0579c40ba3bb336a453
|
||||
|
@ -32,6 +35,7 @@ github.com/naoina/go-stringutil 6b638e95a32d0c1131db0e7fe83775cbea4a0d0b
|
|||
github.com/nats-io/nats b13fc9d12b0b123ebc374e6b808c6228ae4234a3
|
||||
github.com/nats-io/nuid 4f84f5f3b2786224e336af2e13dba0a0a80b76fa
|
||||
github.com/nsqio/go-nsq 0b80d6f05e15ca1930e0c5e1d540ed627e299980
|
||||
github.com/pmezard/go-difflib 792786c7400a136282c1664665ae0a8db921c6c2
|
||||
github.com/prometheus/client_golang 18acf9993a863f4c4b40612e19cdd243e7c86831
|
||||
github.com/prometheus/client_model fa8ad6fec33561be4280a8f0514318c79d7f6cb6
|
||||
github.com/prometheus/common e8eabff8812b05acf522b45fdcd725a785188e37
|
||||
|
@ -40,6 +44,7 @@ github.com/samuel/go-zookeeper 218e9c81c0dd8b3b18172b2bbfad92cc7d6db55f
|
|||
github.com/shirou/gopsutil 1f32ce1bb380845be7f5d174ac641a2c592c0c42
|
||||
github.com/soniah/gosnmp b1b4f885b12c5dcbd021c5cee1c904110de6db7d
|
||||
github.com/streadway/amqp b4f3ceab0337f013208d31348b578d83c0064744
|
||||
github.com/stretchr/objx 1a9d0bb9f541897e62256577b352fdbc1fb4fd94
|
||||
github.com/stretchr/testify 1f4a1643a57e798696635ea4c126e9127adb7d3c
|
||||
github.com/wvanbergen/kafka 1a8639a45164fcc245d5c7b4bd3ccfbd1a0ffbf3
|
||||
github.com/wvanbergen/kazoo-go 0f768712ae6f76454f987c3356177e138df258f8
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
_ "github.com/influxdata/telegraf/plugins/inputs/aerospike"
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/apache"
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/bcache"
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/cloudwatch"
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/couchbase"
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/couchdb"
|
||||
_ "github.com/influxdata/telegraf/plugins/inputs/disque"
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
# Telegraf Plugin: Cloudwatch
|
||||
|
||||
## Configuration:
|
||||
|
||||
```
|
||||
# Read metrics from Cloudwatch
|
||||
[[inputs.cloudwatch]]
|
||||
## AWS region
|
||||
region = "us-east-1"
|
||||
## specify namespaces as strings
|
||||
namespaces = ["AWS/EC2", "AWS/DynamoDB"]
|
||||
```
|
||||
|
||||
In each iteration, the cloudwatch input plugin queries Cloudwatch for
|
||||
datapoints that are timestamped since the last iteration. (The first
|
||||
iteration does not retrieve any data.)
|
||||
|
||||
Some AWS services post timepoints late, in the sense that new
|
||||
timepoints are timestamped 2–3 minutes in the past. These points will
|
||||
be missed by the cloudwatch input plugin if you run telegraf with a
|
||||
short `interval`. Running telegraf with a longer interval, such as
|
||||
`5m`, is recommended.
|
||||
|
||||
|
||||
## Measurements:
|
||||
|
||||
Each namespace becomes a measurement, converted to snake_case and
|
||||
prefixed with `cloudwatch`. For instance, the namespace `AWS/EC2`
|
||||
becomes the measurement `cloudwatch_aws_ec2`, and the namespace
|
||||
`AWS/DynamoDB` becomes the measurement `cloudwatch_aws_dynamo_db`.
|
||||
|
||||
### Fields
|
||||
|
||||
The cloudwatch input plugin retrieves all statistics from all
|
||||
measurements in the specified namespaces. Each combination of metric
|
||||
and statistic becomes a field. Metric names are converted to
|
||||
snake_case. As an example, the metric `DiskWriteBytes` leads to the fields
|
||||
|
||||
* `disk_write_bytes_average`,
|
||||
* `disk_write_bytes_maximum`,
|
||||
* `disk_write_bytes_minimum`,
|
||||
* `disk_write_bytes_sample_count`, and
|
||||
* `disk_write_bytes_sum`.
|
||||
|
||||
To learn about the metrics for a particular Cloudwatch namespace, and
|
||||
to see units and example data, see the AWS documentation for the
|
||||
service in question, or explore using the AWS Console or AWS CLI.
|
||||
|
||||
### Tags
|
||||
|
||||
The cloudwatch input plugin tags the metrics it collects with the AWS
|
||||
region (key: `region`) and the cloudwatch dimensions of the metric in
|
||||
question. The dimensions names are converted to snake_keys, but the
|
||||
values are left as is. As an example, the `AWS/DynamoDB` namespace has
|
||||
a metric called `ThrottledRequest` with the dimensions `Operation` and
|
||||
`TableName`. An example set of tags for this metric could be:
|
||||
|
||||
* `region`: `us-east-1`
|
||||
* `operation`: `GetItem`
|
||||
* `table_name`: `foo`
|
||||
|
||||
## Example output
|
||||
|
||||
```
|
||||
$ ~/src/go/bin/telegraf -config ~/tmp/kapacitor/telegraf.conf -input-filter cloudwatch -debug
|
||||
2016/03/29 10:47:15 Attempting connection to output: influxdb
|
||||
2016/03/29 10:47:16 Successfully connected to output: influxdb
|
||||
2016/03/29 10:47:16 Starting Telegraf (version 0.11.1-54-ge07c792)
|
||||
2016/03/29 10:47:16 Loaded outputs: influxdb
|
||||
2016/03/29 10:47:16 Loaded inputs: cloudwatch
|
||||
2016/03/29 10:47:16 Tags enabled: host=vljosa-yieldbot.local
|
||||
2016/03/29 10:47:16 Agent Config: Interval:5m0s, Debug:true, Quiet:false, Hostname:"vljosa-yieldbot.local", Flush Interval:11.228634593s
|
||||
2016/03/29 10:50:00 Found 26 cloudwatch metrics
|
||||
2016/03/29 10:50:00 Gathered metrics, (5m0s interval), from 1 inputs in 709.03259ms
|
||||
> cloudwatch_aws_dynamo_db,host=vljosa-yieldbot.local,table_name=prd-platform-datomic-config consumed_write_capacity_units_average=1,consumed_write_capacity_units_maximum=1,consumed_write_capacity_units_minimum=1,consumed_write_capacity_units_sample_count=65,consumed_write_capacity_units_sum=65 1459263300548895733
|
||||
> cloudwatch_aws_dynamo_db,host=vljosa-yieldbot.local,table_name=dev-platform-datomic-config consumed_read_capacity_units_average=1,consumed_read_capacity_units_maximum=1,consumed_read_capacity_units_minimum=1,consumed_read_capacity_units_sample_count=48,consumed_read_capacity_units_sum=48 1459263300642785107
|
||||
> cloudwatch_aws_dynamo_db,host=vljosa-yieldbot.local,operation=PutItem,table_name=dev-platform-datomic-config successful_request_latency_average=8.910156727272726,successful_request_latency_maximum=26.477,successful_request_latency_minimum=4.243,successful_request_latency_sample_count=44,successful_request_latency_sum=392.04689599999995 1459263300688946255
|
||||
> cloudwatch_aws_dynamo_db,host=vljosa-yieldbot.local,operation=GetItem,table_name=dev-platform-datomic-config successful_request_latency_average=6.982394130434781,successful_request_latency_maximum=38.125,successful_request_latency_minimum=2.156,successful_request_latency_sample_count=46,successful_request_latency_sum=321.19012999999995 1459263300727174463
|
||||
> cloudwatch_aws_dynamo_db,host=vljosa-yieldbot.local,table_name=dev-platform-datomic-config consumed_write_capacity_units_average=1,consumed_write_capacity_units_maximum=1,consumed_write_capacity_units_minimum=1,consumed_write_capacity_units_sample_count=48,consumed_write_capacity_units_sum=48 1459263300760742003
|
||||
> cloudwatch_aws_dynamo_db,host=vljosa-yieldbot.local,table_name=prd-platform-datomic-config consumed_read_capacity_units_average=1.8539288112827401,consumed_read_capacity_units_maximum=8,consumed_read_capacity_units_minimum=0.5,consumed_read_capacity_units_sample_count=1489,consumed_read_capacity_units_sum=2760.5 1459263300832984286
|
||||
> cloudwatch_aws_dynamo_db,host=vljosa-yieldbot.local,operation=GetItem,table_name=prd-platform-datomic-config successful_request_latency_average=5.014870193569996,successful_request_latency_maximum=56.839959,successful_request_latency_minimum=2.030115,successful_request_latency_sample_count=1493,successful_request_latency_sum=7487.201199000004 1459263300868485699
|
||||
> cloudwatch_aws_dynamo_db,host=vljosa-yieldbot.local,operation=PutItem,table_name=prd-platform-datomic-config successful_request_latency_average=9.664095158730158,successful_request_latency_maximum=25.262,successful_request_latency_minimum=3.533,successful_request_latency_sample_count=63,successful_request_latency_sum=608.837995 1459263300990375223
|
||||
2016/03/29 10:55:01 Gathered metrics, (5m0s interval), from 1 inputs in 1.048629086s
|
||||
2016/03/29 10:55:03 Wrote 8 metrics to output influxdb in 90.0269ms
|
||||
```
|
|
@ -0,0 +1,164 @@
|
|||
package cloudwatch
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"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/azer/snakecase"
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/plugins/inputs"
|
||||
"log"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Cloudwatch struct {
|
||||
Region string
|
||||
Namespaces []string
|
||||
|
||||
// List of metrics to gather statistics for. Computed the first time Gather() is called.
|
||||
metrics []*cloudwatch.Metric
|
||||
// Get metrics statistics since last time Gather() was called.
|
||||
lastTime *time.Time
|
||||
}
|
||||
|
||||
var sampleConfig = `
|
||||
## AWS region
|
||||
region = "us-east-1"
|
||||
## specify namespaces as strings
|
||||
namespaces = ["AWS/EC2", "AWS/DynamoDB"]
|
||||
`
|
||||
|
||||
func (r *Cloudwatch) SampleConfig() string {
|
||||
return sampleConfig
|
||||
}
|
||||
|
||||
func (r *Cloudwatch) Description() string {
|
||||
return "Read metrics from AWS CloudWatch"
|
||||
}
|
||||
|
||||
// Reads stats from AWS CloudWatch. Accumulates stats.
|
||||
// Returns one of the errors encountered while gathering stats (if any).
|
||||
func (r *Cloudwatch) Gather(acc telegraf.Accumulator) error {
|
||||
svc := cloudwatch.New(session.New(), &aws.Config{Region: aws.String(r.Region)})
|
||||
var outerr error
|
||||
now := time.Now()
|
||||
if r.lastTime == nil {
|
||||
r.metrics, outerr = listMetrics(svc, r.Namespaces)
|
||||
log.Printf("Found %d cloudwatch metrics", len(r.metrics))
|
||||
} else {
|
||||
for i := 0; i < len(r.metrics); i++ {
|
||||
metric := r.metrics[i]
|
||||
minutes := int64(now.Sub(*r.lastTime) / time.Minute)
|
||||
if minutes == 0 {
|
||||
minutes = 1
|
||||
}
|
||||
period := minutes * 60
|
||||
outerr = gatherMetric(svc, r.Region, acc, metric, *r.lastTime, now, period)
|
||||
}
|
||||
}
|
||||
r.lastTime = &now
|
||||
return outerr
|
||||
}
|
||||
|
||||
type listMetricsAPI interface {
|
||||
ListMetrics(*cloudwatch.ListMetricsInput) (*cloudwatch.ListMetricsOutput, error)
|
||||
}
|
||||
|
||||
func listMetrics(svc listMetricsAPI, namespaces []string) ([]*cloudwatch.Metric, error) {
|
||||
metrics := []*cloudwatch.Metric{}
|
||||
for i := 0; i < len(namespaces); i++ {
|
||||
namespace := namespaces[i]
|
||||
params := &cloudwatch.ListMetricsInput{
|
||||
Dimensions: []*cloudwatch.DimensionFilter{},
|
||||
MetricName: nil,
|
||||
Namespace: aws.String(namespace),
|
||||
NextToken: nil,
|
||||
}
|
||||
resp, err := svc.ListMetrics(params)
|
||||
if err != nil {
|
||||
return []*cloudwatch.Metric{}, err
|
||||
}
|
||||
metrics = append(metrics, resp.Metrics...)
|
||||
}
|
||||
return metrics, nil
|
||||
|
||||
}
|
||||
|
||||
type getMetricStatisticsAPI interface {
|
||||
GetMetricStatistics(*cloudwatch.GetMetricStatisticsInput) (*cloudwatch.GetMetricStatisticsOutput, error)
|
||||
}
|
||||
|
||||
func gatherMetric(svc getMetricStatisticsAPI, region string, acc telegraf.Accumulator, metric *cloudwatch.Metric, startTime time.Time, endTime time.Time, period int64) error {
|
||||
r, err := svc.GetMetricStatistics(&cloudwatch.GetMetricStatisticsInput{
|
||||
Namespace: metric.Namespace,
|
||||
MetricName: metric.MetricName,
|
||||
Dimensions: metric.Dimensions,
|
||||
Statistics: []*string{
|
||||
aws.String("Average"),
|
||||
aws.String("Maximum"),
|
||||
aws.String("Minimum"),
|
||||
aws.String("Sum"),
|
||||
aws.String("SampleCount")},
|
||||
StartTime: &startTime,
|
||||
EndTime: &endTime,
|
||||
Period: &period,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(r.Datapoints) == 0 {
|
||||
return nil
|
||||
}
|
||||
if len(r.Datapoints) != 1 {
|
||||
return errors.New(fmt.Sprintf("Expected one datapoint, received %d", len(r.Datapoints)))
|
||||
}
|
||||
dp := r.Datapoints[0]
|
||||
fields := make(map[string]interface{})
|
||||
if dp.Average != nil {
|
||||
fields[formatField(*metric.MetricName, "average")] = *dp.Average
|
||||
}
|
||||
if dp.Maximum != nil {
|
||||
fields[formatField(*metric.MetricName, "maximum")] = *dp.Maximum
|
||||
}
|
||||
if dp.Minimum != nil {
|
||||
fields[formatField(*metric.MetricName, "minimum")] = *dp.Minimum
|
||||
}
|
||||
if dp.Sum != nil {
|
||||
fields[formatField(*metric.MetricName, "sum")] = *dp.Sum
|
||||
}
|
||||
if dp.SampleCount != nil {
|
||||
fields[formatField(*metric.MetricName, "sample_count")] = *dp.SampleCount
|
||||
}
|
||||
tags := getTags(region, metric.Dimensions)
|
||||
acc.AddFields(formatMeasurement(*metric.Namespace), fields, tags)
|
||||
return nil
|
||||
}
|
||||
|
||||
func getTags(region string, dimensions []*cloudwatch.Dimension) map[string]string {
|
||||
tags := make(map[string]string)
|
||||
tags["region"] = region
|
||||
for _, d := range dimensions {
|
||||
tags[snakecase.SnakeCase(*d.Name)] = *d.Value
|
||||
}
|
||||
return tags
|
||||
}
|
||||
|
||||
func formatField(metricName string, statistic string) string {
|
||||
return fmt.Sprintf("%s_%s", snakecase.SnakeCase(metricName), statistic)
|
||||
}
|
||||
|
||||
func formatMeasurement(namespace string) string {
|
||||
ns := snakecase.SnakeCase(namespace)
|
||||
ns = strings.Replace(ns, "/", "_", -1)
|
||||
ns = strings.Replace(ns, "__", "_", -1)
|
||||
return fmt.Sprintf("cloudwatch_%s", ns)
|
||||
}
|
||||
|
||||
func init() {
|
||||
inputs.Add("cloudwatch", func() telegraf.Input {
|
||||
return &Cloudwatch{}
|
||||
})
|
||||
}
|
|
@ -0,0 +1,237 @@
|
|||
package cloudwatch
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/cloudwatch"
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ListMetricsMock struct{}
|
||||
|
||||
func (lmm *ListMetricsMock) ListMetrics(params *cloudwatch.ListMetricsInput) (*cloudwatch.ListMetricsOutput, error) {
|
||||
switch *params.Namespace {
|
||||
case "AWS/EC2":
|
||||
return &cloudwatch.ListMetricsOutput{
|
||||
Metrics: []*cloudwatch.Metric{
|
||||
&cloudwatch.Metric{
|
||||
Dimensions: []*cloudwatch.Dimension{
|
||||
&cloudwatch.Dimension{
|
||||
Name: aws.String("InstanceId"),
|
||||
Value: aws.String("i-a6c5c510"),
|
||||
},
|
||||
},
|
||||
MetricName: aws.String("DiskReadBytes"),
|
||||
Namespace: aws.String("AWS/EC2"),
|
||||
},
|
||||
&cloudwatch.Metric{
|
||||
Dimensions: []*cloudwatch.Dimension{
|
||||
&cloudwatch.Dimension{
|
||||
Name: aws.String("InstanceId"),
|
||||
Value: aws.String("i-10a2c094"),
|
||||
},
|
||||
},
|
||||
MetricName: aws.String("DiskWriteBytes"),
|
||||
Namespace: aws.String("AWS/EC2"),
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
case "AWS/DynamoDB":
|
||||
return &cloudwatch.ListMetricsOutput{
|
||||
Metrics: []*cloudwatch.Metric{
|
||||
&cloudwatch.Metric{
|
||||
Dimensions: []*cloudwatch.Dimension{
|
||||
&cloudwatch.Dimension{
|
||||
Name: aws.String("Operation"),
|
||||
Value: aws.String("GetItem"),
|
||||
},
|
||||
&cloudwatch.Dimension{
|
||||
Name: aws.String("TableName"),
|
||||
Value: aws.String("foo"),
|
||||
},
|
||||
},
|
||||
MetricName: aws.String("ThrottledRequests"),
|
||||
Namespace: aws.String("AWS/DynamoDB"),
|
||||
},
|
||||
&cloudwatch.Metric{
|
||||
Dimensions: []*cloudwatch.Dimension{
|
||||
&cloudwatch.Dimension{
|
||||
Name: aws.String("Operation"),
|
||||
Value: aws.String("PutItem"),
|
||||
},
|
||||
&cloudwatch.Dimension{
|
||||
Name: aws.String("TableName"),
|
||||
Value: aws.String("foo"),
|
||||
},
|
||||
},
|
||||
MetricName: aws.String("ThrottledRequests"),
|
||||
Namespace: aws.String("AWS/DynamoDB"),
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
default:
|
||||
return nil, errors.New("No such namespace")
|
||||
}
|
||||
}
|
||||
|
||||
func TestListMetrics(t *testing.T) {
|
||||
var lmm ListMetricsMock
|
||||
|
||||
metrics, err := listMetrics(&lmm, []string{"AWS/EC2"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(metrics) != 2 {
|
||||
t.Fatal("Expected 2 AWS/EC2 metrics, found ", len(metrics))
|
||||
}
|
||||
|
||||
allMetrics, err := listMetrics(&lmm, []string{"AWS/EC2", "AWS/DynamoDB"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(allMetrics) != 4 {
|
||||
t.Fatal("Expected 4 AWS/EC2 and AWS/DynamoDB metrics, found ", len(allMetrics))
|
||||
}
|
||||
}
|
||||
|
||||
type GetMetricStatisticsMock struct{}
|
||||
|
||||
func (gmsm *GetMetricStatisticsMock) GetMetricStatistics(input *cloudwatch.GetMetricStatisticsInput) (*cloudwatch.GetMetricStatisticsOutput, error) {
|
||||
timestamp := time.Unix(1459201201, 0)
|
||||
avg := float64(1.6295248026217786)
|
||||
maximum := float64(8.0)
|
||||
minimum := float64(0.5)
|
||||
sum := float64(10939.0)
|
||||
sampleCount := float64(6713.0)
|
||||
return &cloudwatch.GetMetricStatisticsOutput{
|
||||
Datapoints: []*cloudwatch.Datapoint{
|
||||
&cloudwatch.Datapoint{
|
||||
Timestamp: ×tamp,
|
||||
Average: &avg,
|
||||
Maximum: &maximum,
|
||||
Minimum: &minimum,
|
||||
Sum: &sum,
|
||||
SampleCount: &sampleCount,
|
||||
Unit: aws.String("Count"),
|
||||
},
|
||||
},
|
||||
Label: aws.String("ConsumedReadCapacityUnits"),
|
||||
}, nil
|
||||
}
|
||||
|
||||
type GetMetricStatisticsMockPartial struct{}
|
||||
|
||||
func (gmsm *GetMetricStatisticsMockPartial) GetMetricStatistics(input *cloudwatch.GetMetricStatisticsInput) (*cloudwatch.GetMetricStatisticsOutput, error) {
|
||||
timestamp := time.Unix(1459201201, 0)
|
||||
avg := float64(1.6295248026217786)
|
||||
return &cloudwatch.GetMetricStatisticsOutput{
|
||||
Datapoints: []*cloudwatch.Datapoint{
|
||||
&cloudwatch.Datapoint{
|
||||
Timestamp: ×tamp,
|
||||
Average: &avg,
|
||||
Unit: aws.String("Count"),
|
||||
},
|
||||
},
|
||||
Label: aws.String("ConsumedReadCapacityUnits"),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func TestGatherMetric(t *testing.T) {
|
||||
var svc GetMetricStatisticsMock
|
||||
var acc testutil.Accumulator
|
||||
metric := &cloudwatch.Metric{
|
||||
Dimensions: []*cloudwatch.Dimension{
|
||||
&cloudwatch.Dimension{
|
||||
Name: aws.String("TableName"),
|
||||
Value: aws.String("foo"),
|
||||
},
|
||||
},
|
||||
MetricName: aws.String("ConsumedReadCapacityUnits"),
|
||||
Namespace: aws.String("AWS/DynamoDB"),
|
||||
}
|
||||
bogusTime := time.Now()
|
||||
err := gatherMetric(&svc, "us-east-1", &acc, metric, bogusTime, bogusTime, 300)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
acc.AssertContainsTaggedFields(t, "cloudwatch_aws_dynamo_db",
|
||||
map[string]interface{}{"consumed_read_capacity_units_average": 1.6295248026217786,
|
||||
"consumed_read_capacity_units_maximum": 8.0,
|
||||
"consumed_read_capacity_units_minimum": 0.5,
|
||||
"consumed_read_capacity_units_sum": 10939.0,
|
||||
"consumed_read_capacity_units_sample_count": 6713.0,
|
||||
},
|
||||
map[string]string{
|
||||
"region": "us-east-1",
|
||||
"table_name": "foo",
|
||||
})
|
||||
}
|
||||
|
||||
// Test that it still works with only some statistics
|
||||
func TestGatherMetricPartial(t *testing.T) {
|
||||
var svc GetMetricStatisticsMockPartial
|
||||
var acc testutil.Accumulator
|
||||
metric := &cloudwatch.Metric{
|
||||
Dimensions: []*cloudwatch.Dimension{
|
||||
&cloudwatch.Dimension{
|
||||
Name: aws.String("TableName"),
|
||||
Value: aws.String("foo"),
|
||||
},
|
||||
},
|
||||
MetricName: aws.String("ConsumedReadCapacityUnits"),
|
||||
Namespace: aws.String("AWS/DynamoDB"),
|
||||
}
|
||||
bogusTime := time.Now()
|
||||
err := gatherMetric(&svc, "us-east-1", &acc, metric, bogusTime, bogusTime, 300)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
acc.AssertContainsTaggedFields(t, "cloudwatch_aws_dynamo_db",
|
||||
map[string]interface{}{"consumed_read_capacity_units_average": 1.6295248026217786},
|
||||
map[string]string{
|
||||
"region": "us-east-1",
|
||||
"table_name": "foo",
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetTags(t *testing.T) {
|
||||
tags := getTags("us-east-1", []*cloudwatch.Dimension{
|
||||
&cloudwatch.Dimension{
|
||||
Name: aws.String("Operation"),
|
||||
Value: aws.String("GetItem"),
|
||||
},
|
||||
&cloudwatch.Dimension{
|
||||
Name: aws.String("TableName"),
|
||||
Value: aws.String("foo"),
|
||||
},
|
||||
})
|
||||
if len(tags) != 3 {
|
||||
t.Fatal("Expected 3 tags, not ", len(tags))
|
||||
}
|
||||
if tags["region"] != "us-east-1" {
|
||||
t.Fatal("Expected the tag `region` with value `us-east-1`")
|
||||
}
|
||||
if tags["operation"] != "GetItem" {
|
||||
t.Fatal("Expected the tag `operation` with value `GetItem`")
|
||||
}
|
||||
if tags["table_name"] != "foo" {
|
||||
t.Fatal("Expected the tag `table_name` with value `foo`")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatField(t *testing.T) {
|
||||
if s := formatField("DiskWriteBytes", "average"); s != "disk_write_bytes_average" {
|
||||
t.Fatal("Field should not be ", s)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatMeasurement(t *testing.T) {
|
||||
if s := formatMeasurement("AWS/EC2"); s != "cloudwatch_aws_ec2" {
|
||||
t.Fatal("Measurement should not be ", s)
|
||||
}
|
||||
if s := formatMeasurement("AWS/DynamoDB"); s != "cloudwatch_aws_dynamo_db" {
|
||||
t.Fatal("Measurement should not be ", s)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue