Add timeout option to cloudwatch input (#6553)

This commit is contained in:
Greg 2019-10-21 15:18:55 -06:00 committed by Daniel Nelson
parent e5baf7de89
commit 8ec79513b6
2 changed files with 42 additions and 20 deletions

View File

@ -70,6 +70,9 @@ API endpoint. In the following order the plugin will attempt to authenticate.
## See http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch_limits.html ## See http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch_limits.html
# ratelimit = 25 # ratelimit = 25
## Timeout for http requests made by the cloudwatch client.
# timeout = "5s"
## Namespace-wide statistic filters. These allow fewer queries to be made to ## Namespace-wide statistic filters. These allow fewer queries to be made to
## cloudwatch. ## cloudwatch.
# statistic_include = [ "average", "sum", "minimum", "maximum", sample_count" ] # statistic_include = [ "average", "sum", "minimum", "maximum", sample_count" ]

View File

@ -3,6 +3,8 @@ package cloudwatch
import ( import (
"errors" "errors"
"fmt" "fmt"
"net"
"net/http"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -23,16 +25,17 @@ import (
type ( type (
// CloudWatch contains the configuration and cache for the cloudwatch plugin. // CloudWatch contains the configuration and cache for the cloudwatch plugin.
CloudWatch struct { CloudWatch struct {
Region string `toml:"region"` Region string `toml:"region"`
AccessKey string `toml:"access_key"` AccessKey string `toml:"access_key"`
SecretKey string `toml:"secret_key"` SecretKey string `toml:"secret_key"`
RoleARN string `toml:"role_arn"` RoleARN string `toml:"role_arn"`
Profile string `toml:"profile"` Profile string `toml:"profile"`
CredentialPath string `toml:"shared_credential_file"` CredentialPath string `toml:"shared_credential_file"`
Token string `toml:"token"` Token string `toml:"token"`
EndpointURL string `toml:"endpoint_url"` EndpointURL string `toml:"endpoint_url"`
StatisticExclude []string `toml:"statistic_exclude"` StatisticExclude []string `toml:"statistic_exclude"`
StatisticInclude []string `toml:"statistic_include"` StatisticInclude []string `toml:"statistic_include"`
Timeout internal.Duration `toml:"timeout"`
Period internal.Duration `toml:"period"` Period internal.Duration `toml:"period"`
Delay internal.Duration `toml:"delay"` Delay internal.Duration `toml:"delay"`
@ -133,6 +136,9 @@ func (c *CloudWatch) SampleConfig() string {
## See http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch_limits.html ## See http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch_limits.html
# ratelimit = 25 # ratelimit = 25
## Timeout for http requests made by the cloudwatch client.
# timeout = "5s"
## Namespace-wide statistic filters. These allow fewer queries to be made to ## Namespace-wide statistic filters. These allow fewer queries to be made to
## cloudwatch. ## cloudwatch.
# statistic_include = [ "average", "sum", "minimum", "maximum", sample_count" ] # statistic_include = [ "average", "sum", "minimum", "maximum", sample_count" ]
@ -183,10 +189,7 @@ func (c *CloudWatch) Gather(acc telegraf.Accumulator) error {
return err return err
} }
err = c.updateWindow(time.Now()) c.updateWindow(time.Now())
if err != nil {
return err
}
// Get all of the possible queries so we can send groups of 100. // Get all of the possible queries so we can send groups of 100.
queries, err := c.getDataQueries(filteredMetrics) queries, err := c.getDataQueries(filteredMetrics)
@ -235,7 +238,7 @@ func (c *CloudWatch) Gather(acc telegraf.Accumulator) error {
return c.aggregateMetrics(acc, results) return c.aggregateMetrics(acc, results)
} }
func (c *CloudWatch) initializeCloudWatch() error { func (c *CloudWatch) initializeCloudWatch() {
credentialConfig := &internalaws.CredentialConfig{ credentialConfig := &internalaws.CredentialConfig{
Region: c.Region, Region: c.Region,
AccessKey: c.AccessKey, AccessKey: c.AccessKey,
@ -248,10 +251,27 @@ func (c *CloudWatch) initializeCloudWatch() error {
} }
configProvider := credentialConfig.Credentials() configProvider := credentialConfig.Credentials()
cfg := &aws.Config{} cfg := &aws.Config{
HTTPClient: &http.Client{
// use values from DefaultTransport
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
DualStack: true,
}).DialContext,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
},
Timeout: c.Timeout.Duration,
},
}
loglevel := aws.LogOff loglevel := aws.LogOff
c.client = cloudwatch.New(configProvider, cfg.WithLogLevel(loglevel)) c.client = cloudwatch.New(configProvider, cfg.WithLogLevel(loglevel))
return nil
} }
type filteredMetric struct { type filteredMetric struct {
@ -370,7 +390,7 @@ func (c *CloudWatch) fetchNamespaceMetrics() ([]*cloudwatch.Metric, error) {
return metrics, nil return metrics, nil
} }
func (c *CloudWatch) updateWindow(relativeTo time.Time) error { func (c *CloudWatch) updateWindow(relativeTo time.Time) {
windowEnd := relativeTo.Add(-c.Delay.Duration) windowEnd := relativeTo.Add(-c.Delay.Duration)
if c.windowEnd.IsZero() { if c.windowEnd.IsZero() {
@ -382,8 +402,6 @@ func (c *CloudWatch) updateWindow(relativeTo time.Time) error {
} }
c.windowEnd = windowEnd c.windowEnd = windowEnd
return nil
} }
// getDataQueries gets all of the possible queries so we can maximize the request payload. // getDataQueries gets all of the possible queries so we can maximize the request payload.
@ -535,6 +553,7 @@ func init() {
return &CloudWatch{ return &CloudWatch{
CacheTTL: internal.Duration{Duration: time.Hour}, CacheTTL: internal.Duration{Duration: time.Hour},
RateLimit: 25, RateLimit: 25,
Timeout: internal.Duration{Duration: time.Second * 5},
} }
}) })
} }