chore: Update to AWS SDK v2 (#9647)
This commit is contained in:
parent
a4d8a4b84f
commit
06f2a37b4a
|
|
@ -1,11 +1,12 @@
|
|||
package aws
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/client"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"context"
|
||||
awsV2 "github.com/aws/aws-sdk-go-v2/aws"
|
||||
configV2 "github.com/aws/aws-sdk-go-v2/config"
|
||||
credentialsV2 "github.com/aws/aws-sdk-go-v2/credentials"
|
||||
stscredsV2 "github.com/aws/aws-sdk-go-v2/credentials/stscreds"
|
||||
"github.com/aws/aws-sdk-go-v2/service/sts"
|
||||
)
|
||||
|
||||
type CredentialConfig struct {
|
||||
|
|
@ -21,45 +22,66 @@ type CredentialConfig struct {
|
|||
WebIdentityTokenFile string `toml:"web_identity_token_file"`
|
||||
}
|
||||
|
||||
func (c *CredentialConfig) Credentials() (client.ConfigProvider, error) {
|
||||
func (c *CredentialConfig) Credentials() (awsV2.Config, error) {
|
||||
if c.RoleARN != "" {
|
||||
return c.assumeCredentials()
|
||||
}
|
||||
|
||||
return c.rootCredentials()
|
||||
}
|
||||
|
||||
func (c *CredentialConfig) rootCredentials() (client.ConfigProvider, error) {
|
||||
config := &aws.Config{
|
||||
Region: aws.String(c.Region),
|
||||
}
|
||||
if c.EndpointURL != "" {
|
||||
config.Endpoint = &c.EndpointURL
|
||||
}
|
||||
if c.AccessKey != "" || c.SecretKey != "" {
|
||||
config.Credentials = credentials.NewStaticCredentials(c.AccessKey, c.SecretKey, c.Token)
|
||||
} else if c.Profile != "" || c.Filename != "" {
|
||||
config.Credentials = credentials.NewSharedCredentials(c.Filename, c.Profile)
|
||||
func (c *CredentialConfig) rootCredentials() (awsV2.Config, error) {
|
||||
options := []func(*configV2.LoadOptions) error{
|
||||
configV2.WithRegion(c.Region),
|
||||
}
|
||||
|
||||
return session.NewSession(config)
|
||||
if c.EndpointURL != "" {
|
||||
resolver := awsV2.EndpointResolverFunc(func(service, region string) (awsV2.Endpoint, error) {
|
||||
return awsV2.Endpoint{
|
||||
URL: c.EndpointURL,
|
||||
HostnameImmutable: true,
|
||||
Source: awsV2.EndpointSourceCustom,
|
||||
}, nil
|
||||
})
|
||||
options = append(options, configV2.WithEndpointResolver(resolver))
|
||||
}
|
||||
|
||||
if c.Profile != "" {
|
||||
options = append(options, configV2.WithSharedConfigProfile(c.Profile))
|
||||
}
|
||||
if c.Filename != "" {
|
||||
options = append(options, configV2.WithSharedCredentialsFiles([]string{c.Filename}))
|
||||
}
|
||||
|
||||
if c.AccessKey != "" || c.SecretKey != "" {
|
||||
provider := credentialsV2.NewStaticCredentialsProvider(c.AccessKey, c.SecretKey, c.Token)
|
||||
options = append(options, configV2.WithCredentialsProvider(provider))
|
||||
}
|
||||
|
||||
return configV2.LoadDefaultConfig(context.Background(), options...)
|
||||
}
|
||||
|
||||
func (c *CredentialConfig) assumeCredentials() (client.ConfigProvider, error) {
|
||||
func (c *CredentialConfig) assumeCredentials() (awsV2.Config, error) {
|
||||
rootCredentials, err := c.rootCredentials()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config := &aws.Config{
|
||||
Region: aws.String(c.Region),
|
||||
Endpoint: &c.EndpointURL,
|
||||
return awsV2.Config{}, err
|
||||
}
|
||||
|
||||
var provider awsV2.CredentialsProvider
|
||||
stsService := sts.NewFromConfig(rootCredentials)
|
||||
if c.WebIdentityTokenFile != "" {
|
||||
config.Credentials = stscreds.NewWebIdentityCredentials(rootCredentials, c.RoleARN, c.RoleSessionName, c.WebIdentityTokenFile)
|
||||
provider = stscredsV2.NewWebIdentityRoleProvider(stsService, c.RoleARN, stscredsV2.IdentityTokenFile(c.WebIdentityTokenFile), func(opts *stscredsV2.WebIdentityRoleOptions) {
|
||||
if c.RoleSessionName != "" {
|
||||
opts.RoleSessionName = c.RoleSessionName
|
||||
}
|
||||
})
|
||||
} else {
|
||||
config.Credentials = stscreds.NewCredentials(rootCredentials, c.RoleARN)
|
||||
provider = stscredsV2.NewAssumeRoleProvider(stsService, c.RoleARN, func(opts *stscredsV2.AssumeRoleOptions) {
|
||||
if c.RoleSessionName != "" {
|
||||
opts.RoleSessionName = c.RoleSessionName
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return session.NewSession(config)
|
||||
rootCredentials.Credentials = awsV2.NewCredentialsCache(provider)
|
||||
return rootCredentials, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,17 +36,27 @@ following works:
|
|||
- github.com/aws/aws-sdk-go-v2 [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/LICENSE.txt)
|
||||
- github.com/aws/aws-sdk-go-v2/config [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/config/LICENSE.txt)
|
||||
- github.com/aws/aws-sdk-go-v2/credentials [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/credentials/LICENSE.txt)
|
||||
- github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/feature/dynamodb/attributevalue/LICENSE.txt)
|
||||
- github.com/aws/aws-sdk-go-v2/feature/ec2/imds [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/feature/ec2/imds/LICENSE.txt)
|
||||
- github.com/aws/aws-sdk-go-v2/feature/s3/manager [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/LICENSE.txt)
|
||||
- github.com/aws/aws-sdk-go-v2/internal/ini [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/ec2/LICENSE.txt)
|
||||
- github.com/aws/aws-sdk-go-v2/feature/s3/manager [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/feature/s3/manager/LICENSE.txt)
|
||||
- github.com/aws/aws-sdk-go-v2/internal/configsources [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/internal/configsources/LICENSE.txt)
|
||||
- github.com/aws/aws-sdk-go-v2/internal/ini [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/internal/ini/LICENSE.txt)
|
||||
- github.com/aws/aws-sdk-go-v2/service/cloudwatch [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/cloudwatch/LICENSE.txt)
|
||||
- github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/cloudwatchlogs/LICENSE.txt)
|
||||
- github.com/aws/aws-sdk-go-v2/service/dynamodb [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/dynamodb/LICENSE.txt)
|
||||
- github.com/aws/aws-sdk-go-v2/service/dynamodbstreams [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/dynamodbstreams/LICENSE.txt)
|
||||
- github.com/aws/aws-sdk-go-v2/service/ec2 [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/ec2/LICENSE.txt)
|
||||
- github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/internal/accept-encoding/LICENSE.txt)
|
||||
- github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/internal/endpoint-discovery/LICENSE.txt)
|
||||
- github.com/aws/aws-sdk-go-v2/service/internal/presigned-url [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/internal/presigned-url/LICENSE.txt)
|
||||
- github.com/aws/aws-sdk-go-v2/service/internal/s3shared [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/internal/s3shared/LICENSE.txt)
|
||||
- github.com/aws/aws-sdk-go-v2/service/kinesis [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/kinesis/LICENSE.txt)
|
||||
- github.com/aws/aws-sdk-go-v2/service/s3 [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/s3/LICENSE.txt)
|
||||
- github.com/aws/aws-sdk-go-v2/service/sso [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/ec2/LICENSE.txt)
|
||||
- github.com/aws/aws-sdk-go-v2/service/sts [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/sts/LICENSE.txt)
|
||||
- github.com/aws/aws-sdk-go-v2/service/timestreamwrite [Apache License 2.0](https://github.com/aws/aws-sdk-go-v2/blob/main/service/timestreamwrite/LICENSE.txt)
|
||||
- github.com/aws/smithy-go [Apache License 2.0](https://github.com/aws/smithy-go/blob/main/LICENSE)
|
||||
- github.com/awslabs/kinesis-aggregation/go [Apache License 2.0](https://github.com/awslabs/kinesis-aggregation/blob/master/LICENSE.txt)
|
||||
- github.com/benbjohnson/clock [MIT License](https://github.com/benbjohnson/clock/blob/master/LICENSE)
|
||||
- github.com/beorn7/perks [MIT License](https://github.com/beorn7/perks/blob/master/LICENSE)
|
||||
- github.com/bmatcuk/doublestar [MIT License](https://github.com/bmatcuk/doublestar/blob/master/LICENSE)
|
||||
|
|
|
|||
24
go.mod
24
go.mod
|
|
@ -47,19 +47,26 @@ require (
|
|||
github.com/aristanetworks/glog v0.0.0-20191112221043-67e8567f59f3 // indirect
|
||||
github.com/aristanetworks/goarista v0.0.0-20190325233358-a123909ec740
|
||||
github.com/armon/go-metrics v0.3.3 // indirect
|
||||
github.com/aws/aws-sdk-go v1.38.69
|
||||
github.com/aws/aws-sdk-go-v2 v1.9.1
|
||||
github.com/aws/aws-sdk-go-v2/config v1.8.2
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.4.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.4.2
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.5.1
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.5.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.0.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.2.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.7.0
|
||||
github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.5.2
|
||||
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.5.0
|
||||
github.com/aws/aws-sdk-go-v2/service/ec2 v1.1.0
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.3.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.1.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.3.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.7.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/kinesis v1.6.0
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.16.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.4.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.7.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.7.1
|
||||
github.com/aws/aws-sdk-go-v2/service/timestreamwrite v1.3.2
|
||||
github.com/aws/smithy-go v1.8.0
|
||||
github.com/benbjohnson/clock v1.1.0
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
|
|
@ -129,8 +136,8 @@ require (
|
|||
github.com/grid-x/serial v0.0.0-20191104121038-e24bc9bf6f08 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
|
||||
github.com/harlow/kinesis-consumer v0.3.1-0.20181230152818-2f58b136fee0
|
||||
github.com/hashicorp/consul/api v1.11.0
|
||||
github.com/harlow/kinesis-consumer v0.3.6-0.20210911031324-5a873d6e9fec
|
||||
github.com/hashicorp/consul/api v1.9.1
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1 // indirect
|
||||
github.com/hashicorp/go-hclog v0.16.2 // indirect
|
||||
github.com/hashicorp/go-immutable-radix v1.2.0 // indirect
|
||||
|
|
@ -264,7 +271,7 @@ require (
|
|||
github.com/xdg/scram v1.0.3
|
||||
github.com/xdg/stringprep v1.0.3 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
|
||||
github.com/yuin/gopher-lua v0.0.0-20180630135845-46796da1b0b4 // indirect
|
||||
github.com/yuin/gopher-lua v0.0.0-20200603152657-dc2b0ca8b37e // indirect
|
||||
go.etcd.io/etcd/api/v3 v3.5.0 // indirect
|
||||
go.mongodb.org/mongo-driver v1.5.3
|
||||
go.opencensus.io v0.23.0 // indirect
|
||||
|
|
@ -327,7 +334,10 @@ require (
|
|||
)
|
||||
|
||||
require (
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.2.3 // indirect
|
||||
github.com/aws/aws-sdk-go v1.38.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.2.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.4.0 // indirect
|
||||
github.com/awslabs/kinesis-aggregation/go v0.0.0-20210630091500-54e17340d32f // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.1.1 // indirect
|
||||
github.com/jcmturner/aescts/v2 v2.0.0 // indirect
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect
|
||||
|
|
|
|||
105
go.sum
105
go.sum
|
|
@ -153,7 +153,9 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ
|
|||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||
github.com/DataDog/sketches-go v0.0.0-20190923095040-43f19ad77ff7/go.mod h1:Q5DbzQ+3AkgGwymQO7aZFNP7ns2lZKGtvRBzRXfdi60=
|
||||
github.com/DataDog/zstd v1.3.6-0.20190409195224-796139022798/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
|
||||
github.com/DataDog/zstd v1.4.4/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
|
||||
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
|
||||
|
|
@ -238,6 +240,8 @@ github.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15 h1:AUNCr9CiJuwrRY
|
|||
github.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=
|
||||
github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
|
||||
github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE=
|
||||
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
|
||||
github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk=
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1004 h1:YtaYjXmemIMyySUbs0VGFPqsLpsNHf4TW/L6yqpJQ9s=
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1004/go.mod h1:pUKYbK5JQ+1Dfxk80P0qxGqe5dkxDoabbZS7zOcouyA=
|
||||
github.com/amir/raidman v0.0.0-20170415203553-1ccc43bfb9c9 h1:FXrPTd8Rdlc94dKccl7KPmdmIbVh/OjelJ8/vgMRzcQ=
|
||||
|
|
@ -265,6 +269,10 @@ github.com/apache/thrift v0.14.1/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb
|
|||
github.com/apache/thrift v0.14.2/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/apache/thrift v0.15.0 h1:aGvdaR0v1t9XLgjtBYwxcBvBOTMqClzwE26CHOgjW1Y=
|
||||
github.com/apache/thrift v0.15.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU=
|
||||
github.com/apex/log v1.6.0/go.mod h1:x7s+P9VtvFBXge9Vbn+8TrqKmuzmD35TTkeBHul8UtY=
|
||||
github.com/apex/logs v1.0.0/go.mod h1:XzxuLZ5myVHDy9SAmYpamKKRNApGj54PfYLcFrXqDwo=
|
||||
github.com/aphistic/golf v0.0.0-20180712155816-02c07f170c5a/go.mod h1:3NqKYiepwy8kCu4PNA+aP7WUV72eXWJeP9/r3/K9aLE=
|
||||
github.com/aphistic/sweet v0.2.0/go.mod h1:fWDlIh/isSE9n6EPsRmC0det+whmX6dJid3stzu0Xys=
|
||||
github.com/aristanetworks/glog v0.0.0-20191112221043-67e8567f59f3 h1:Bmjk+DjIi3tTAU0wxGaFbfjGUqlxxSXARq9A96Kgoos=
|
||||
github.com/aristanetworks/glog v0.0.0-20191112221043-67e8567f59f3/go.mod h1:KASm+qXFKs/xjSoWn30NrWBBvdTTQq+UjkhjEJHfSFA=
|
||||
github.com/aristanetworks/goarista v0.0.0-20190325233358-a123909ec740 h1:FD4/ikKOFxwP8muWDypbmBWc634+YcAs3eBrYAmRdZY=
|
||||
|
|
@ -287,56 +295,111 @@ github.com/ashanbrown/forbidigo v1.1.0/go.mod h1:vVW7PEdqEFqapJe95xHkTfB1+XvZXBF
|
|||
github.com/ashanbrown/makezero v0.0.0-20201205152432-7b7cdbb3025a/go.mod h1:oG9Dnez7/ESBqc4EdrdNlryeo7d0KcW1ftXHm7nU/UU=
|
||||
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
|
||||
github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
|
||||
github.com/aws/aws-sdk-go v1.19.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.20.6/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
|
||||
github.com/aws/aws-sdk-go v1.38.3 h1:QCL/le04oAz2jELMRSuJVjGT7H+4hhoQc66eMPCfU/k=
|
||||
github.com/aws/aws-sdk-go v1.38.3/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
|
||||
github.com/aws/aws-sdk-go v1.38.69 h1:V489lmrdkIQSfF6OAGZZ1Cavcm7eczCm2JcGvX+yHRg=
|
||||
github.com/aws/aws-sdk-go v1.38.69/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
|
||||
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||
github.com/aws/aws-sdk-go-v2 v1.1.0/go.mod h1:smfAbmpW+tcRVuNUjo3MOArSZmW72t62rkCzc2i0TWM=
|
||||
github.com/aws/aws-sdk-go-v2 v1.8.0/go.mod h1:xEFuWz+3TYdlPRuo+CqATbeDWIWyaT5uAPwPaWtgse0=
|
||||
github.com/aws/aws-sdk-go-v2 v1.8.0/go.mod h1:xEFuWz+3TYdlPRuo+CqATbeDWIWyaT5uAPwPaWtgse0=
|
||||
github.com/aws/aws-sdk-go-v2 v1.8.0/go.mod h1:xEFuWz+3TYdlPRuo+CqATbeDWIWyaT5uAPwPaWtgse0=
|
||||
github.com/aws/aws-sdk-go-v2 v1.8.1/go.mod h1:xEFuWz+3TYdlPRuo+CqATbeDWIWyaT5uAPwPaWtgse0=
|
||||
github.com/aws/aws-sdk-go-v2 v1.9.0/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4=
|
||||
github.com/aws/aws-sdk-go-v2 v1.9.1 h1:ZbovGV/qo40nrOJ4q8G33AGICzaPI45FHQWJ9650pF4=
|
||||
github.com/aws/aws-sdk-go-v2 v1.9.1/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.6.0/go.mod h1:TNtBVmka80lRPk5+S9ZqVfFszOQAGJJ9KbT3EM3CHNU=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.6.0/go.mod h1:TNtBVmka80lRPk5+S9ZqVfFszOQAGJJ9KbT3EM3CHNU=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.6.1/go.mod h1:t/y3UPu0XEDy0cEw6mvygaBQaPzWiYAxfP2SzgtvclA=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.8.2 h1:Dqy4ySXFmulRmZhfynm/5CD4Y6aXiTVhDtXLIuUe/r0=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.8.2/go.mod h1:r0bkX9NyuCuf28qVcsEMtpAQibT7gA1Q0gzkjvgJdLU=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.3.2/go.mod h1:PACKuTJdt6AlXvEq8rFI4eDmoqDFC5DpVKQbWysaDgM=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.3.2/go.mod h1:PACKuTJdt6AlXvEq8rFI4eDmoqDFC5DpVKQbWysaDgM=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.3.3/go.mod h1:oVieKMT3m9BSfqhOfuQ+E0j/yN84ZAJ7Qv8Sfume/ak=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.4.2 h1:8kVE4Og6wlhVrMGiORQ3p9gRj2exjzhFRB+QzWBUa5Q=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.4.2/go.mod h1:9Sp6u121/f0NnvHyhG7dgoYeUTEFC2vsvJqJ6wXpkaI=
|
||||
github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.2.0 h1:8kvinmbIDObqsWegKP0JjeanYPiA4GUVpAtciNWE+jw=
|
||||
github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.2.0/go.mod h1:UVFtSYSWCHj2+brBLDHUdlJXmz8LxUpZhA+Ewypc+xQ=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.4.0/go.mod h1:Mj/U8OpDbcVcoctrYwA2bak8k/HFPdcLzI/vaiXMwuM=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.4.0/go.mod h1:Mj/U8OpDbcVcoctrYwA2bak8k/HFPdcLzI/vaiXMwuM=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.4.1/go.mod h1:+GTydg3uHmVlQdkRoetz6VHKbOMEYof70m19IpMLifc=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.5.1 h1:Nm+BxqBtT0r+AnD6byGMCGT4Km0QwHBy8mAYptNPXY4=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.5.1/go.mod h1:W1ldHfsgeGlKpJ4xZMKZUI6Wmp6EAstU7PxnhbXWWrI=
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.4.0/go.mod h1:eHwXu2+uE/T6gpnYWwBwqoeqRf9IXyCcolyOWDRAErQ=
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.5.3 h1:0O72494cCsazjpsGfo+LXezru6PMSp0HUB1m5UfpaRU=
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.5.3/go.mod h1:claNkz2j/N/AZceFcAbR0NyuWnrn+jCYpI+6Ozjsc0k=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.0.2/go.mod h1:1QsSZvLUuaQ6VJsCXolYCEzV0mVBkNBp64pIJy9yRks=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.0.2/go.mod h1:1QsSZvLUuaQ6VJsCXolYCEzV0mVBkNBp64pIJy9yRks=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.0.4 h1:IM9b6hlCcVFJFydPoyphs/t7YrHfqKy7T4/7AG5Eprs=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.0.4/go.mod h1:W5gGbtNXFpF9/ssYZTaItzG/B+j0bjTnwStiCP2AtWU=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.2.0/go.mod h1:Q5jATQc+f1MfZp3PDMhn6ry18hGvE0i8yvbXoKbnZaE=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.2.0/go.mod h1:Q5jATQc+f1MfZp3PDMhn6ry18hGvE0i8yvbXoKbnZaE=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.2.0/go.mod h1:Q5jATQc+f1MfZp3PDMhn6ry18hGvE0i8yvbXoKbnZaE=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.2.1/go.mod h1:Pv3WenDjI0v2Jl7UaMFIIbPOBbhn33RmmAmGgkXDoqY=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.2.3 h1:NnXJXUz7oihrSlPKEM0yZ19b+7GQ47MX/LluLlEyE/Y=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.2.3/go.mod h1:EES9ToeC3h063zCFDdqWGnARExNdULPaBvARm1FLwxA=
|
||||
github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.7.0 h1:vXZPcDQg7e5z2IKz0huei6zhfAxDoZdXej2o3jUbjCI=
|
||||
github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.7.0/go.mod h1:BlrFkwOhSgESkbdS+zJBy4+1mQ3f3Fq9Gp8nT+gaSwk=
|
||||
github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.5.2 h1:B120/boLr82yRaQFEPn9u01OwWMnc+xGvz5SOHfBrHY=
|
||||
github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.5.2/go.mod h1:td1djV1rAzEPcit9L8urGneIi2pYvtI7b/kfMWdpe84=
|
||||
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.5.0 h1:SGwKUQaJudQQZE72dDQlL2FGuHNAEK1CyqKLTjh6mqE=
|
||||
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.5.0/go.mod h1:XY5YhCS9SLul3JSQ08XG/nfxXxrkh6RR21XPq/J//NY=
|
||||
github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.4.0 h1:QbFWJr2SAyVYvyoOHvJU6sCGLnqNT94ZbWElJMEI1JY=
|
||||
github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.4.0/go.mod h1:bYsEP8w5YnbYyrx/Zi5hy4hTwRRQISSJS3RWrsGRijg=
|
||||
github.com/aws/aws-sdk-go-v2/service/ec2 v1.1.0 h1:+VnEgB1yp+7KlOsk6FXX/v/fU9uL5oSujIMkKQBBmp8=
|
||||
github.com/aws/aws-sdk-go-v2/service/ec2 v1.1.0/go.mod h1:/6514fU/SRcY3+ousB1zjUqiXjruSuti2qcfE70osOc=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.2.2/go.mod h1:EASdTcM1lGhUe1/p4gkojHwlGJkeoRjjr1sRCzup3Is=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.2.2/go.mod h1:EASdTcM1lGhUe1/p4gkojHwlGJkeoRjjr1sRCzup3Is=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.3.0 h1:gceOysEWNNwLd6cki65IMBZ4WAM0MwgBQq2n7kejoT8=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.3.0 h1:gceOysEWNNwLd6cki65IMBZ4WAM0MwgBQq2n7kejoT8=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.3.0/go.mod h1:v8ygadNyATSm6elwJ/4gzJwcFhri9RqS8skgHKiwXPU=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.3.0/go.mod h1:v8ygadNyATSm6elwJ/4gzJwcFhri9RqS8skgHKiwXPU=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.0.2/go.mod h1:Gej5xRE+MK0r35OnxJJ07iqQ5JC1avTW/4MwGfsC2io=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.1.0 h1:QCPbsMPMcM4iGbui5SH6O4uxvZffPoBJ4CIGX7dU0l4=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.1.0/go.mod h1:enkU5tq2HoXY+ZMiQprgF3Q83T3PbO77E83yXXzRZWE=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.1/go.mod h1:PISaKWylTYAyruocNk4Lr9miOOJjOcVBd7twCPbydDk=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.2.2/go.mod h1:NXmNI41bdEsJMrD0v9rUvbGCB5GwdBEpKvUvIY3vTFg=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.2.2/go.mod h1:NXmNI41bdEsJMrD0v9rUvbGCB5GwdBEpKvUvIY3vTFg=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.2.3/go.mod h1:7gcsONBmFoCcKrAqrm95trrMd2+C/ReYKP7Vfu8yHHA=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.3.1 h1:APEjhKZLFlNVLATnA/TJyA+w1r/xd5r5ACWBDZ9aIvc=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.3.1/go.mod h1:Ve+eJOx9UWaT/lMVebnFhDhO49fSLVedHoA82+Rqme0=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.5.2/go.mod h1:QuL2Ym8BkrLmN4lUofXYq6000/i5jPjosCNK//t6gak=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.7.1 h1:YEz2KMyqK2zyG3uOa0l2xBc/H6NUVJir8FhwHQHF3rc=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.7.1/go.mod h1:yg4EN/BKoc7+DLhNOxxdvoO3+iyW2FuynvaKqLcLDUM=
|
||||
github.com/aws/aws-sdk-go-v2/service/kinesis v1.6.0 h1:hb+NupVMUzINGUCfDs2+YqMkWKu47dBIQHpulM0XWh4=
|
||||
github.com/aws/aws-sdk-go-v2/service/kinesis v1.6.0/go.mod h1:9O7UG2pELnP0hq35+Gd7XDjOLBkg7tmgRQ0y14ZjoJI=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.12.0/go.mod h1:6J++A5xpo7QDsIeSqPK4UHqMSyPOCopa+zKtqAMhqVQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.16.0 h1:dt1JQFj/135ozwGIWeCM3aQ8N/kB3Xu3Uu4r9zuOIyc=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.16.0/go.mod h1:Tk23mCmfL3wb3tNIeMk/0diUZ0W4R6uZtjYKguMLW2s=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.3.2/go.mod h1:J21I6kF+d/6XHVk7kp/cx9YVD2TMD2TbLwtRGVcinXo=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.3.2/go.mod h1:J21I6kF+d/6XHVk7kp/cx9YVD2TMD2TbLwtRGVcinXo=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.3.3/go.mod h1:Jgw5O+SK7MZ2Yi9Yvzb4PggAPYaFSliiQuWR0hNjexk=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.4.1 h1:RfgQyv3bFT2Js6XokcrNtTjQ6wAVBRpoCgTFsypihHA=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.4.1/go.mod h1:ycPdbJZlM0BLhuBnd80WX9PucWPG88qps/2jl9HugXs=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.6.1/go.mod h1:hLZ/AnkIKHLuPGjEiyghNEdvJ2PP0MgOxcmv9EBJ4xs=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.6.1/go.mod h1:hLZ/AnkIKHLuPGjEiyghNEdvJ2PP0MgOxcmv9EBJ4xs=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.6.2/go.mod h1:RBhoMJB8yFToaCnbe0jNq5Dcdy0jp6LhHqg55rjClkM=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.7.1 h1:7ce9ugapSgBapwLhg7AJTqKW5U92VRX3vX65k2tsB+g=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.7.1/go.mod h1:r1i8QwKPzwByXqZb3POQfBs7jozrdnHz8PVbsvyx73w=
|
||||
github.com/aws/aws-sdk-go-v2/service/timestreamwrite v1.3.2 h1:1s/RRA5Owuz4/G/eWCdCKgC+9zaz2vxFsRSwe7R3cPY=
|
||||
github.com/aws/aws-sdk-go-v2/service/timestreamwrite v1.3.2 h1:1s/RRA5Owuz4/G/eWCdCKgC+9zaz2vxFsRSwe7R3cPY=
|
||||
github.com/aws/aws-sdk-go-v2/service/timestreamwrite v1.3.2/go.mod h1:XoDkdZ5pBf2za2GWbFHQ8Ps0K8fRbmbwrHh7PF5xnzQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/timestreamwrite v1.3.2/go.mod h1:XoDkdZ5pBf2za2GWbFHQ8Ps0K8fRbmbwrHh7PF5xnzQ=
|
||||
github.com/aws/smithy-go v1.0.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw=
|
||||
github.com/aws/smithy-go v1.0.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw=
|
||||
github.com/aws/smithy-go v1.7.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
|
||||
github.com/aws/smithy-go v1.7.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
|
||||
github.com/aws/smithy-go v1.7.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
|
||||
github.com/aws/smithy-go v1.8.0 h1:AEwwwXQZtUwP5Mz506FeXXrKBe0jA8gVM+1gEcSRooc=
|
||||
github.com/aws/smithy-go v1.8.0 h1:AEwwwXQZtUwP5Mz506FeXXrKBe0jA8gVM+1gEcSRooc=
|
||||
github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
|
||||
github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
|
||||
github.com/awslabs/kinesis-aggregation/go v0.0.0-20210630091500-54e17340d32f h1:Pf0BjJDga7C98f0vhw+Ip5EaiE07S3lTKpIYPNS0nMo=
|
||||
github.com/awslabs/kinesis-aggregation/go v0.0.0-20210630091500-54e17340d32f/go.mod h1:SghidfnxvX7ribW6nHI7T+IBbc9puZ9kk5Tx/88h8P4=
|
||||
github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I=
|
||||
github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
|
||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
|
|
@ -580,6 +643,7 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
|
|||
github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ=
|
||||
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
|
||||
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200624174652-8d2f3be8b2d9/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20200911182023-62edffca9245/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/digitalocean/godo v1.58.0/go.mod h1:p7dOjjtSBqCTUksqtA5Fd3uaKs9kyTq2xcz76ulEJRU=
|
||||
|
|
@ -819,6 +883,7 @@ github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3yg
|
|||
github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
|
||||
github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg=
|
||||
github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
github.com/go-redis/redis/v8 v8.0.0-beta.6/go.mod h1:g79Vpae8JMzg5qjk8BiwU9tK+HmU3iDVyS4UAJLFycI=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
|
|
@ -954,6 +1019,7 @@ github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZ
|
|||
github.com/golangci/misspell v0.3.5/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA=
|
||||
github.com/golangci/revgrep v0.0.0-20210208091834-cd28932614b5/go.mod h1:LK+zW4MpyytAWQRz0M4xnzEk50lSvqDQKfx304apFkY=
|
||||
github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/google/addlicense v0.0.0-20200906110928-a0294312aa76/go.mod h1:EMjYTRimagHs1FwlIqKyX3wAM0u3rA+McvlIIWmSamA=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
|
|
@ -1070,13 +1136,13 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFb
|
|||
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw=
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
|
||||
github.com/harlow/kinesis-consumer v0.3.1-0.20181230152818-2f58b136fee0 h1:U0KvGD9CJIl1nbgu9yLsfWxMT6WqL8fG0IBB7RvOZZQ=
|
||||
github.com/harlow/kinesis-consumer v0.3.1-0.20181230152818-2f58b136fee0/go.mod h1:dk23l2BruuUzRP8wbybQbPn3J7sZga2QHICCeaEy5rQ=
|
||||
github.com/harlow/kinesis-consumer v0.3.6-0.20210911031324-5a873d6e9fec h1:ya+kv1eNnd5QhcHuaj5g5eMq5Ra3VCNaPY2ZI7Aq91o=
|
||||
github.com/harlow/kinesis-consumer v0.3.6-0.20210911031324-5a873d6e9fec/go.mod h1:FIT1uhdVv2iXO0l6aACPZSVHxdth7RdmoT34jk9MEm0=
|
||||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
||||
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
|
||||
github.com/hashicorp/consul/api v1.8.1/go.mod h1:sDjTOq0yUyv5G4h+BqSea7Fn6BU+XbolEz1952UB+mk=
|
||||
github.com/hashicorp/consul/api v1.11.0 h1:Hw/G8TtRvOElqxVIhBzXciiSTbapq8hZ2XKZsXk5ZCE=
|
||||
github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=
|
||||
github.com/hashicorp/consul/api v1.9.1 h1:SngrdG2L62qqLsUz85qcPhFZ78rPf8tcD5qjMgs6MME=
|
||||
github.com/hashicorp/consul/api v1.9.1/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=
|
||||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
github.com/hashicorp/consul/sdk v0.7.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPAvlcdx16zZ0fM=
|
||||
|
|
@ -1344,6 +1410,7 @@ github.com/leoluk/perflib_exporter v0.1.0/go.mod h1:rpV0lYj7lemdTm31t7zpCqYqPnw7
|
|||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.9.0 h1:L8nSXQQzAYByakOFMTwpjRoHsMJklur4Gi59b6VivR8=
|
||||
github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
|
||||
|
|
@ -1415,6 +1482,7 @@ github.com/mdlayher/netlink v1.1.0 h1:mpdLgm+brq10nI9zM1BpX1kpDbh3NLl3RSnVq6ZSkf
|
|||
github.com/mdlayher/netlink v1.1.0/go.mod h1:H4WCitaheIsdF9yOYu8CFmCgQthAPIWZmcKp9uZHgmY=
|
||||
github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg=
|
||||
github.com/mgechev/revive v1.0.3/go.mod h1:POGGZagSo/0frdr7VeAifzS5Uka0d0GPiM35MsTO8nE=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/microsoft/ApplicationInsights-Go v0.4.4 h1:G4+H9WNs6ygSCe6sUyxRc2U81TI5Es90b2t/MwX5KqY=
|
||||
github.com/microsoft/ApplicationInsights-Go v0.4.4/go.mod h1:fKRUseBqkw6bDiXTs3ESTiU/4YTIHsQS4W3fP2ieF4U=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
|
|
@ -1609,6 +1677,7 @@ github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKw
|
|||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.1.1-0.20190913142402-a7454ce5950e/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
|
||||
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
|
||||
github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5 h1:ZCnq+JUrvXcDVhX/xRolRBZifmabN1HcS1wrPSvxhrU=
|
||||
|
|
@ -1767,6 +1836,7 @@ github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff/go.mod h1:xvqspo
|
|||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
|
|
@ -1846,11 +1916,14 @@ github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE
|
|||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sleepinggenius2/gosmi v0.4.3 h1:99Zwzy1Cvgsh396sw07oR2G4ab88ILGZFMxSlGWnR6o=
|
||||
github.com/sleepinggenius2/gosmi v0.4.3/go.mod h1:l8OniPmd3bJzw0MXP2/qh7AhP/e+bTY2CNivIhsnDT0=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8=
|
||||
github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
|
||||
github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/smartystreets/gunit v1.0.0/go.mod h1:qwPWnhz6pn0NnRBP++URONOVyNkPyr4SauJk4cUOwJs=
|
||||
github.com/snowflakedb/gosnowflake v1.6.2 h1:drZkX7Ve3qr3lLD/f0vxwesgJZfNerivknAvPRAMy88=
|
||||
github.com/snowflakedb/gosnowflake v1.6.2/go.mod h1:k1Wq+O8dRD/jmFBLyStEv2OrgHoMFQpqHCRSy70P0dI=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
|
|
@ -1934,6 +2007,12 @@ github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94/go.mod h1:Qimiff
|
|||
github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
github.com/tinylib/msgp v1.1.6 h1:i+SbKraHhnrf9M5MYmvQhFnbLhAXSDWF8WWsuyRdocw=
|
||||
github.com/tinylib/msgp v1.1.6/go.mod h1:75BAfg2hauQhs3qedfdDZmWAPcFMAvJE5b9rGOMufyw=
|
||||
github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0=
|
||||
github.com/tj/assert v0.0.3/go.mod h1:Ne6X72Q+TB1AteidzQncjw9PabbMp4PBMZ1k+vd1Pvk=
|
||||
github.com/tj/go-buffer v1.0.1/go.mod h1:iyiJpfFcR2B9sXu7KvjbT9fpM4mOelRSDTbntVj52Uc=
|
||||
github.com/tj/go-elastic v0.0.0-20171221160941-36157cbbebc2/go.mod h1:WjeM0Oo1eNAjXGDx2yma7uG2XoyRZTq1uv3M/o7imD0=
|
||||
github.com/tj/go-kinesis v0.0.0-20171128231115-08b17f58cb1b/go.mod h1:/yhzCV0xPfx6jb1bBgRFjl5lytqVqZXEaeqWP8lTEao=
|
||||
github.com/tj/go-spin v1.1.0/go.mod h1:Mg1mzmePZm4dva8Qz60H2lHwmJ2loum4VIrLgVnKwh4=
|
||||
github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI=
|
||||
github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev3vTo=
|
||||
github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs=
|
||||
|
|
@ -2020,8 +2099,8 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
|||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/gopher-lua v0.0.0-20180630135845-46796da1b0b4 h1:f6CCNiTjQZ0uWK4jPwhwYB8QIGGfn0ssD9kVzRUUUpk=
|
||||
github.com/yuin/gopher-lua v0.0.0-20180630135845-46796da1b0b4/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU=
|
||||
github.com/yuin/gopher-lua v0.0.0-20200603152657-dc2b0ca8b37e h1:oIpIX9VKxSCFrfjsKpluGbNPBGq9iNnT9crH781j9wY=
|
||||
github.com/yuin/gopher-lua v0.0.0-20200603152657-dc2b0ca8b37e/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ=
|
||||
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
|
||||
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
|
||||
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
|
||||
|
|
@ -2064,6 +2143,7 @@ go.opentelemetry.io/collector v0.28.0 h1:XmRwoSj3HZtC7O/12fBoQ9DInvwBwFHgHLZrwNx
|
|||
go.opentelemetry.io/collector v0.28.0/go.mod h1:AP/BTXwo1eedoJO7V+HQ68CSvJU1lcdqOzJCgt1VsNs=
|
||||
go.opentelemetry.io/collector/model v0.35.0 h1:NpKjghiqlei4ecwjOYOMhD6tj4gY8yiWHPJmbFs/ArI=
|
||||
go.opentelemetry.io/collector/model v0.35.0/go.mod h1:+7YCSjJG+MqiIFjauzt7oM2qkqBsaJWh5hcsO4fwsAc=
|
||||
go.opentelemetry.io/otel v0.7.0/go.mod h1:aZMyHG5TqDOXEgH2tyLiXSUKly1jT3yqE9PmrzIeCdo=
|
||||
go.opentelemetry.io/otel v1.0.0-RC3 h1:kvwiyEkiUT/JaadXzVLI/R1wDO934A7r3Bs2wEe6wqA=
|
||||
go.opentelemetry.io/otel v1.0.0-RC3/go.mod h1:Ka5j3ua8tZs4Rkq4Ex3hwgBgOchyPVq5S6P2lz//nKQ=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.23.0 h1:vKIEsT6IJU0NYd+iZccjgCmk80zsa7dTiC2Bu7U1jz0=
|
||||
|
|
@ -2119,6 +2199,7 @@ golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACk
|
|||
golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
|
|
@ -2164,8 +2245,9 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
|
|||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5 h1:FR+oGxGfbQu1d+jglI3rCkjAjUnhRSZcUxr+DqlDLNo=
|
||||
golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
|
||||
golang.org/x/exp v0.0.0-20200513190911-00229845015e h1:rMqLP+9XLy+LdbCXHjJHAmTfXCr93W7oruWA6Hq1Alc=
|
||||
golang.org/x/exp v0.0.0-20200513190911-00229845015e/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
|
||||
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
|
|
@ -2362,6 +2444,7 @@ golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20191003212358-c178f38b412c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
|
@ -2670,6 +2753,7 @@ google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98
|
|||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20191009194640-548a555dbc03/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
|
|
@ -2839,6 +2923,7 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package cloudwatch
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
|
|
@ -9,8 +10,9 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
cwClient "github.com/aws/aws-sdk-go/service/cloudwatch"
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
cwClient "github.com/aws/aws-sdk-go-v2/service/cloudwatch"
|
||||
"github.com/aws/aws-sdk-go-v2/service/cloudwatch/types"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/config"
|
||||
|
|
@ -23,6 +25,14 @@ import (
|
|||
"github.com/influxdata/telegraf/plugins/inputs"
|
||||
)
|
||||
|
||||
const (
|
||||
StatisticAverage = "Average"
|
||||
StatisticMaximum = "Maximum"
|
||||
StatisticMinimum = "Minimum"
|
||||
StatisticSum = "Sum"
|
||||
StatisticSampleCount = "SampleCount"
|
||||
)
|
||||
|
||||
// CloudWatch contains the configuration and cache for the cloudwatch plugin.
|
||||
type CloudWatch struct {
|
||||
StatisticExclude []string `toml:"statistic_exclude"`
|
||||
|
|
@ -72,12 +82,12 @@ type metricCache struct {
|
|||
ttl time.Duration
|
||||
built time.Time
|
||||
metrics []filteredMetric
|
||||
queries map[string][]*cwClient.MetricDataQuery
|
||||
queries map[string][]types.MetricDataQuery
|
||||
}
|
||||
|
||||
type cloudwatchClient interface {
|
||||
ListMetrics(*cwClient.ListMetricsInput) (*cwClient.ListMetricsOutput, error)
|
||||
GetMetricData(*cwClient.GetMetricDataInput) (*cwClient.GetMetricDataOutput, error)
|
||||
ListMetrics(context.Context, *cwClient.ListMetricsInput, ...func(*cwClient.Options)) (*cwClient.ListMetricsOutput, error)
|
||||
GetMetricData(context.Context, *cwClient.GetMetricDataInput, ...func(*cwClient.Options)) (*cwClient.GetMetricDataOutput, error)
|
||||
}
|
||||
|
||||
// SampleConfig returns the default configuration of the Cloudwatch input plugin.
|
||||
|
|
@ -227,12 +237,12 @@ func (c *CloudWatch) Gather(acc telegraf.Accumulator) error {
|
|||
wg := sync.WaitGroup{}
|
||||
rLock := sync.Mutex{}
|
||||
|
||||
results := map[string][]*cwClient.MetricDataResult{}
|
||||
results := map[string][]types.MetricDataResult{}
|
||||
|
||||
for namespace, namespacedQueries := range queries {
|
||||
// 500 is the maximum number of metric data queries a `GetMetricData` request can contain.
|
||||
batchSize := 500
|
||||
var batches [][]*cwClient.MetricDataQuery
|
||||
var batches [][]types.MetricDataQuery
|
||||
|
||||
for batchSize < len(namespacedQueries) {
|
||||
namespacedQueries, batches = namespacedQueries[batchSize:], append(batches, namespacedQueries[0:batchSize:batchSize])
|
||||
|
|
@ -242,7 +252,7 @@ func (c *CloudWatch) Gather(acc telegraf.Accumulator) error {
|
|||
for i := range batches {
|
||||
wg.Add(1)
|
||||
<-lmtr.C
|
||||
go func(n string, inm []*cwClient.MetricDataQuery) {
|
||||
go func(n string, inm []types.MetricDataQuery) {
|
||||
defer wg.Done()
|
||||
result, err := c.gatherMetrics(c.getDataInputs(inm))
|
||||
if err != nil {
|
||||
|
|
@ -268,8 +278,15 @@ func (c *CloudWatch) initializeCloudWatch() error {
|
|||
return err
|
||||
}
|
||||
|
||||
cfg := &aws.Config{
|
||||
HTTPClient: &http.Client{
|
||||
cfg, err := c.CredentialConfig.Credentials()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.client = cwClient.NewFromConfig(cfg, func(options *cwClient.Options) {
|
||||
// Disable logging
|
||||
options.ClientLogMode = 0
|
||||
|
||||
options.HTTPClient = &http.Client{
|
||||
// use values from DefaultTransport
|
||||
Transport: &http.Transport{
|
||||
Proxy: proxy,
|
||||
|
|
@ -284,15 +301,8 @@ func (c *CloudWatch) initializeCloudWatch() error {
|
|||
ExpectContinueTimeout: 1 * time.Second,
|
||||
},
|
||||
Timeout: time.Duration(c.Timeout),
|
||||
},
|
||||
}
|
||||
|
||||
loglevel := aws.LogOff
|
||||
p, err := c.CredentialConfig.Credentials()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.client = cwClient.New(p, cfg.WithLogLevel(loglevel))
|
||||
}
|
||||
})
|
||||
|
||||
// Initialize regex matchers for each Dimension value.
|
||||
for _, m := range c.Metrics {
|
||||
|
|
@ -310,7 +320,7 @@ func (c *CloudWatch) initializeCloudWatch() error {
|
|||
}
|
||||
|
||||
type filteredMetric struct {
|
||||
metrics []*cwClient.Metric
|
||||
metrics []types.Metric
|
||||
statFilter filter.Filter
|
||||
}
|
||||
|
||||
|
|
@ -325,18 +335,18 @@ func getFilteredMetrics(c *CloudWatch) ([]filteredMetric, error) {
|
|||
// check for provided metric filter
|
||||
if c.Metrics != nil {
|
||||
for _, m := range c.Metrics {
|
||||
metrics := []*cwClient.Metric{}
|
||||
metrics := []types.Metric{}
|
||||
if !hasWildcard(m.Dimensions) {
|
||||
dimensions := make([]*cwClient.Dimension, len(m.Dimensions))
|
||||
dimensions := make([]types.Dimension, len(m.Dimensions))
|
||||
for k, d := range m.Dimensions {
|
||||
dimensions[k] = &cwClient.Dimension{
|
||||
dimensions[k] = types.Dimension{
|
||||
Name: aws.String(d.Name),
|
||||
Value: aws.String(d.Value),
|
||||
}
|
||||
}
|
||||
for _, name := range m.MetricNames {
|
||||
for _, namespace := range c.Namespaces {
|
||||
metrics = append(metrics, &cwClient.Metric{
|
||||
metrics = append(metrics, types.Metric{
|
||||
Namespace: aws.String(namespace),
|
||||
MetricName: aws.String(name),
|
||||
Dimensions: dimensions,
|
||||
|
|
@ -352,7 +362,7 @@ func getFilteredMetrics(c *CloudWatch) ([]filteredMetric, error) {
|
|||
for _, metric := range allMetrics {
|
||||
if isSelected(name, metric, m.Dimensions) {
|
||||
for _, namespace := range c.Namespaces {
|
||||
metrics = append(metrics, &cwClient.Metric{
|
||||
metrics = append(metrics, types.Metric{
|
||||
Namespace: aws.String(namespace),
|
||||
MetricName: aws.String(name),
|
||||
Dimensions: metric.Dimensions,
|
||||
|
|
@ -401,32 +411,24 @@ func getFilteredMetrics(c *CloudWatch) ([]filteredMetric, error) {
|
|||
}
|
||||
|
||||
// fetchNamespaceMetrics retrieves available metrics for a given CloudWatch namespace.
|
||||
func (c *CloudWatch) fetchNamespaceMetrics() ([]*cwClient.Metric, error) {
|
||||
metrics := []*cwClient.Metric{}
|
||||
func (c *CloudWatch) fetchNamespaceMetrics() ([]types.Metric, error) {
|
||||
metrics := []types.Metric{}
|
||||
|
||||
var token *string
|
||||
var params *cwClient.ListMetricsInput
|
||||
var recentlyActive *string
|
||||
|
||||
switch c.RecentlyActive {
|
||||
case "PT3H":
|
||||
recentlyActive = &c.RecentlyActive
|
||||
default:
|
||||
recentlyActive = nil
|
||||
params := &cwClient.ListMetricsInput{
|
||||
Dimensions: []types.DimensionFilter{},
|
||||
NextToken: token,
|
||||
MetricName: nil,
|
||||
}
|
||||
if c.RecentlyActive == "PT3H" {
|
||||
params.RecentlyActive = types.RecentlyActivePt3h
|
||||
}
|
||||
|
||||
for _, namespace := range c.Namespaces {
|
||||
|
||||
params = &cwClient.ListMetricsInput{
|
||||
Dimensions: []*cwClient.DimensionFilter{},
|
||||
NextToken: token,
|
||||
MetricName: nil,
|
||||
RecentlyActive: recentlyActive,
|
||||
Namespace: aws.String(namespace),
|
||||
}
|
||||
|
||||
params.Namespace = aws.String(namespace)
|
||||
for {
|
||||
resp, err := c.client.ListMetrics(params)
|
||||
resp, err := c.client.ListMetrics(context.Background(), params)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list metrics with params per namespace: %v", err)
|
||||
}
|
||||
|
|
@ -457,75 +459,75 @@ func (c *CloudWatch) updateWindow(relativeTo time.Time) {
|
|||
}
|
||||
|
||||
// getDataQueries gets all of the possible queries so we can maximize the request payload.
|
||||
func (c *CloudWatch) getDataQueries(filteredMetrics []filteredMetric) map[string][]*cwClient.MetricDataQuery {
|
||||
func (c *CloudWatch) getDataQueries(filteredMetrics []filteredMetric) map[string][]types.MetricDataQuery {
|
||||
if c.metricCache != nil && c.metricCache.queries != nil && c.metricCache.isValid() {
|
||||
return c.metricCache.queries
|
||||
}
|
||||
|
||||
c.queryDimensions = map[string]*map[string]string{}
|
||||
|
||||
dataQueries := map[string][]*cwClient.MetricDataQuery{}
|
||||
dataQueries := map[string][]types.MetricDataQuery{}
|
||||
for i, filtered := range filteredMetrics {
|
||||
for j, metric := range filtered.metrics {
|
||||
id := strconv.Itoa(j) + "_" + strconv.Itoa(i)
|
||||
dimension := ctod(metric.Dimensions)
|
||||
if filtered.statFilter.Match("average") {
|
||||
c.queryDimensions["average_"+id] = dimension
|
||||
dataQueries[*metric.Namespace] = append(dataQueries[*metric.Namespace], &cwClient.MetricDataQuery{
|
||||
dataQueries[*metric.Namespace] = append(dataQueries[*metric.Namespace], types.MetricDataQuery{
|
||||
Id: aws.String("average_" + id),
|
||||
Label: aws.String(snakeCase(*metric.MetricName + "_average")),
|
||||
MetricStat: &cwClient.MetricStat{
|
||||
Metric: metric,
|
||||
Period: aws.Int64(int64(time.Duration(c.Period).Seconds())),
|
||||
Stat: aws.String(cwClient.StatisticAverage),
|
||||
MetricStat: &types.MetricStat{
|
||||
Metric: &metric,
|
||||
Period: aws.Int32(int32(time.Duration(c.Period).Seconds())),
|
||||
Stat: aws.String(StatisticAverage),
|
||||
},
|
||||
})
|
||||
}
|
||||
if filtered.statFilter.Match("maximum") {
|
||||
c.queryDimensions["maximum_"+id] = dimension
|
||||
dataQueries[*metric.Namespace] = append(dataQueries[*metric.Namespace], &cwClient.MetricDataQuery{
|
||||
dataQueries[*metric.Namespace] = append(dataQueries[*metric.Namespace], types.MetricDataQuery{
|
||||
Id: aws.String("maximum_" + id),
|
||||
Label: aws.String(snakeCase(*metric.MetricName + "_maximum")),
|
||||
MetricStat: &cwClient.MetricStat{
|
||||
Metric: metric,
|
||||
Period: aws.Int64(int64(time.Duration(c.Period).Seconds())),
|
||||
Stat: aws.String(cwClient.StatisticMaximum),
|
||||
MetricStat: &types.MetricStat{
|
||||
Metric: &metric,
|
||||
Period: aws.Int32(int32(time.Duration(c.Period).Seconds())),
|
||||
Stat: aws.String(StatisticMaximum),
|
||||
},
|
||||
})
|
||||
}
|
||||
if filtered.statFilter.Match("minimum") {
|
||||
c.queryDimensions["minimum_"+id] = dimension
|
||||
dataQueries[*metric.Namespace] = append(dataQueries[*metric.Namespace], &cwClient.MetricDataQuery{
|
||||
dataQueries[*metric.Namespace] = append(dataQueries[*metric.Namespace], types.MetricDataQuery{
|
||||
Id: aws.String("minimum_" + id),
|
||||
Label: aws.String(snakeCase(*metric.MetricName + "_minimum")),
|
||||
MetricStat: &cwClient.MetricStat{
|
||||
Metric: metric,
|
||||
Period: aws.Int64(int64(time.Duration(c.Period).Seconds())),
|
||||
Stat: aws.String(cwClient.StatisticMinimum),
|
||||
MetricStat: &types.MetricStat{
|
||||
Metric: &metric,
|
||||
Period: aws.Int32(int32(time.Duration(c.Period).Seconds())),
|
||||
Stat: aws.String(StatisticMinimum),
|
||||
},
|
||||
})
|
||||
}
|
||||
if filtered.statFilter.Match("sum") {
|
||||
c.queryDimensions["sum_"+id] = dimension
|
||||
dataQueries[*metric.Namespace] = append(dataQueries[*metric.Namespace], &cwClient.MetricDataQuery{
|
||||
dataQueries[*metric.Namespace] = append(dataQueries[*metric.Namespace], types.MetricDataQuery{
|
||||
Id: aws.String("sum_" + id),
|
||||
Label: aws.String(snakeCase(*metric.MetricName + "_sum")),
|
||||
MetricStat: &cwClient.MetricStat{
|
||||
Metric: metric,
|
||||
Period: aws.Int64(int64(time.Duration(c.Period).Seconds())),
|
||||
Stat: aws.String(cwClient.StatisticSum),
|
||||
MetricStat: &types.MetricStat{
|
||||
Metric: &metric,
|
||||
Period: aws.Int32(int32(time.Duration(c.Period).Seconds())),
|
||||
Stat: aws.String(StatisticSum),
|
||||
},
|
||||
})
|
||||
}
|
||||
if filtered.statFilter.Match("sample_count") {
|
||||
c.queryDimensions["sample_count_"+id] = dimension
|
||||
dataQueries[*metric.Namespace] = append(dataQueries[*metric.Namespace], &cwClient.MetricDataQuery{
|
||||
dataQueries[*metric.Namespace] = append(dataQueries[*metric.Namespace], types.MetricDataQuery{
|
||||
Id: aws.String("sample_count_" + id),
|
||||
Label: aws.String(snakeCase(*metric.MetricName + "_sample_count")),
|
||||
MetricStat: &cwClient.MetricStat{
|
||||
Metric: metric,
|
||||
Period: aws.Int64(int64(time.Duration(c.Period).Seconds())),
|
||||
Stat: aws.String(cwClient.StatisticSampleCount),
|
||||
MetricStat: &types.MetricStat{
|
||||
Metric: &metric,
|
||||
Period: aws.Int32(int32(time.Duration(c.Period).Seconds())),
|
||||
Stat: aws.String(StatisticSampleCount),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
|
@ -553,11 +555,11 @@ func (c *CloudWatch) getDataQueries(filteredMetrics []filteredMetric) map[string
|
|||
// gatherMetrics gets metric data from Cloudwatch.
|
||||
func (c *CloudWatch) gatherMetrics(
|
||||
params *cwClient.GetMetricDataInput,
|
||||
) ([]*cwClient.MetricDataResult, error) {
|
||||
results := []*cwClient.MetricDataResult{}
|
||||
) ([]types.MetricDataResult, error) {
|
||||
results := []types.MetricDataResult{}
|
||||
|
||||
for {
|
||||
resp, err := c.client.GetMetricData(params)
|
||||
resp, err := c.client.GetMetricData(context.Background(), params)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get metric data: %v", err)
|
||||
}
|
||||
|
|
@ -574,7 +576,7 @@ func (c *CloudWatch) gatherMetrics(
|
|||
|
||||
func (c *CloudWatch) aggregateMetrics(
|
||||
acc telegraf.Accumulator,
|
||||
metricDataResults map[string][]*cwClient.MetricDataResult,
|
||||
metricDataResults map[string][]types.MetricDataResult,
|
||||
) error {
|
||||
var (
|
||||
grouper = internalMetric.NewSeriesGrouper()
|
||||
|
|
@ -592,7 +594,7 @@ func (c *CloudWatch) aggregateMetrics(
|
|||
tags["region"] = c.Region
|
||||
|
||||
for i := range result.Values {
|
||||
if err := grouper.Add(namespace, tags, *result.Timestamps[i], *result.Label, *result.Values[i]); err != nil {
|
||||
if err := grouper.Add(namespace, tags, result.Timestamps[i], *result.Label, result.Values[i]); err != nil {
|
||||
acc.AddError(err)
|
||||
}
|
||||
}
|
||||
|
|
@ -635,7 +637,7 @@ func snakeCase(s string) string {
|
|||
}
|
||||
|
||||
// ctod converts cloudwatch dimensions to regular dimensions.
|
||||
func ctod(cDimensions []*cwClient.Dimension) *map[string]string {
|
||||
func ctod(cDimensions []types.Dimension) *map[string]string {
|
||||
dimensions := map[string]string{}
|
||||
for i := range cDimensions {
|
||||
dimensions[snakeCase(*cDimensions[i].Name)] = *cDimensions[i].Value
|
||||
|
|
@ -643,7 +645,7 @@ func ctod(cDimensions []*cwClient.Dimension) *map[string]string {
|
|||
return &dimensions
|
||||
}
|
||||
|
||||
func (c *CloudWatch) getDataInputs(dataQueries []*cwClient.MetricDataQuery) *cwClient.GetMetricDataInput {
|
||||
func (c *CloudWatch) getDataInputs(dataQueries []types.MetricDataQuery) *cwClient.GetMetricDataInput {
|
||||
return &cwClient.GetMetricDataInput{
|
||||
StartTime: aws.Time(c.windowStart),
|
||||
EndTime: aws.Time(c.windowEnd),
|
||||
|
|
@ -665,7 +667,7 @@ func hasWildcard(dimensions []*Dimension) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func isSelected(name string, metric *cwClient.Metric, dimensions []*Dimension) bool {
|
||||
func isSelected(name string, metric types.Metric, dimensions []*Dimension) bool {
|
||||
if name != *metric.MetricName {
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
package cloudwatch
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
cwClient "github.com/aws/aws-sdk-go/service/cloudwatch"
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
cwClient "github.com/aws/aws-sdk-go-v2/service/cloudwatch"
|
||||
"github.com/aws/aws-sdk-go-v2/service/cloudwatch/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/influxdata/telegraf/config"
|
||||
|
|
@ -18,13 +20,13 @@ import (
|
|||
|
||||
type mockGatherCloudWatchClient struct{}
|
||||
|
||||
func (m *mockGatherCloudWatchClient) ListMetrics(params *cwClient.ListMetricsInput) (*cwClient.ListMetricsOutput, error) {
|
||||
func (m *mockGatherCloudWatchClient) ListMetrics(_ context.Context, params *cwClient.ListMetricsInput, _ ...func(*cwClient.Options)) (*cwClient.ListMetricsOutput, error) {
|
||||
return &cwClient.ListMetricsOutput{
|
||||
Metrics: []*cwClient.Metric{
|
||||
Metrics: []types.Metric{
|
||||
{
|
||||
Namespace: params.Namespace,
|
||||
MetricName: aws.String("Latency"),
|
||||
Dimensions: []*cwClient.Dimension{
|
||||
Dimensions: []types.Dimension{
|
||||
{
|
||||
Name: aws.String("LoadBalancerName"),
|
||||
Value: aws.String("p-example"),
|
||||
|
|
@ -35,63 +37,53 @@ func (m *mockGatherCloudWatchClient) ListMetrics(params *cwClient.ListMetricsInp
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (m *mockGatherCloudWatchClient) GetMetricData(params *cwClient.GetMetricDataInput) (*cwClient.GetMetricDataOutput, error) {
|
||||
func (m *mockGatherCloudWatchClient) GetMetricData(_ context.Context, params *cwClient.GetMetricDataInput, _ ...func(*cwClient.Options)) (*cwClient.GetMetricDataOutput, error) {
|
||||
return &cwClient.GetMetricDataOutput{
|
||||
MetricDataResults: []*cwClient.MetricDataResult{
|
||||
MetricDataResults: []types.MetricDataResult{
|
||||
{
|
||||
Id: aws.String("minimum_0_0"),
|
||||
Label: aws.String("latency_minimum"),
|
||||
StatusCode: aws.String("completed"),
|
||||
Timestamps: []*time.Time{
|
||||
params.EndTime,
|
||||
},
|
||||
Values: []*float64{
|
||||
aws.Float64(0.1),
|
||||
StatusCode: types.StatusCodeComplete,
|
||||
Timestamps: []time.Time{
|
||||
*params.EndTime,
|
||||
},
|
||||
Values: []float64{0.1},
|
||||
},
|
||||
{
|
||||
Id: aws.String("maximum_0_0"),
|
||||
Label: aws.String("latency_maximum"),
|
||||
StatusCode: aws.String("completed"),
|
||||
Timestamps: []*time.Time{
|
||||
params.EndTime,
|
||||
},
|
||||
Values: []*float64{
|
||||
aws.Float64(0.3),
|
||||
StatusCode: types.StatusCodeComplete,
|
||||
Timestamps: []time.Time{
|
||||
*params.EndTime,
|
||||
},
|
||||
Values: []float64{0.3},
|
||||
},
|
||||
{
|
||||
Id: aws.String("average_0_0"),
|
||||
Label: aws.String("latency_average"),
|
||||
StatusCode: aws.String("completed"),
|
||||
Timestamps: []*time.Time{
|
||||
params.EndTime,
|
||||
},
|
||||
Values: []*float64{
|
||||
aws.Float64(0.2),
|
||||
StatusCode: types.StatusCodeComplete,
|
||||
Timestamps: []time.Time{
|
||||
*params.EndTime,
|
||||
},
|
||||
Values: []float64{0.2},
|
||||
},
|
||||
{
|
||||
Id: aws.String("sum_0_0"),
|
||||
Label: aws.String("latency_sum"),
|
||||
StatusCode: aws.String("completed"),
|
||||
Timestamps: []*time.Time{
|
||||
params.EndTime,
|
||||
},
|
||||
Values: []*float64{
|
||||
aws.Float64(123),
|
||||
StatusCode: types.StatusCodeComplete,
|
||||
Timestamps: []time.Time{
|
||||
*params.EndTime,
|
||||
},
|
||||
Values: []float64{123},
|
||||
},
|
||||
{
|
||||
Id: aws.String("sample_count_0_0"),
|
||||
Label: aws.String("latency_sample_count"),
|
||||
StatusCode: aws.String("completed"),
|
||||
Timestamps: []*time.Time{
|
||||
params.EndTime,
|
||||
},
|
||||
Values: []*float64{
|
||||
aws.Float64(100),
|
||||
StatusCode: types.StatusCodeComplete,
|
||||
Timestamps: []time.Time{
|
||||
*params.EndTime,
|
||||
},
|
||||
Values: []float64{100},
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
|
|
@ -158,8 +150,8 @@ func TestGather_MultipleNamespaces(t *testing.T) {
|
|||
|
||||
type mockSelectMetricsCloudWatchClient struct{}
|
||||
|
||||
func (m *mockSelectMetricsCloudWatchClient) ListMetrics(_ *cwClient.ListMetricsInput) (*cwClient.ListMetricsOutput, error) {
|
||||
metrics := []*cwClient.Metric{}
|
||||
func (m *mockSelectMetricsCloudWatchClient) ListMetrics(_ context.Context, params *cwClient.ListMetricsInput, _ ...func(*cwClient.Options)) (*cwClient.ListMetricsOutput, error) {
|
||||
metrics := []types.Metric{}
|
||||
// 4 metrics are available
|
||||
metricNames := []string{"Latency", "RequestCount", "HealthyHostCount", "UnHealthyHostCount"}
|
||||
// for 3 ELBs
|
||||
|
|
@ -169,10 +161,10 @@ func (m *mockSelectMetricsCloudWatchClient) ListMetrics(_ *cwClient.ListMetricsI
|
|||
for _, m := range metricNames {
|
||||
for _, lb := range loadBalancers {
|
||||
// For each metric/ELB pair, we get an aggregate value across all AZs.
|
||||
metrics = append(metrics, &cwClient.Metric{
|
||||
metrics = append(metrics, types.Metric{
|
||||
Namespace: aws.String("AWS/ELB"),
|
||||
MetricName: aws.String(m),
|
||||
Dimensions: []*cwClient.Dimension{
|
||||
Dimensions: []types.Dimension{
|
||||
{
|
||||
Name: aws.String("LoadBalancerName"),
|
||||
Value: aws.String(lb),
|
||||
|
|
@ -181,10 +173,10 @@ func (m *mockSelectMetricsCloudWatchClient) ListMetrics(_ *cwClient.ListMetricsI
|
|||
})
|
||||
for _, az := range availabilityZones {
|
||||
// We get a metric for each metric/ELB/AZ triplet.
|
||||
metrics = append(metrics, &cwClient.Metric{
|
||||
metrics = append(metrics, types.Metric{
|
||||
Namespace: aws.String("AWS/ELB"),
|
||||
MetricName: aws.String(m),
|
||||
Dimensions: []*cwClient.Dimension{
|
||||
Dimensions: []types.Dimension{
|
||||
{
|
||||
Name: aws.String("LoadBalancerName"),
|
||||
Value: aws.String(lb),
|
||||
|
|
@ -205,7 +197,7 @@ func (m *mockSelectMetricsCloudWatchClient) ListMetrics(_ *cwClient.ListMetricsI
|
|||
return result, nil
|
||||
}
|
||||
|
||||
func (m *mockSelectMetricsCloudWatchClient) GetMetricData(_ *cwClient.GetMetricDataInput) (*cwClient.GetMetricDataOutput, error) {
|
||||
func (m *mockSelectMetricsCloudWatchClient) GetMetricData(_ context.Context, params *cwClient.GetMetricDataInput, _ ...func(*cwClient.Options)) (*cwClient.GetMetricDataOutput, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
|
@ -246,16 +238,16 @@ func TestSelectMetrics(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGenerateStatisticsInputParams(t *testing.T) {
|
||||
d := &cwClient.Dimension{
|
||||
d := types.Dimension{
|
||||
Name: aws.String("LoadBalancerName"),
|
||||
Value: aws.String("p-example"),
|
||||
}
|
||||
|
||||
namespace := "AWS/ELB"
|
||||
m := &cwClient.Metric{
|
||||
m := types.Metric{
|
||||
MetricName: aws.String("Latency"),
|
||||
Dimensions: []*cwClient.Dimension{d},
|
||||
Namespace: &namespace,
|
||||
Dimensions: []types.Dimension{d},
|
||||
Namespace: aws.String(namespace),
|
||||
}
|
||||
|
||||
duration, _ := time.ParseDuration("1m")
|
||||
|
|
@ -274,7 +266,7 @@ func TestGenerateStatisticsInputParams(t *testing.T) {
|
|||
c.updateWindow(now)
|
||||
|
||||
statFilter, _ := filter.NewIncludeExcludeFilter(nil, nil)
|
||||
queries := c.getDataQueries([]filteredMetric{{metrics: []*cwClient.Metric{m}, statFilter: statFilter}})
|
||||
queries := c.getDataQueries([]filteredMetric{{metrics: []types.Metric{m}, statFilter: statFilter}})
|
||||
params := c.getDataInputs(queries[namespace])
|
||||
|
||||
require.EqualValues(t, *params.EndTime, now.Add(-time.Duration(c.Delay)))
|
||||
|
|
@ -285,16 +277,16 @@ func TestGenerateStatisticsInputParams(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGenerateStatisticsInputParamsFiltered(t *testing.T) {
|
||||
d := &cwClient.Dimension{
|
||||
d := types.Dimension{
|
||||
Name: aws.String("LoadBalancerName"),
|
||||
Value: aws.String("p-example"),
|
||||
}
|
||||
|
||||
namespace := "AWS/ELB"
|
||||
m := &cwClient.Metric{
|
||||
m := types.Metric{
|
||||
MetricName: aws.String("Latency"),
|
||||
Dimensions: []*cwClient.Dimension{d},
|
||||
Namespace: &namespace,
|
||||
Dimensions: []types.Dimension{d},
|
||||
Namespace: aws.String(namespace),
|
||||
}
|
||||
|
||||
duration, _ := time.ParseDuration("1m")
|
||||
|
|
@ -313,7 +305,7 @@ func TestGenerateStatisticsInputParamsFiltered(t *testing.T) {
|
|||
c.updateWindow(now)
|
||||
|
||||
statFilter, _ := filter.NewIncludeExcludeFilter([]string{"average", "sample_count"}, nil)
|
||||
queries := c.getDataQueries([]filteredMetric{{metrics: []*cwClient.Metric{m}, statFilter: statFilter}})
|
||||
queries := c.getDataQueries([]filteredMetric{{metrics: []types.Metric{m}, statFilter: statFilter}})
|
||||
params := c.getDataInputs(queries[namespace])
|
||||
|
||||
require.EqualValues(t, *params.EndTime, now.Add(-time.Duration(c.Delay)))
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/service/dynamodb"
|
||||
"github.com/aws/aws-sdk-go/service/kinesis"
|
||||
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
|
||||
"github.com/aws/aws-sdk-go-v2/service/kinesis"
|
||||
consumer "github.com/harlow/kinesis-consumer"
|
||||
"github.com/harlow/kinesis-consumer/checkpoint/ddb"
|
||||
"github.com/harlow/kinesis-consumer/store/ddb"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
internalaws "github.com/influxdata/telegraf/config/aws"
|
||||
|
|
@ -44,7 +44,7 @@ type (
|
|||
acc telegraf.TrackingAccumulator
|
||||
sem chan struct{}
|
||||
|
||||
checkpoint consumer.Checkpoint
|
||||
checkpoint consumer.Store
|
||||
checkpoints map[string]checkpoint
|
||||
records map[telegraf.TrackingID]string
|
||||
checkpointTex sync.Mutex
|
||||
|
|
@ -153,31 +153,19 @@ func (k *KinesisConsumer) SetParser(parser parsers.Parser) {
|
|||
}
|
||||
|
||||
func (k *KinesisConsumer) connect(ac telegraf.Accumulator) error {
|
||||
p, err := k.CredentialConfig.Credentials()
|
||||
cfg, err := k.CredentialConfig.Credentials()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client := kinesis.New(p)
|
||||
client := kinesis.NewFromConfig(cfg)
|
||||
|
||||
k.checkpoint = &noopCheckpoint{}
|
||||
k.checkpoint = &noopStore{}
|
||||
if k.DynamoDB != nil {
|
||||
p, err := (&internalaws.CredentialConfig{
|
||||
Region: k.Region,
|
||||
AccessKey: k.AccessKey,
|
||||
SecretKey: k.SecretKey,
|
||||
RoleARN: k.RoleARN,
|
||||
Profile: k.Profile,
|
||||
Filename: k.Filename,
|
||||
Token: k.Token,
|
||||
EndpointURL: k.EndpointURL,
|
||||
}).Credentials()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var err error
|
||||
k.checkpoint, err = ddb.New(
|
||||
k.DynamoDB.AppName,
|
||||
k.DynamoDB.TableName,
|
||||
ddb.WithDynamoClient(dynamodb.New(p)),
|
||||
ddb.WithDynamoClient(dynamodb.NewFromConfig(cfg)),
|
||||
ddb.WithMaxInterval(time.Second*10),
|
||||
)
|
||||
if err != nil {
|
||||
|
|
@ -189,7 +177,7 @@ func (k *KinesisConsumer) connect(ac telegraf.Accumulator) error {
|
|||
k.StreamName,
|
||||
consumer.WithClient(client),
|
||||
consumer.WithShardIteratorType(k.ShardIteratorType),
|
||||
consumer.WithCheckpoint(k),
|
||||
consumer.WithStore(k),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -214,10 +202,10 @@ func (k *KinesisConsumer) connect(ac telegraf.Accumulator) error {
|
|||
k.wg.Add(1)
|
||||
go func() {
|
||||
defer k.wg.Done()
|
||||
err := k.cons.Scan(ctx, func(r *consumer.Record) consumer.ScanStatus {
|
||||
err := k.cons.Scan(ctx, func(r *consumer.Record) error {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return consumer.ScanStatus{Error: ctx.Err()}
|
||||
return ctx.Err()
|
||||
case k.sem <- struct{}{}:
|
||||
break
|
||||
}
|
||||
|
|
@ -227,7 +215,7 @@ func (k *KinesisConsumer) connect(ac telegraf.Accumulator) error {
|
|||
k.Log.Errorf("Scan parser error: %s", err.Error())
|
||||
}
|
||||
|
||||
return consumer.ScanStatus{}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
k.cancel()
|
||||
|
|
@ -298,7 +286,7 @@ func (k *KinesisConsumer) onDelivery(ctx context.Context) {
|
|||
}
|
||||
|
||||
k.lastSeqNum = strToBint(sequenceNum)
|
||||
if err := k.checkpoint.Set(chk.streamName, chk.shardID, sequenceNum); err != nil {
|
||||
if err := k.checkpoint.SetCheckpoint(chk.streamName, chk.shardID, sequenceNum); err != nil {
|
||||
k.Log.Debug("Setting checkpoint failed: %v", err)
|
||||
}
|
||||
} else {
|
||||
|
|
@ -332,13 +320,13 @@ func (k *KinesisConsumer) Gather(acc telegraf.Accumulator) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Get wraps the checkpoint's Get function (called by consumer library)
|
||||
func (k *KinesisConsumer) Get(streamName, shardID string) (string, error) {
|
||||
return k.checkpoint.Get(streamName, shardID)
|
||||
// Get wraps the checkpoint's GetCheckpoint function (called by consumer library)
|
||||
func (k *KinesisConsumer) GetCheckpoint(streamName, shardID string) (string, error) {
|
||||
return k.checkpoint.GetCheckpoint(streamName, shardID)
|
||||
}
|
||||
|
||||
// Set wraps the checkpoint's Set function (called by consumer library)
|
||||
func (k *KinesisConsumer) Set(streamName, shardID, sequenceNumber string) error {
|
||||
// Set wraps the checkpoint's SetCheckpoint function (called by consumer library)
|
||||
func (k *KinesisConsumer) SetCheckpoint(streamName, shardID, sequenceNumber string) error {
|
||||
if sequenceNumber == "" {
|
||||
return fmt.Errorf("sequence number should not be empty")
|
||||
}
|
||||
|
|
@ -390,10 +378,10 @@ func (k *KinesisConsumer) Init() error {
|
|||
return k.configureProcessContentEncodingFunc()
|
||||
}
|
||||
|
||||
type noopCheckpoint struct{}
|
||||
type noopStore struct{}
|
||||
|
||||
func (n noopCheckpoint) Set(string, string, string) error { return nil }
|
||||
func (n noopCheckpoint) Get(string, string) (string, error) { return "", nil }
|
||||
func (n noopStore) SetCheckpoint(string, string, string) error { return nil }
|
||||
func (n noopStore) GetCheckpoint(string, string) (string, error) { return "", nil }
|
||||
|
||||
func init() {
|
||||
negOne, _ = new(big.Int).SetString("-1", 10)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ package kinesis_consumer
|
|||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/aws/aws-sdk-go-v2/service/kinesis/types"
|
||||
consumer "github.com/harlow/kinesis-consumer"
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/plugins/parsers"
|
||||
|
|
@ -53,7 +54,12 @@ func TestKinesisConsumer_onMessage(t *testing.T) {
|
|||
records: make(map[telegraf.TrackingID]string),
|
||||
},
|
||||
args: args{
|
||||
r: &consumer.Record{Data: notZippedBytes, SequenceNumber: aws.String("anything")},
|
||||
r: &consumer.Record{
|
||||
Record: types.Record{
|
||||
Data: notZippedBytes,
|
||||
SequenceNumber: aws.String("anything"),
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
expected: expected{
|
||||
|
|
@ -69,7 +75,12 @@ func TestKinesisConsumer_onMessage(t *testing.T) {
|
|||
records: make(map[telegraf.TrackingID]string),
|
||||
},
|
||||
args: args{
|
||||
r: &consumer.Record{Data: notZippedBytes, SequenceNumber: aws.String("anything")},
|
||||
r: &consumer.Record{
|
||||
Record: types.Record{
|
||||
Data: notZippedBytes,
|
||||
SequenceNumber: aws.String("anything"),
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
expected: expected{
|
||||
|
|
@ -85,7 +96,12 @@ func TestKinesisConsumer_onMessage(t *testing.T) {
|
|||
records: make(map[telegraf.TrackingID]string),
|
||||
},
|
||||
args: args{
|
||||
r: &consumer.Record{Data: notZippedBytes, SequenceNumber: aws.String("anything")},
|
||||
r: &consumer.Record{
|
||||
Record: types.Record{
|
||||
Data: notZippedBytes,
|
||||
SequenceNumber: aws.String("anything"),
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
expected: expected{
|
||||
|
|
@ -100,7 +116,12 @@ func TestKinesisConsumer_onMessage(t *testing.T) {
|
|||
records: make(map[telegraf.TrackingID]string),
|
||||
},
|
||||
args: args{
|
||||
r: &consumer.Record{Data: notZippedBytes, SequenceNumber: aws.String("anything")},
|
||||
r: &consumer.Record{
|
||||
Record: types.Record{
|
||||
Data: notZippedBytes,
|
||||
SequenceNumber: aws.String("anything"),
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
expected: expected{
|
||||
|
|
@ -116,7 +137,12 @@ func TestKinesisConsumer_onMessage(t *testing.T) {
|
|||
records: make(map[telegraf.TrackingID]string),
|
||||
},
|
||||
args: args{
|
||||
r: &consumer.Record{Data: gzippedBytes, SequenceNumber: aws.String("anything")},
|
||||
r: &consumer.Record{
|
||||
Record: types.Record{
|
||||
Data: gzippedBytes,
|
||||
SequenceNumber: aws.String("anything"),
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
expected: expected{
|
||||
|
|
@ -132,7 +158,12 @@ func TestKinesisConsumer_onMessage(t *testing.T) {
|
|||
records: make(map[telegraf.TrackingID]string),
|
||||
},
|
||||
args: args{
|
||||
r: &consumer.Record{Data: zlibBytpes, SequenceNumber: aws.String("anything")},
|
||||
r: &consumer.Record{
|
||||
Record: types.Record{
|
||||
Data: zlibBytpes,
|
||||
SequenceNumber: aws.String("anything"),
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
expected: expected{
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
package cloudwatch
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/cloudwatch"
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/aws/aws-sdk-go-v2/service/cloudwatch"
|
||||
"github.com/aws/aws-sdk-go-v2/service/cloudwatch/types"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
internalaws "github.com/influxdata/telegraf/config/aws"
|
||||
|
|
@ -17,7 +19,7 @@ import (
|
|||
type CloudWatch struct {
|
||||
Namespace string `toml:"namespace"` // CloudWatch Metrics Namespace
|
||||
HighResolutionMetrics bool `toml:"high_resolution_metrics"`
|
||||
svc *cloudwatch.CloudWatch
|
||||
svc *cloudwatch.Client
|
||||
|
||||
WriteStatistics bool `toml:"write_statistics"`
|
||||
|
||||
|
|
@ -38,7 +40,7 @@ const (
|
|||
|
||||
type cloudwatchField interface {
|
||||
addValue(sType statisticType, value float64)
|
||||
buildDatum() []*cloudwatch.MetricDatum
|
||||
buildDatum() []types.MetricDatum
|
||||
}
|
||||
|
||||
type statisticField struct {
|
||||
|
|
@ -56,8 +58,8 @@ func (f *statisticField) addValue(sType statisticType, value float64) {
|
|||
}
|
||||
}
|
||||
|
||||
func (f *statisticField) buildDatum() []*cloudwatch.MetricDatum {
|
||||
var datums []*cloudwatch.MetricDatum
|
||||
func (f *statisticField) buildDatum() []types.MetricDatum {
|
||||
var datums []types.MetricDatum
|
||||
|
||||
if f.hasAllFields() {
|
||||
// If we have all required fields, we build datum with StatisticValues
|
||||
|
|
@ -66,24 +68,24 @@ func (f *statisticField) buildDatum() []*cloudwatch.MetricDatum {
|
|||
sum := f.values[statisticTypeSum]
|
||||
count := f.values[statisticTypeCount]
|
||||
|
||||
datum := &cloudwatch.MetricDatum{
|
||||
datum := types.MetricDatum{
|
||||
MetricName: aws.String(strings.Join([]string{f.metricName, f.fieldName}, "_")),
|
||||
Dimensions: BuildDimensions(f.tags),
|
||||
Timestamp: aws.Time(f.timestamp),
|
||||
StatisticValues: &cloudwatch.StatisticSet{
|
||||
StatisticValues: &types.StatisticSet{
|
||||
Minimum: aws.Float64(min),
|
||||
Maximum: aws.Float64(max),
|
||||
Sum: aws.Float64(sum),
|
||||
SampleCount: aws.Float64(count),
|
||||
},
|
||||
StorageResolution: aws.Int64(f.storageResolution),
|
||||
StorageResolution: aws.Int32(int32(f.storageResolution)),
|
||||
}
|
||||
|
||||
datums = append(datums, datum)
|
||||
} else {
|
||||
// If we don't have all required fields, we build each field as independent datum
|
||||
for sType, value := range f.values {
|
||||
datum := &cloudwatch.MetricDatum{
|
||||
datum := types.MetricDatum{
|
||||
Value: aws.Float64(value),
|
||||
Dimensions: BuildDimensions(f.tags),
|
||||
Timestamp: aws.Time(f.timestamp),
|
||||
|
|
@ -134,14 +136,14 @@ func (f *valueField) addValue(sType statisticType, value float64) {
|
|||
}
|
||||
}
|
||||
|
||||
func (f *valueField) buildDatum() []*cloudwatch.MetricDatum {
|
||||
return []*cloudwatch.MetricDatum{
|
||||
func (f *valueField) buildDatum() []types.MetricDatum {
|
||||
return []types.MetricDatum{
|
||||
{
|
||||
MetricName: aws.String(strings.Join([]string{f.metricName, f.fieldName}, "_")),
|
||||
Value: aws.Float64(f.value),
|
||||
Dimensions: BuildDimensions(f.tags),
|
||||
Timestamp: aws.Time(f.timestamp),
|
||||
StorageResolution: aws.Int64(f.storageResolution),
|
||||
StorageResolution: aws.Int32(int32(f.storageResolution)),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -198,11 +200,12 @@ func (c *CloudWatch) Description() string {
|
|||
}
|
||||
|
||||
func (c *CloudWatch) Connect() error {
|
||||
p, err := c.CredentialConfig.Credentials()
|
||||
cfg, err := c.CredentialConfig.Credentials()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.svc = cloudwatch.New(p)
|
||||
|
||||
c.svc = cloudwatch.NewFromConfig(cfg)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -211,7 +214,7 @@ func (c *CloudWatch) Close() error {
|
|||
}
|
||||
|
||||
func (c *CloudWatch) Write(metrics []telegraf.Metric) error {
|
||||
var datums []*cloudwatch.MetricDatum
|
||||
var datums []types.MetricDatum
|
||||
for _, m := range metrics {
|
||||
d := BuildMetricDatum(c.WriteStatistics, c.HighResolutionMetrics, m)
|
||||
datums = append(datums, d...)
|
||||
|
|
@ -229,13 +232,13 @@ func (c *CloudWatch) Write(metrics []telegraf.Metric) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *CloudWatch) WriteToCloudWatch(datums []*cloudwatch.MetricDatum) error {
|
||||
func (c *CloudWatch) WriteToCloudWatch(datums []types.MetricDatum) error {
|
||||
params := &cloudwatch.PutMetricDataInput{
|
||||
MetricData: datums,
|
||||
Namespace: aws.String(c.Namespace),
|
||||
}
|
||||
|
||||
_, err := c.svc.PutMetricData(params)
|
||||
_, err := c.svc.PutMetricData(context.Background(), params)
|
||||
|
||||
if err != nil {
|
||||
c.Log.Errorf("Unable to write to CloudWatch : %+v", err.Error())
|
||||
|
|
@ -246,13 +249,13 @@ func (c *CloudWatch) WriteToCloudWatch(datums []*cloudwatch.MetricDatum) error {
|
|||
|
||||
// Partition the MetricDatums into smaller slices of a max size so that are under the limit
|
||||
// for the AWS API calls.
|
||||
func PartitionDatums(size int, datums []*cloudwatch.MetricDatum) [][]*cloudwatch.MetricDatum {
|
||||
func PartitionDatums(size int, datums []types.MetricDatum) [][]types.MetricDatum {
|
||||
numberOfPartitions := len(datums) / size
|
||||
if len(datums)%size != 0 {
|
||||
numberOfPartitions++
|
||||
}
|
||||
|
||||
partitions := make([][]*cloudwatch.MetricDatum, numberOfPartitions)
|
||||
partitions := make([][]types.MetricDatum, numberOfPartitions)
|
||||
|
||||
for i := 0; i < numberOfPartitions; i++ {
|
||||
start := size * i
|
||||
|
|
@ -270,7 +273,7 @@ func PartitionDatums(size int, datums []*cloudwatch.MetricDatum) [][]*cloudwatch
|
|||
// Make a MetricDatum from telegraf.Metric. It would check if all required fields of
|
||||
// cloudwatch.StatisticSet are available. If so, it would build MetricDatum from statistic values.
|
||||
// Otherwise, fields would still been built independently.
|
||||
func BuildMetricDatum(buildStatistic bool, highResolutionMetrics bool, point telegraf.Metric) []*cloudwatch.MetricDatum {
|
||||
func BuildMetricDatum(buildStatistic bool, highResolutionMetrics bool, point telegraf.Metric) []types.MetricDatum {
|
||||
fields := make(map[string]cloudwatchField)
|
||||
tags := point.Tags()
|
||||
storageResolution := int64(60)
|
||||
|
|
@ -320,7 +323,7 @@ func BuildMetricDatum(buildStatistic bool, highResolutionMetrics bool, point tel
|
|||
}
|
||||
}
|
||||
|
||||
var datums []*cloudwatch.MetricDatum
|
||||
var datums []types.MetricDatum
|
||||
for _, f := range fields {
|
||||
d := f.buildDatum()
|
||||
datums = append(datums, d...)
|
||||
|
|
@ -332,13 +335,13 @@ func BuildMetricDatum(buildStatistic bool, highResolutionMetrics bool, point tel
|
|||
// Make a list of Dimensions by using a Point's tags. CloudWatch supports up to
|
||||
// 10 dimensions per metric so we only keep up to the first 10 alphabetically.
|
||||
// This always includes the "host" tag if it exists.
|
||||
func BuildDimensions(mTags map[string]string) []*cloudwatch.Dimension {
|
||||
func BuildDimensions(mTags map[string]string) []types.Dimension {
|
||||
const MaxDimensions = 10
|
||||
dimensions := make([]*cloudwatch.Dimension, 0, MaxDimensions)
|
||||
dimensions := make([]types.Dimension, 0, MaxDimensions)
|
||||
|
||||
// This is pretty ugly but we always want to include the "host" tag if it exists.
|
||||
if host, ok := mTags["host"]; ok {
|
||||
dimensions = append(dimensions, &cloudwatch.Dimension{
|
||||
dimensions = append(dimensions, types.Dimension{
|
||||
Name: aws.String("host"),
|
||||
Value: aws.String(host),
|
||||
})
|
||||
|
|
@ -362,7 +365,7 @@ func BuildDimensions(mTags map[string]string) []*cloudwatch.Dimension {
|
|||
continue
|
||||
}
|
||||
|
||||
dimensions = append(dimensions, &cloudwatch.Dimension{
|
||||
dimensions = append(dimensions, types.Dimension{
|
||||
Name: aws.String(k),
|
||||
Value: aws.String(mTags[k]),
|
||||
})
|
||||
|
|
|
|||
|
|
@ -2,14 +2,13 @@ package cloudwatch
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/aws/aws-sdk-go-v2/service/cloudwatch/types"
|
||||
"math"
|
||||
"sort"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/cloudwatch"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/metric"
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
|
|
@ -117,8 +116,8 @@ func TestBuildMetricDatums(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestMetricDatumResolution(t *testing.T) {
|
||||
const expectedStandardResolutionValue = int64(60)
|
||||
const expectedHighResolutionValue = int64(1)
|
||||
const expectedStandardResolutionValue = int32(60)
|
||||
const expectedHighResolutionValue = int32(1)
|
||||
|
||||
assert := assert.New(t)
|
||||
|
||||
|
|
@ -153,19 +152,19 @@ func TestBuildMetricDatums_SkipEmptyTags(t *testing.T) {
|
|||
func TestPartitionDatums(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
testDatum := cloudwatch.MetricDatum{
|
||||
testDatum := types.MetricDatum{
|
||||
MetricName: aws.String("Foo"),
|
||||
Value: aws.Float64(1),
|
||||
}
|
||||
|
||||
zeroDatum := []*cloudwatch.MetricDatum{}
|
||||
oneDatum := []*cloudwatch.MetricDatum{&testDatum}
|
||||
twoDatum := []*cloudwatch.MetricDatum{&testDatum, &testDatum}
|
||||
threeDatum := []*cloudwatch.MetricDatum{&testDatum, &testDatum, &testDatum}
|
||||
zeroDatum := []types.MetricDatum{}
|
||||
oneDatum := []types.MetricDatum{testDatum}
|
||||
twoDatum := []types.MetricDatum{testDatum, testDatum}
|
||||
threeDatum := []types.MetricDatum{testDatum, testDatum, testDatum}
|
||||
|
||||
assert.Equal([][]*cloudwatch.MetricDatum{}, PartitionDatums(2, zeroDatum))
|
||||
assert.Equal([][]*cloudwatch.MetricDatum{oneDatum}, PartitionDatums(2, oneDatum))
|
||||
assert.Equal([][]*cloudwatch.MetricDatum{oneDatum}, PartitionDatums(2, oneDatum))
|
||||
assert.Equal([][]*cloudwatch.MetricDatum{twoDatum}, PartitionDatums(2, twoDatum))
|
||||
assert.Equal([][]*cloudwatch.MetricDatum{twoDatum, oneDatum}, PartitionDatums(2, threeDatum))
|
||||
assert.Equal([][]types.MetricDatum{}, PartitionDatums(2, zeroDatum))
|
||||
assert.Equal([][]types.MetricDatum{oneDatum}, PartitionDatums(2, oneDatum))
|
||||
assert.Equal([][]types.MetricDatum{oneDatum}, PartitionDatums(2, oneDatum))
|
||||
assert.Equal([][]types.MetricDatum{twoDatum}, PartitionDatums(2, twoDatum))
|
||||
assert.Equal([][]types.MetricDatum{twoDatum, oneDatum}, PartitionDatums(2, threeDatum))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,21 @@
|
|||
package cloudwatch_logs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/service/cloudwatchlogs"
|
||||
"github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs"
|
||||
"github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs/types"
|
||||
"github.com/influxdata/telegraf"
|
||||
internalaws "github.com/influxdata/telegraf/config/aws"
|
||||
"github.com/influxdata/telegraf/plugins/outputs"
|
||||
)
|
||||
|
||||
type messageBatch struct {
|
||||
logEvents []*cloudwatchlogs.InputLogEvent
|
||||
logEvents []types.InputLogEvent
|
||||
messageCount int
|
||||
}
|
||||
type logStreamContainer struct {
|
||||
|
|
@ -25,16 +27,16 @@ type logStreamContainer struct {
|
|||
|
||||
//Cloudwatch Logs service interface
|
||||
type cloudWatchLogs interface {
|
||||
DescribeLogGroups(*cloudwatchlogs.DescribeLogGroupsInput) (*cloudwatchlogs.DescribeLogGroupsOutput, error)
|
||||
DescribeLogStreams(*cloudwatchlogs.DescribeLogStreamsInput) (*cloudwatchlogs.DescribeLogStreamsOutput, error)
|
||||
CreateLogStream(*cloudwatchlogs.CreateLogStreamInput) (*cloudwatchlogs.CreateLogStreamOutput, error)
|
||||
PutLogEvents(*cloudwatchlogs.PutLogEventsInput) (*cloudwatchlogs.PutLogEventsOutput, error)
|
||||
DescribeLogGroups(context.Context, *cloudwatchlogs.DescribeLogGroupsInput, ...func(options *cloudwatchlogs.Options)) (*cloudwatchlogs.DescribeLogGroupsOutput, error)
|
||||
DescribeLogStreams(context.Context, *cloudwatchlogs.DescribeLogStreamsInput, ...func(options *cloudwatchlogs.Options)) (*cloudwatchlogs.DescribeLogStreamsOutput, error)
|
||||
CreateLogStream(context.Context, *cloudwatchlogs.CreateLogStreamInput, ...func(options *cloudwatchlogs.Options)) (*cloudwatchlogs.CreateLogStreamOutput, error)
|
||||
PutLogEvents(context.Context, *cloudwatchlogs.PutLogEventsInput, ...func(options *cloudwatchlogs.Options)) (*cloudwatchlogs.PutLogEventsOutput, error)
|
||||
}
|
||||
|
||||
// CloudWatchLogs plugin object definition
|
||||
type CloudWatchLogs struct {
|
||||
LogGroup string `toml:"log_group"`
|
||||
lg *cloudwatchlogs.LogGroup //log group data
|
||||
LogGroup string `toml:"log_group"`
|
||||
lg *types.LogGroup //log group data
|
||||
|
||||
LogStream string `toml:"log_stream"`
|
||||
lsKey string //log stream source: tag or field
|
||||
|
|
@ -187,19 +189,17 @@ func (c *CloudWatchLogs) Connect() error {
|
|||
var logGroupsOutput = &cloudwatchlogs.DescribeLogGroupsOutput{NextToken: &dummyToken}
|
||||
var err error
|
||||
|
||||
p, err := c.CredentialConfig.Credentials()
|
||||
cfg, err := c.CredentialConfig.Credentials()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.svc = cloudwatchlogs.New(p)
|
||||
if c.svc == nil {
|
||||
return fmt.Errorf("can't create cloudwatch logs service endpoint")
|
||||
}
|
||||
c.svc = cloudwatchlogs.NewFromConfig(cfg)
|
||||
|
||||
//Find log group with name 'c.LogGroup'
|
||||
if c.lg == nil { //In case connection is not retried, first time
|
||||
for logGroupsOutput.NextToken != nil {
|
||||
logGroupsOutput, err = c.svc.DescribeLogGroups(
|
||||
context.Background(),
|
||||
&cloudwatchlogs.DescribeLogGroupsInput{
|
||||
LogGroupNamePrefix: &c.LogGroup,
|
||||
NextToken: queryToken})
|
||||
|
|
@ -212,7 +212,7 @@ func (c *CloudWatchLogs) Connect() error {
|
|||
for _, logGroup := range logGroupsOutput.LogGroups {
|
||||
if *(logGroup.LogGroupName) == c.LogGroup {
|
||||
c.Log.Debugf("Found log group %q", c.LogGroup)
|
||||
c.lg = logGroup
|
||||
c.lg = &logGroup //nolint:revive
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -325,7 +325,7 @@ func (c *CloudWatchLogs) Write(metrics []telegraf.Metric) error {
|
|||
lsContainer = val
|
||||
} else {
|
||||
lsContainer.messageBatches[0].messageCount = 0
|
||||
lsContainer.messageBatches[0].logEvents = []*cloudwatchlogs.InputLogEvent{}
|
||||
lsContainer.messageBatches[0].logEvents = []types.InputLogEvent{}
|
||||
c.ls[logStream] = lsContainer
|
||||
}
|
||||
|
||||
|
|
@ -335,7 +335,7 @@ func (c *CloudWatchLogs) Write(metrics []telegraf.Metric) error {
|
|||
lsContainer.currentBatchIndex++
|
||||
lsContainer.messageBatches = append(lsContainer.messageBatches,
|
||||
messageBatch{
|
||||
logEvents: []*cloudwatchlogs.InputLogEvent{},
|
||||
logEvents: []types.InputLogEvent{},
|
||||
messageCount: 0})
|
||||
lsContainer.currentBatchSizeBytes = messageSizeInBytesForAWS
|
||||
} else {
|
||||
|
|
@ -349,7 +349,7 @@ func (c *CloudWatchLogs) Write(metrics []telegraf.Metric) error {
|
|||
//Adding metring to batch
|
||||
lsContainer.messageBatches[lsContainer.currentBatchIndex].logEvents =
|
||||
append(lsContainer.messageBatches[lsContainer.currentBatchIndex].logEvents,
|
||||
&cloudwatchlogs.InputLogEvent{
|
||||
types.InputLogEvent{
|
||||
Message: &logData,
|
||||
Timestamp: &metricTime})
|
||||
}
|
||||
|
|
@ -370,11 +370,11 @@ func (c *CloudWatchLogs) Write(metrics []telegraf.Metric) error {
|
|||
if elem.sequenceToken == "" {
|
||||
//This is the first attempt to write to log stream,
|
||||
//need to check log stream existence and create it if necessary
|
||||
describeLogStreamOutput, err := c.svc.DescribeLogStreams(&cloudwatchlogs.DescribeLogStreamsInput{
|
||||
describeLogStreamOutput, err := c.svc.DescribeLogStreams(context.Background(), &cloudwatchlogs.DescribeLogStreamsInput{
|
||||
LogGroupName: &c.LogGroup,
|
||||
LogStreamNamePrefix: &logStream})
|
||||
if err == nil && len(describeLogStreamOutput.LogStreams) == 0 {
|
||||
_, err := c.svc.CreateLogStream(&cloudwatchlogs.CreateLogStreamInput{
|
||||
_, err := c.svc.CreateLogStream(context.Background(), &cloudwatchlogs.CreateLogStreamInput{
|
||||
LogGroupName: &c.LogGroup,
|
||||
LogStreamName: &logStream})
|
||||
if err != nil {
|
||||
|
|
@ -404,14 +404,14 @@ func (c *CloudWatchLogs) Write(metrics []telegraf.Metric) error {
|
|||
|
||||
//There is a quota of 5 requests per second per log stream. Additional
|
||||
//requests are throttled. This quota can't be changed.
|
||||
putLogEventsOutput, err := c.svc.PutLogEvents(&putLogEvents)
|
||||
putLogEventsOutput, err := c.svc.PutLogEvents(context.Background(), &putLogEvents)
|
||||
if err != nil {
|
||||
c.Log.Errorf("Can't push logs batch to AWS. Reason: %v", err)
|
||||
continue
|
||||
}
|
||||
//Cleanup batch
|
||||
elem.messageBatches[index] = messageBatch{
|
||||
logEvents: []*cloudwatchlogs.InputLogEvent{},
|
||||
logEvents: []types.InputLogEvent{},
|
||||
messageCount: 0}
|
||||
|
||||
elem.sequenceToken = *putLogEventsOutput.NextSequenceToken
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package cloudwatch_logs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
|
|
@ -8,7 +9,8 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/service/cloudwatchlogs"
|
||||
cloudwatchlogsV2 "github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs"
|
||||
"github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs/types"
|
||||
"github.com/influxdata/telegraf"
|
||||
internalaws "github.com/influxdata/telegraf/config/aws"
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
|
|
@ -17,24 +19,24 @@ import (
|
|||
|
||||
type mockCloudWatchLogs struct {
|
||||
logStreamName string
|
||||
pushedLogEvents []cloudwatchlogs.InputLogEvent
|
||||
pushedLogEvents []types.InputLogEvent
|
||||
}
|
||||
|
||||
func (c *mockCloudWatchLogs) Init(lsName string) {
|
||||
c.logStreamName = lsName
|
||||
c.pushedLogEvents = make([]cloudwatchlogs.InputLogEvent, 0)
|
||||
c.pushedLogEvents = make([]types.InputLogEvent, 0)
|
||||
}
|
||||
|
||||
func (c *mockCloudWatchLogs) DescribeLogGroups(*cloudwatchlogs.DescribeLogGroupsInput) (*cloudwatchlogs.DescribeLogGroupsOutput, error) {
|
||||
func (c *mockCloudWatchLogs) DescribeLogGroups(context.Context, *cloudwatchlogsV2.DescribeLogGroupsInput, ...func(options *cloudwatchlogsV2.Options)) (*cloudwatchlogsV2.DescribeLogGroupsOutput, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *mockCloudWatchLogs) DescribeLogStreams(*cloudwatchlogs.DescribeLogStreamsInput) (*cloudwatchlogs.DescribeLogStreamsOutput, error) {
|
||||
func (c *mockCloudWatchLogs) DescribeLogStreams(context.Context, *cloudwatchlogsV2.DescribeLogStreamsInput, ...func(options *cloudwatchlogsV2.Options)) (*cloudwatchlogsV2.DescribeLogStreamsOutput, error) {
|
||||
arn := "arn"
|
||||
creationTime := time.Now().Unix()
|
||||
sequenceToken := "arbitraryToken"
|
||||
output := &cloudwatchlogs.DescribeLogStreamsOutput{
|
||||
LogStreams: []*cloudwatchlogs.LogStream{
|
||||
output := &cloudwatchlogsV2.DescribeLogStreamsOutput{
|
||||
LogStreams: []types.LogStream{
|
||||
{
|
||||
Arn: &arn,
|
||||
CreationTime: &creationTime,
|
||||
|
|
@ -48,15 +50,15 @@ func (c *mockCloudWatchLogs) DescribeLogStreams(*cloudwatchlogs.DescribeLogStrea
|
|||
}
|
||||
return output, nil
|
||||
}
|
||||
func (c *mockCloudWatchLogs) CreateLogStream(*cloudwatchlogs.CreateLogStreamInput) (*cloudwatchlogs.CreateLogStreamOutput, error) {
|
||||
func (c *mockCloudWatchLogs) CreateLogStream(context.Context, *cloudwatchlogsV2.CreateLogStreamInput, ...func(options *cloudwatchlogsV2.Options)) (*cloudwatchlogsV2.CreateLogStreamOutput, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (c *mockCloudWatchLogs) PutLogEvents(input *cloudwatchlogs.PutLogEventsInput) (*cloudwatchlogs.PutLogEventsOutput, error) {
|
||||
func (c *mockCloudWatchLogs) PutLogEvents(_ context.Context, input *cloudwatchlogsV2.PutLogEventsInput, _ ...func(options *cloudwatchlogsV2.Options)) (*cloudwatchlogsV2.PutLogEventsOutput, error) {
|
||||
sequenceToken := "arbitraryToken"
|
||||
output := &cloudwatchlogs.PutLogEventsOutput{NextSequenceToken: &sequenceToken}
|
||||
output := &cloudwatchlogsV2.PutLogEventsOutput{NextSequenceToken: &sequenceToken}
|
||||
//Saving messages
|
||||
for _, event := range input.LogEvents {
|
||||
c.pushedLogEvents = append(c.pushedLogEvents, *event)
|
||||
c.pushedLogEvents = append(c.pushedLogEvents, event)
|
||||
}
|
||||
|
||||
return output, nil
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
package kinesis
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/kinesis"
|
||||
"github.com/aws/aws-sdk-go/service/kinesis/kinesisiface"
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/aws/aws-sdk-go-v2/service/kinesis"
|
||||
"github.com/aws/aws-sdk-go-v2/service/kinesis/types"
|
||||
"github.com/gofrs/uuid"
|
||||
"github.com/influxdata/telegraf"
|
||||
internalaws "github.com/influxdata/telegraf/config/aws"
|
||||
|
|
@ -26,7 +27,7 @@ type (
|
|||
|
||||
Log telegraf.Logger `toml:"-"`
|
||||
serializer serializers.Serializer
|
||||
svc kinesisiface.KinesisAPI
|
||||
svc kinesisClient
|
||||
|
||||
internalaws.CredentialConfig
|
||||
}
|
||||
|
|
@ -38,6 +39,10 @@ type (
|
|||
}
|
||||
)
|
||||
|
||||
type kinesisClient interface {
|
||||
PutRecords(context.Context, *kinesis.PutRecordsInput, ...func(*kinesis.Options)) (*kinesis.PutRecordsOutput, error)
|
||||
}
|
||||
|
||||
var sampleConfig = `
|
||||
## Amazon REGION of kinesis endpoint.
|
||||
region = "ap-southeast-2"
|
||||
|
|
@ -126,13 +131,14 @@ func (k *KinesisOutput) Connect() error {
|
|||
k.Log.Infof("Establishing a connection to Kinesis in %s", k.Region)
|
||||
}
|
||||
|
||||
p, err := k.CredentialConfig.Credentials()
|
||||
cfg, err := k.CredentialConfig.Credentials()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
svc := kinesis.New(p)
|
||||
|
||||
_, err = svc.DescribeStreamSummary(&kinesis.DescribeStreamSummaryInput{
|
||||
svc := kinesis.NewFromConfig(cfg)
|
||||
|
||||
_, err = svc.DescribeStreamSummary(context.Background(), &kinesis.DescribeStreamSummaryInput{
|
||||
StreamName: aws.String(k.StreamName),
|
||||
})
|
||||
k.svc = svc
|
||||
|
|
@ -147,14 +153,14 @@ func (k *KinesisOutput) SetSerializer(serializer serializers.Serializer) {
|
|||
k.serializer = serializer
|
||||
}
|
||||
|
||||
func (k *KinesisOutput) writeKinesis(r []*kinesis.PutRecordsRequestEntry) time.Duration {
|
||||
func (k *KinesisOutput) writeKinesis(r []types.PutRecordsRequestEntry) time.Duration {
|
||||
start := time.Now()
|
||||
payload := &kinesis.PutRecordsInput{
|
||||
Records: r,
|
||||
StreamName: aws.String(k.StreamName),
|
||||
}
|
||||
|
||||
resp, err := k.svc.PutRecords(payload)
|
||||
resp, err := k.svc.PutRecords(context.Background(), payload)
|
||||
if err != nil {
|
||||
k.Log.Errorf("Unable to write to Kinesis : %s", err.Error())
|
||||
return time.Since(start)
|
||||
|
|
@ -214,7 +220,7 @@ func (k *KinesisOutput) Write(metrics []telegraf.Metric) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
r := []*kinesis.PutRecordsRequestEntry{}
|
||||
r := []types.PutRecordsRequestEntry{}
|
||||
|
||||
for _, metric := range metrics {
|
||||
sz++
|
||||
|
|
@ -227,12 +233,12 @@ func (k *KinesisOutput) Write(metrics []telegraf.Metric) error {
|
|||
|
||||
partitionKey := k.getPartitionKey(metric)
|
||||
|
||||
d := kinesis.PutRecordsRequestEntry{
|
||||
d := types.PutRecordsRequestEntry{
|
||||
Data: values,
|
||||
PartitionKey: aws.String(partitionKey),
|
||||
}
|
||||
|
||||
r = append(r, &d)
|
||||
r = append(r, d)
|
||||
|
||||
if sz == maxRecordsPerRequest {
|
||||
elapsed := k.writeKinesis(r)
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
package kinesis
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/service/kinesis"
|
||||
"github.com/aws/aws-sdk-go/service/kinesis/kinesisiface"
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/aws/aws-sdk-go-v2/service/kinesis"
|
||||
"github.com/aws/aws-sdk-go-v2/service/kinesis/types"
|
||||
"github.com/gofrs/uuid"
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/plugins/serializers"
|
||||
|
|
@ -110,7 +110,7 @@ func TestPartitionKey(t *testing.T) {
|
|||
func TestWriteKinesis_WhenSuccess(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
records := []*kinesis.PutRecordsRequestEntry{
|
||||
records := []types.PutRecordsRequestEntry{
|
||||
{
|
||||
PartitionKey: aws.String(testPartitionKey),
|
||||
Data: []byte{0x65},
|
||||
|
|
@ -120,7 +120,7 @@ func TestWriteKinesis_WhenSuccess(t *testing.T) {
|
|||
svc := &mockKinesisPutRecords{}
|
||||
svc.SetupResponse(
|
||||
0,
|
||||
[]*kinesis.PutRecordsResultEntry{
|
||||
[]types.PutRecordsResultEntry{
|
||||
{
|
||||
SequenceNumber: aws.String(testSequenceNumber),
|
||||
ShardId: aws.String(testShardID),
|
||||
|
|
@ -148,7 +148,7 @@ func TestWriteKinesis_WhenSuccess(t *testing.T) {
|
|||
func TestWriteKinesis_WhenRecordErrors(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
records := []*kinesis.PutRecordsRequestEntry{
|
||||
records := []types.PutRecordsRequestEntry{
|
||||
{
|
||||
PartitionKey: aws.String(testPartitionKey),
|
||||
Data: []byte{0x66},
|
||||
|
|
@ -158,7 +158,7 @@ func TestWriteKinesis_WhenRecordErrors(t *testing.T) {
|
|||
svc := &mockKinesisPutRecords{}
|
||||
svc.SetupResponse(
|
||||
1,
|
||||
[]*kinesis.PutRecordsResultEntry{
|
||||
[]types.PutRecordsResultEntry{
|
||||
{
|
||||
ErrorCode: aws.String("InternalFailure"),
|
||||
ErrorMessage: aws.String("Internal Service Failure"),
|
||||
|
|
@ -186,7 +186,7 @@ func TestWriteKinesis_WhenRecordErrors(t *testing.T) {
|
|||
func TestWriteKinesis_WhenServiceError(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
records := []*kinesis.PutRecordsRequestEntry{
|
||||
records := []types.PutRecordsRequestEntry{
|
||||
{
|
||||
PartitionKey: aws.String(testPartitionKey),
|
||||
Data: []byte{},
|
||||
|
|
@ -195,7 +195,7 @@ func TestWriteKinesis_WhenServiceError(t *testing.T) {
|
|||
|
||||
svc := &mockKinesisPutRecords{}
|
||||
svc.SetupErrorResponse(
|
||||
awserr.New("InvalidArgumentException", "Invalid record", nil),
|
||||
&types.InvalidArgumentException{Message: aws.String("Invalid record")},
|
||||
)
|
||||
|
||||
k := KinesisOutput{
|
||||
|
|
@ -262,7 +262,7 @@ func TestWrite_SingleMetric(t *testing.T) {
|
|||
svc.AssertRequests(t, []*kinesis.PutRecordsInput{
|
||||
{
|
||||
StreamName: aws.String(testStreamName),
|
||||
Records: []*kinesis.PutRecordsRequestEntry{
|
||||
Records: []types.PutRecordsRequestEntry{
|
||||
{
|
||||
PartitionKey: aws.String(testPartitionKey),
|
||||
Data: metricData,
|
||||
|
|
@ -449,7 +449,7 @@ func TestWrite_SerializerError(t *testing.T) {
|
|||
svc.AssertRequests(t, []*kinesis.PutRecordsInput{
|
||||
{
|
||||
StreamName: aws.String(testStreamName),
|
||||
Records: []*kinesis.PutRecordsRequestEntry{
|
||||
Records: []types.PutRecordsRequestEntry{
|
||||
{
|
||||
PartitionKey: aws.String(testPartitionKey),
|
||||
Data: metric1Data,
|
||||
|
|
@ -469,20 +469,18 @@ type mockKinesisPutRecordsResponse struct {
|
|||
}
|
||||
|
||||
type mockKinesisPutRecords struct {
|
||||
kinesisiface.KinesisAPI
|
||||
|
||||
requests []*kinesis.PutRecordsInput
|
||||
responses []*mockKinesisPutRecordsResponse
|
||||
}
|
||||
|
||||
func (m *mockKinesisPutRecords) SetupResponse(
|
||||
failedRecordCount int64,
|
||||
records []*kinesis.PutRecordsResultEntry,
|
||||
failedRecordCount int32,
|
||||
records []types.PutRecordsResultEntry,
|
||||
) {
|
||||
m.responses = append(m.responses, &mockKinesisPutRecordsResponse{
|
||||
Err: nil,
|
||||
Output: &kinesis.PutRecordsOutput{
|
||||
FailedRecordCount: aws.Int64(failedRecordCount),
|
||||
FailedRecordCount: aws.Int32(failedRecordCount),
|
||||
Records: records,
|
||||
},
|
||||
})
|
||||
|
|
@ -490,25 +488,25 @@ func (m *mockKinesisPutRecords) SetupResponse(
|
|||
|
||||
func (m *mockKinesisPutRecords) SetupGenericResponse(
|
||||
successfulRecordCount uint32,
|
||||
failedRecordCount uint32,
|
||||
failedRecordCount int32,
|
||||
) {
|
||||
records := []*kinesis.PutRecordsResultEntry{}
|
||||
records := []types.PutRecordsResultEntry{}
|
||||
|
||||
for i := uint32(0); i < successfulRecordCount; i++ {
|
||||
records = append(records, &kinesis.PutRecordsResultEntry{
|
||||
records = append(records, types.PutRecordsResultEntry{
|
||||
SequenceNumber: aws.String(testSequenceNumber),
|
||||
ShardId: aws.String(testShardID),
|
||||
})
|
||||
}
|
||||
|
||||
for i := uint32(0); i < failedRecordCount; i++ {
|
||||
records = append(records, &kinesis.PutRecordsResultEntry{
|
||||
for i := int32(0); i < failedRecordCount; i++ {
|
||||
records = append(records, types.PutRecordsResultEntry{
|
||||
ErrorCode: aws.String("InternalFailure"),
|
||||
ErrorMessage: aws.String("Internal Service Failure"),
|
||||
})
|
||||
}
|
||||
|
||||
m.SetupResponse(int64(failedRecordCount), records)
|
||||
m.SetupResponse(failedRecordCount, records)
|
||||
}
|
||||
|
||||
func (m *mockKinesisPutRecords) SetupErrorResponse(err error) {
|
||||
|
|
@ -518,7 +516,7 @@ func (m *mockKinesisPutRecords) SetupErrorResponse(err error) {
|
|||
})
|
||||
}
|
||||
|
||||
func (m *mockKinesisPutRecords) PutRecords(input *kinesis.PutRecordsInput) (*kinesis.PutRecordsOutput, error) {
|
||||
func (m *mockKinesisPutRecords) PutRecords(_ context.Context, input *kinesis.PutRecordsInput, _ ...func(*kinesis.Options)) (*kinesis.PutRecordsOutput, error) {
|
||||
reqNum := len(m.requests)
|
||||
if reqNum > len(m.responses) {
|
||||
return nil, fmt.Errorf("Response for request %+v not setup", reqNum)
|
||||
|
|
@ -612,12 +610,12 @@ func createTestMetrics(
|
|||
|
||||
func createPutRecordsRequestEntries(
|
||||
metricsData [][]byte,
|
||||
) []*kinesis.PutRecordsRequestEntry {
|
||||
) []types.PutRecordsRequestEntry {
|
||||
count := len(metricsData)
|
||||
records := make([]*kinesis.PutRecordsRequestEntry, count)
|
||||
records := make([]types.PutRecordsRequestEntry, count)
|
||||
|
||||
for i := 0; i < count; i++ {
|
||||
records[i] = &kinesis.PutRecordsRequestEntry{
|
||||
records[i] = types.PutRecordsRequestEntry{
|
||||
PartitionKey: aws.String(testPartitionKey),
|
||||
Data: metricsData[i],
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
package timestream
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash/fnv"
|
||||
"reflect"
|
||||
|
|
@ -11,9 +13,10 @@ import (
|
|||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/plugins/outputs"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/service/timestreamwrite"
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/aws/aws-sdk-go-v2/service/timestreamwrite"
|
||||
"github.com/aws/aws-sdk-go-v2/service/timestreamwrite/types"
|
||||
"github.com/aws/smithy-go"
|
||||
internalaws "github.com/influxdata/telegraf/config/aws"
|
||||
)
|
||||
|
||||
|
|
@ -38,9 +41,9 @@ type (
|
|||
}
|
||||
|
||||
WriteClient interface {
|
||||
CreateTable(*timestreamwrite.CreateTableInput) (*timestreamwrite.CreateTableOutput, error)
|
||||
WriteRecords(*timestreamwrite.WriteRecordsInput) (*timestreamwrite.WriteRecordsOutput, error)
|
||||
DescribeDatabase(*timestreamwrite.DescribeDatabaseInput) (*timestreamwrite.DescribeDatabaseOutput, error)
|
||||
CreateTable(context.Context, *timestreamwrite.CreateTableInput, ...func(*timestreamwrite.Options)) (*timestreamwrite.CreateTableOutput, error)
|
||||
WriteRecords(context.Context, *timestreamwrite.WriteRecordsInput, ...func(*timestreamwrite.Options)) (*timestreamwrite.WriteRecordsOutput, error)
|
||||
DescribeDatabase(context.Context, *timestreamwrite.DescribeDatabaseInput, ...func(*timestreamwrite.Options)) (*timestreamwrite.DescribeDatabaseOutput, error)
|
||||
}
|
||||
)
|
||||
|
||||
|
|
@ -170,11 +173,11 @@ var sampleConfig = `
|
|||
|
||||
// WriteFactory function provides a way to mock the client instantiation for testing purposes.
|
||||
var WriteFactory = func(credentialConfig *internalaws.CredentialConfig) (WriteClient, error) {
|
||||
configProvider, err := credentialConfig.Credentials()
|
||||
cfg, err := credentialConfig.Credentials()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return ×treamwrite.Client{}, err
|
||||
}
|
||||
return timestreamwrite.New(configProvider), nil
|
||||
return timestreamwrite.NewFromConfig(cfg), nil
|
||||
}
|
||||
|
||||
func (t *Timestream) Connect() error {
|
||||
|
|
@ -235,7 +238,7 @@ func (t *Timestream) Connect() error {
|
|||
describeDatabaseInput := ×treamwrite.DescribeDatabaseInput{
|
||||
DatabaseName: aws.String(t.DatabaseName),
|
||||
}
|
||||
describeDatabaseOutput, err := svc.DescribeDatabase(describeDatabaseInput)
|
||||
describeDatabaseOutput, err := svc.DescribeDatabase(context.Background(), describeDatabaseInput)
|
||||
if err != nil {
|
||||
t.Log.Errorf("Couldn't describe database '%s'. Check error, fix permissions, connectivity, create database.", t.DatabaseName)
|
||||
return err
|
||||
|
|
@ -278,33 +281,45 @@ func (t *Timestream) Write(metrics []telegraf.Metric) error {
|
|||
func (t *Timestream) writeToTimestream(writeRecordsInput *timestreamwrite.WriteRecordsInput, resourceNotFoundRetry bool) error {
|
||||
t.Log.Debugf("Writing to Timestream: '%v' with ResourceNotFoundRetry: '%t'", writeRecordsInput, resourceNotFoundRetry)
|
||||
|
||||
_, err := t.svc.WriteRecords(writeRecordsInput)
|
||||
_, err := t.svc.WriteRecords(context.Background(), writeRecordsInput)
|
||||
if err != nil {
|
||||
// Telegraf will retry ingesting the metrics if an error is returned from the plugin.
|
||||
// Therefore, return error only for retryable exceptions: ThrottlingException and 5xx exceptions.
|
||||
if e, ok := err.(awserr.Error); ok {
|
||||
switch e.Code() {
|
||||
case timestreamwrite.ErrCodeResourceNotFoundException:
|
||||
if resourceNotFoundRetry {
|
||||
t.Log.Warnf("Failed to write to Timestream database '%s' table '%s'. Error: '%s'",
|
||||
t.DatabaseName, *writeRecordsInput.TableName, e)
|
||||
return t.createTableAndRetry(writeRecordsInput)
|
||||
}
|
||||
t.logWriteToTimestreamError(err, writeRecordsInput.TableName)
|
||||
case timestreamwrite.ErrCodeThrottlingException:
|
||||
return fmt.Errorf("unable to write to Timestream database '%s' table '%s'. Error: %s",
|
||||
t.DatabaseName, *writeRecordsInput.TableName, err)
|
||||
case timestreamwrite.ErrCodeInternalServerException:
|
||||
return fmt.Errorf("unable to write to Timestream database '%s' table '%s'. Error: %s",
|
||||
t.DatabaseName, *writeRecordsInput.TableName, err)
|
||||
default:
|
||||
t.logWriteToTimestreamError(err, writeRecordsInput.TableName)
|
||||
var notFound *types.ResourceNotFoundException
|
||||
if errors.As(err, ¬Found) {
|
||||
if resourceNotFoundRetry {
|
||||
t.Log.Warnf("Failed to write to Timestream database '%s' table '%s'. Error: '%s'",
|
||||
t.DatabaseName, *writeRecordsInput.TableName, notFound)
|
||||
return t.createTableAndRetry(writeRecordsInput)
|
||||
}
|
||||
} else {
|
||||
t.logWriteToTimestreamError(notFound, writeRecordsInput.TableName)
|
||||
}
|
||||
|
||||
var rejected *types.RejectedRecordsException
|
||||
if errors.As(err, &rejected) {
|
||||
t.logWriteToTimestreamError(err, writeRecordsInput.TableName)
|
||||
return nil
|
||||
}
|
||||
|
||||
var throttling *types.ThrottlingException
|
||||
if errors.As(err, &throttling) {
|
||||
return fmt.Errorf("unable to write to Timestream database '%s' table '%s'. Error: %s",
|
||||
t.DatabaseName, *writeRecordsInput.TableName, throttling)
|
||||
}
|
||||
|
||||
var internal *types.InternalServerException
|
||||
if errors.As(err, &internal) {
|
||||
return fmt.Errorf("unable to write to Timestream database '%s' table '%s'. Error: %s",
|
||||
t.DatabaseName, *writeRecordsInput.TableName, internal)
|
||||
}
|
||||
|
||||
var operation *smithy.OperationError
|
||||
if !errors.As(err, &operation) {
|
||||
// Retry other, non-aws errors.
|
||||
return fmt.Errorf("unable to write to Timestream database '%s' table '%s'. Error: %s",
|
||||
t.DatabaseName, *writeRecordsInput.TableName, err)
|
||||
}
|
||||
t.logWriteToTimestreamError(err, writeRecordsInput.TableName)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -334,27 +349,25 @@ func (t *Timestream) createTable(tableName *string) error {
|
|||
createTableInput := ×treamwrite.CreateTableInput{
|
||||
DatabaseName: aws.String(t.DatabaseName),
|
||||
TableName: aws.String(*tableName),
|
||||
RetentionProperties: ×treamwrite.RetentionProperties{
|
||||
MagneticStoreRetentionPeriodInDays: aws.Int64(t.CreateTableMagneticStoreRetentionPeriodInDays),
|
||||
MemoryStoreRetentionPeriodInHours: aws.Int64(t.CreateTableMemoryStoreRetentionPeriodInHours),
|
||||
RetentionProperties: &types.RetentionProperties{
|
||||
MagneticStoreRetentionPeriodInDays: t.CreateTableMagneticStoreRetentionPeriodInDays,
|
||||
MemoryStoreRetentionPeriodInHours: t.CreateTableMemoryStoreRetentionPeriodInHours,
|
||||
},
|
||||
}
|
||||
var tags []*timestreamwrite.Tag
|
||||
var tags []types.Tag
|
||||
for key, val := range t.CreateTableTags {
|
||||
tags = append(tags, ×treamwrite.Tag{
|
||||
tags = append(tags, types.Tag{
|
||||
Key: aws.String(key),
|
||||
Value: aws.String(val),
|
||||
})
|
||||
}
|
||||
createTableInput.SetTags(tags)
|
||||
createTableInput.Tags = tags
|
||||
|
||||
_, err := t.svc.CreateTable(createTableInput)
|
||||
_, err := t.svc.CreateTable(context.Background(), createTableInput)
|
||||
if err != nil {
|
||||
if e, ok := err.(awserr.Error); ok {
|
||||
if _, ok := err.(*types.ConflictException); ok {
|
||||
// if the table was created in the meantime, it's ok.
|
||||
if e.Code() == timestreamwrite.ErrCodeConflictException {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
@ -380,17 +393,17 @@ func (t *Timestream) TransformMetrics(metrics []telegraf.Metric) []*timestreamwr
|
|||
newWriteRecord := ×treamwrite.WriteRecordsInput{
|
||||
DatabaseName: aws.String(t.DatabaseName),
|
||||
Records: records,
|
||||
CommonAttributes: ×treamwrite.Record{
|
||||
CommonAttributes: &types.Record{
|
||||
Dimensions: dimensions,
|
||||
Time: aws.String(timeValue),
|
||||
TimeUnit: aws.String(timeUnit),
|
||||
TimeUnit: timeUnit,
|
||||
},
|
||||
}
|
||||
if t.MappingMode == MappingModeSingleTable {
|
||||
newWriteRecord.SetTableName(t.SingleTableName)
|
||||
newWriteRecord.TableName = &t.SingleTableName
|
||||
}
|
||||
if t.MappingMode == MappingModeMultiTable {
|
||||
newWriteRecord.SetTableName(m.Name())
|
||||
newWriteRecord.TableName = aws.String(m.Name())
|
||||
}
|
||||
|
||||
writeRequests[id] = newWriteRecord
|
||||
|
|
@ -440,17 +453,17 @@ func hashFromMetricTimeNameTagKeys(m telegraf.Metric) uint64 {
|
|||
return h.Sum64()
|
||||
}
|
||||
|
||||
func (t *Timestream) buildDimensions(point telegraf.Metric) []*timestreamwrite.Dimension {
|
||||
var dimensions []*timestreamwrite.Dimension
|
||||
func (t *Timestream) buildDimensions(point telegraf.Metric) []types.Dimension {
|
||||
var dimensions []types.Dimension
|
||||
for tagName, tagValue := range point.Tags() {
|
||||
dimension := ×treamwrite.Dimension{
|
||||
dimension := types.Dimension{
|
||||
Name: aws.String(tagName),
|
||||
Value: aws.String(tagValue),
|
||||
}
|
||||
dimensions = append(dimensions, dimension)
|
||||
}
|
||||
if t.MappingMode == MappingModeSingleTable {
|
||||
dimension := ×treamwrite.Dimension{
|
||||
dimension := types.Dimension{
|
||||
Name: aws.String(t.SingleTableDimensionNameForTelegrafMeasurementName),
|
||||
Value: aws.String(point.Name()),
|
||||
}
|
||||
|
|
@ -463,8 +476,8 @@ func (t *Timestream) buildDimensions(point telegraf.Metric) []*timestreamwrite.D
|
|||
// Tags and time are not included - common attributes are built separately.
|
||||
// Records with unsupported Metric Field type are skipped.
|
||||
// It returns an array of Timestream write records.
|
||||
func (t *Timestream) buildWriteRecords(point telegraf.Metric) []*timestreamwrite.Record {
|
||||
var records []*timestreamwrite.Record
|
||||
func (t *Timestream) buildWriteRecords(point telegraf.Metric) []types.Record {
|
||||
var records []types.Record
|
||||
for fieldName, fieldValue := range point.Fields() {
|
||||
stringFieldValue, stringFieldValueType, ok := convertValue(fieldValue)
|
||||
if !ok {
|
||||
|
|
@ -473,9 +486,9 @@ func (t *Timestream) buildWriteRecords(point telegraf.Metric) []*timestreamwrite
|
|||
fieldName, reflect.TypeOf(fieldValue))
|
||||
continue
|
||||
}
|
||||
record := ×treamwrite.Record{
|
||||
record := types.Record{
|
||||
MeasureName: aws.String(fieldName),
|
||||
MeasureValueType: aws.String(stringFieldValueType),
|
||||
MeasureValueType: stringFieldValueType,
|
||||
MeasureValue: aws.String(stringFieldValue),
|
||||
}
|
||||
records = append(records, record)
|
||||
|
|
@ -486,13 +499,13 @@ func (t *Timestream) buildWriteRecords(point telegraf.Metric) []*timestreamwrite
|
|||
// partitionRecords splits the Timestream records into smaller slices of a max size
|
||||
// so that are under the limit for the Timestream API call.
|
||||
// It returns the array of array of records.
|
||||
func partitionRecords(size int, records []*timestreamwrite.Record) [][]*timestreamwrite.Record {
|
||||
func partitionRecords(size int, records []types.Record) [][]types.Record {
|
||||
numberOfPartitions := len(records) / size
|
||||
if len(records)%size != 0 {
|
||||
numberOfPartitions++
|
||||
}
|
||||
|
||||
partitions := make([][]*timestreamwrite.Record, numberOfPartitions)
|
||||
partitions := make([][]types.Record, numberOfPartitions)
|
||||
|
||||
for i := 0; i < numberOfPartitions; i++ {
|
||||
start := size * i
|
||||
|
|
@ -509,25 +522,19 @@ func partitionRecords(size int, records []*timestreamwrite.Record) [][]*timestre
|
|||
|
||||
// getTimestreamTime produces Timestream TimeUnit and TimeValue with minimum possible granularity
|
||||
// while maintaining the same information.
|
||||
func getTimestreamTime(time time.Time) (timeUnit string, timeValue string) {
|
||||
const (
|
||||
TimeUnitS = "SECONDS"
|
||||
TimeUnitMS = "MILLISECONDS"
|
||||
TimeUnitUS = "MICROSECONDS"
|
||||
TimeUnitNS = "NANOSECONDS"
|
||||
)
|
||||
nanosTime := time.UnixNano()
|
||||
func getTimestreamTime(t time.Time) (timeUnit types.TimeUnit, timeValue string) {
|
||||
nanosTime := t.UnixNano()
|
||||
if nanosTime%1e9 == 0 {
|
||||
timeUnit = TimeUnitS
|
||||
timeUnit = types.TimeUnitSeconds
|
||||
timeValue = strconv.FormatInt(nanosTime/1e9, 10)
|
||||
} else if nanosTime%1e6 == 0 {
|
||||
timeUnit = TimeUnitMS
|
||||
timeUnit = types.TimeUnitMilliseconds
|
||||
timeValue = strconv.FormatInt(nanosTime/1e6, 10)
|
||||
} else if nanosTime%1e3 == 0 {
|
||||
timeUnit = TimeUnitUS
|
||||
timeUnit = types.TimeUnitMicroseconds
|
||||
timeValue = strconv.FormatInt(nanosTime/1e3, 10)
|
||||
} else {
|
||||
timeUnit = TimeUnitNS
|
||||
timeUnit = types.TimeUnitNanoseconds
|
||||
timeValue = strconv.FormatInt(nanosTime, 10)
|
||||
}
|
||||
return
|
||||
|
|
@ -535,61 +542,55 @@ func getTimestreamTime(time time.Time) (timeUnit string, timeValue string) {
|
|||
|
||||
// convertValue converts single Field value from Telegraf Metric and produces
|
||||
// value, valueType Timestream representation.
|
||||
func convertValue(v interface{}) (value string, valueType string, ok bool) {
|
||||
const (
|
||||
TypeBigInt = "BIGINT"
|
||||
TypeDouble = "DOUBLE"
|
||||
TypeBoolean = "BOOLEAN"
|
||||
TypeVarchar = "VARCHAR"
|
||||
)
|
||||
func convertValue(v interface{}) (value string, valueType types.MeasureValueType, ok bool) {
|
||||
ok = true
|
||||
|
||||
switch t := v.(type) {
|
||||
case int:
|
||||
valueType = TypeBigInt
|
||||
valueType = types.MeasureValueTypeBigint
|
||||
value = strconv.FormatInt(int64(t), 10)
|
||||
case int8:
|
||||
valueType = TypeBigInt
|
||||
valueType = types.MeasureValueTypeBigint
|
||||
value = strconv.FormatInt(int64(t), 10)
|
||||
case int16:
|
||||
valueType = TypeBigInt
|
||||
valueType = types.MeasureValueTypeBigint
|
||||
value = strconv.FormatInt(int64(t), 10)
|
||||
case int32:
|
||||
valueType = TypeBigInt
|
||||
valueType = types.MeasureValueTypeBigint
|
||||
value = strconv.FormatInt(int64(t), 10)
|
||||
case int64:
|
||||
valueType = TypeBigInt
|
||||
valueType = types.MeasureValueTypeBigint
|
||||
value = strconv.FormatInt(t, 10)
|
||||
case uint:
|
||||
valueType = TypeBigInt
|
||||
valueType = types.MeasureValueTypeBigint
|
||||
value = strconv.FormatUint(uint64(t), 10)
|
||||
case uint8:
|
||||
valueType = TypeBigInt
|
||||
valueType = types.MeasureValueTypeBigint
|
||||
value = strconv.FormatUint(uint64(t), 10)
|
||||
case uint16:
|
||||
valueType = TypeBigInt
|
||||
valueType = types.MeasureValueTypeBigint
|
||||
value = strconv.FormatUint(uint64(t), 10)
|
||||
case uint32:
|
||||
valueType = TypeBigInt
|
||||
valueType = types.MeasureValueTypeBigint
|
||||
value = strconv.FormatUint(uint64(t), 10)
|
||||
case uint64:
|
||||
valueType = TypeBigInt
|
||||
valueType = types.MeasureValueTypeBigint
|
||||
value = strconv.FormatUint(t, 10)
|
||||
case float32:
|
||||
valueType = TypeDouble
|
||||
valueType = types.MeasureValueTypeDouble
|
||||
value = strconv.FormatFloat(float64(t), 'f', -1, 32)
|
||||
case float64:
|
||||
valueType = TypeDouble
|
||||
valueType = types.MeasureValueTypeDouble
|
||||
value = strconv.FormatFloat(t, 'f', -1, 64)
|
||||
case bool:
|
||||
valueType = TypeBoolean
|
||||
valueType = types.MeasureValueTypeBoolean
|
||||
if t {
|
||||
value = "true"
|
||||
} else {
|
||||
value = "false"
|
||||
}
|
||||
case string:
|
||||
valueType = TypeVarchar
|
||||
valueType = types.MeasureValueTypeVarchar
|
||||
value = t
|
||||
default:
|
||||
// Skip unsupported type.
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/timestreamwrite"
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/aws/aws-sdk-go-v2/service/timestreamwrite/types"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
|
@ -19,57 +19,57 @@ func TestGetTimestreamTime(t *testing.T) {
|
|||
tOnlySeconds := time.Date(2020, time.November, 10, 23, 44, 20, 0, time.UTC)
|
||||
|
||||
tUnitNanos, tValueNanos := getTimestreamTime(tWithNanos)
|
||||
assertions.Equal("NANOSECONDS", tUnitNanos)
|
||||
assertions.Equal(types.TimeUnitNanoseconds, tUnitNanos)
|
||||
assertions.Equal("1605051860000000123", tValueNanos)
|
||||
|
||||
tUnitMicros, tValueMicros := getTimestreamTime(tWithMicros)
|
||||
assertions.Equal("MICROSECONDS", tUnitMicros)
|
||||
assertions.Equal(types.TimeUnitMicroseconds, tUnitMicros)
|
||||
assertions.Equal("1605051860000123", tValueMicros)
|
||||
|
||||
tUnitMillis, tValueMillis := getTimestreamTime(tWithMillis)
|
||||
assertions.Equal("MILLISECONDS", tUnitMillis)
|
||||
assertions.Equal(types.TimeUnitMilliseconds, tUnitMillis)
|
||||
assertions.Equal("1605051860123", tValueMillis)
|
||||
|
||||
tUnitSeconds, tValueSeconds := getTimestreamTime(tOnlySeconds)
|
||||
assertions.Equal("SECONDS", tUnitSeconds)
|
||||
assertions.Equal(types.TimeUnitSeconds, tUnitSeconds)
|
||||
assertions.Equal("1605051860", tValueSeconds)
|
||||
}
|
||||
|
||||
func TestPartitionRecords(t *testing.T) {
|
||||
assertions := assert.New(t)
|
||||
|
||||
testDatum := timestreamwrite.Record{
|
||||
testDatum := types.Record{
|
||||
MeasureName: aws.String("Foo"),
|
||||
MeasureValueType: aws.String("DOUBLE"),
|
||||
MeasureValueType: types.MeasureValueTypeDouble,
|
||||
MeasureValue: aws.String("123"),
|
||||
}
|
||||
|
||||
var zeroDatum []*timestreamwrite.Record
|
||||
oneDatum := []*timestreamwrite.Record{&testDatum}
|
||||
twoDatum := []*timestreamwrite.Record{&testDatum, &testDatum}
|
||||
threeDatum := []*timestreamwrite.Record{&testDatum, &testDatum, &testDatum}
|
||||
var zeroDatum []types.Record
|
||||
oneDatum := []types.Record{testDatum}
|
||||
twoDatum := []types.Record{testDatum, testDatum}
|
||||
threeDatum := []types.Record{testDatum, testDatum, testDatum}
|
||||
|
||||
assertions.Equal([][]*timestreamwrite.Record{}, partitionRecords(2, zeroDatum))
|
||||
assertions.Equal([][]*timestreamwrite.Record{oneDatum}, partitionRecords(2, oneDatum))
|
||||
assertions.Equal([][]*timestreamwrite.Record{oneDatum}, partitionRecords(2, oneDatum))
|
||||
assertions.Equal([][]*timestreamwrite.Record{twoDatum}, partitionRecords(2, twoDatum))
|
||||
assertions.Equal([][]*timestreamwrite.Record{twoDatum, oneDatum}, partitionRecords(2, threeDatum))
|
||||
assertions.Equal([][]types.Record{}, partitionRecords(2, zeroDatum))
|
||||
assertions.Equal([][]types.Record{oneDatum}, partitionRecords(2, oneDatum))
|
||||
assertions.Equal([][]types.Record{oneDatum}, partitionRecords(2, oneDatum))
|
||||
assertions.Equal([][]types.Record{twoDatum}, partitionRecords(2, twoDatum))
|
||||
assertions.Equal([][]types.Record{twoDatum, oneDatum}, partitionRecords(2, threeDatum))
|
||||
}
|
||||
|
||||
func TestConvertValueSupported(t *testing.T) {
|
||||
intInputValues := []interface{}{-1, int8(-2), int16(-3), int32(-4), int64(-5)}
|
||||
intOutputValues := []string{"-1", "-2", "-3", "-4", "-5"}
|
||||
intOutputValueTypes := []string{"BIGINT", "BIGINT", "BIGINT", "BIGINT", "BIGINT"}
|
||||
intOutputValueTypes := []types.MeasureValueType{types.MeasureValueTypeBigint, types.MeasureValueTypeBigint, types.MeasureValueTypeBigint, types.MeasureValueTypeBigint, types.MeasureValueTypeBigint}
|
||||
testConvertValueSupportedCases(t, intInputValues, intOutputValues, intOutputValueTypes)
|
||||
|
||||
uintInputValues := []interface{}{uint(1), uint8(2), uint16(3), uint32(4), uint64(5)}
|
||||
uintOutputValues := []string{"1", "2", "3", "4", "5"}
|
||||
uintOutputValueTypes := []string{"BIGINT", "BIGINT", "BIGINT", "BIGINT", "BIGINT"}
|
||||
uintOutputValueTypes := []types.MeasureValueType{types.MeasureValueTypeBigint, types.MeasureValueTypeBigint, types.MeasureValueTypeBigint, types.MeasureValueTypeBigint, types.MeasureValueTypeBigint}
|
||||
testConvertValueSupportedCases(t, uintInputValues, uintOutputValues, uintOutputValueTypes)
|
||||
|
||||
otherInputValues := []interface{}{"foo", float32(22.123), 22.1234, true}
|
||||
otherOutputValues := []string{"foo", "22.123", "22.1234", "true"}
|
||||
otherOutputValueTypes := []string{"VARCHAR", "DOUBLE", "DOUBLE", "BOOLEAN"}
|
||||
otherOutputValueTypes := []types.MeasureValueType{types.MeasureValueTypeVarchar, types.MeasureValueTypeDouble, types.MeasureValueTypeDouble, types.MeasureValueTypeBoolean}
|
||||
testConvertValueSupportedCases(t, otherInputValues, otherOutputValues, otherOutputValueTypes)
|
||||
}
|
||||
|
||||
|
|
@ -80,7 +80,7 @@ func TestConvertValueUnsupported(t *testing.T) {
|
|||
}
|
||||
|
||||
func testConvertValueSupportedCases(t *testing.T,
|
||||
inputValues []interface{}, outputValues []string, outputValueTypes []string) {
|
||||
inputValues []interface{}, outputValues []string, outputValueTypes []types.MeasureValueType) {
|
||||
assertions := assert.New(t)
|
||||
for i, inputValue := range inputValues {
|
||||
v, vt, ok := convertValue(inputValue)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package timestream_test
|
||||
package timestream
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
|
|
@ -9,13 +10,11 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/timestreamwrite"
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/aws/aws-sdk-go-v2/service/timestreamwrite"
|
||||
"github.com/aws/aws-sdk-go-v2/service/timestreamwrite/types"
|
||||
"github.com/influxdata/telegraf"
|
||||
internalaws "github.com/influxdata/telegraf/config/aws"
|
||||
ts "github.com/influxdata/telegraf/plugins/outputs/timestream"
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
|
@ -34,40 +33,37 @@ var time2 = time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)
|
|||
|
||||
const time2Epoch = "1257894000"
|
||||
|
||||
const timeUnit = "SECONDS"
|
||||
|
||||
const metricName1 = "metricName1"
|
||||
const metricName2 = "metricName2"
|
||||
|
||||
type mockTimestreamClient struct {
|
||||
}
|
||||
type mockTimestreamClient struct{}
|
||||
|
||||
func (m *mockTimestreamClient) CreateTable(*timestreamwrite.CreateTableInput) (*timestreamwrite.CreateTableOutput, error) {
|
||||
func (m *mockTimestreamClient) CreateTable(context.Context, *timestreamwrite.CreateTableInput, ...func(*timestreamwrite.Options)) (*timestreamwrite.CreateTableOutput, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (m *mockTimestreamClient) WriteRecords(*timestreamwrite.WriteRecordsInput) (*timestreamwrite.WriteRecordsOutput, error) {
|
||||
func (m *mockTimestreamClient) WriteRecords(context.Context, *timestreamwrite.WriteRecordsInput, ...func(*timestreamwrite.Options)) (*timestreamwrite.WriteRecordsOutput, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (m *mockTimestreamClient) DescribeDatabase(*timestreamwrite.DescribeDatabaseInput) (*timestreamwrite.DescribeDatabaseOutput, error) {
|
||||
func (m *mockTimestreamClient) DescribeDatabase(context.Context, *timestreamwrite.DescribeDatabaseInput, ...func(*timestreamwrite.Options)) (*timestreamwrite.DescribeDatabaseOutput, error) {
|
||||
return nil, fmt.Errorf("hello from DescribeDatabase")
|
||||
}
|
||||
|
||||
func TestConnectValidatesConfigParameters(t *testing.T) {
|
||||
assertions := assert.New(t)
|
||||
ts.WriteFactory = func(credentialConfig *internalaws.CredentialConfig) (ts.WriteClient, error) {
|
||||
WriteFactory = func(credentialConfig *internalaws.CredentialConfig) (WriteClient, error) {
|
||||
return &mockTimestreamClient{}, nil
|
||||
}
|
||||
// checking base arguments
|
||||
noDatabaseName := ts.Timestream{Log: testutil.Logger{}}
|
||||
noDatabaseName := Timestream{Log: testutil.Logger{}}
|
||||
assertions.Contains(noDatabaseName.Connect().Error(), "DatabaseName")
|
||||
|
||||
noMappingMode := ts.Timestream{
|
||||
noMappingMode := Timestream{
|
||||
DatabaseName: tsDbName,
|
||||
Log: testutil.Logger{},
|
||||
}
|
||||
assertions.Contains(noMappingMode.Connect().Error(), "MappingMode")
|
||||
|
||||
incorrectMappingMode := ts.Timestream{
|
||||
incorrectMappingMode := Timestream{
|
||||
DatabaseName: tsDbName,
|
||||
MappingMode: "foo",
|
||||
Log: testutil.Logger{},
|
||||
|
|
@ -75,24 +71,24 @@ func TestConnectValidatesConfigParameters(t *testing.T) {
|
|||
assertions.Contains(incorrectMappingMode.Connect().Error(), "single-table")
|
||||
|
||||
// multi-table arguments
|
||||
validMappingModeMultiTable := ts.Timestream{
|
||||
validMappingModeMultiTable := Timestream{
|
||||
DatabaseName: tsDbName,
|
||||
MappingMode: ts.MappingModeMultiTable,
|
||||
MappingMode: MappingModeMultiTable,
|
||||
Log: testutil.Logger{},
|
||||
}
|
||||
assertions.Nil(validMappingModeMultiTable.Connect())
|
||||
|
||||
singleTableNameWithMultiTable := ts.Timestream{
|
||||
singleTableNameWithMultiTable := Timestream{
|
||||
DatabaseName: tsDbName,
|
||||
MappingMode: ts.MappingModeMultiTable,
|
||||
MappingMode: MappingModeMultiTable,
|
||||
SingleTableName: testSingleTableName,
|
||||
Log: testutil.Logger{},
|
||||
}
|
||||
assertions.Contains(singleTableNameWithMultiTable.Connect().Error(), "SingleTableName")
|
||||
|
||||
singleTableDimensionWithMultiTable := ts.Timestream{
|
||||
singleTableDimensionWithMultiTable := Timestream{
|
||||
DatabaseName: tsDbName,
|
||||
MappingMode: ts.MappingModeMultiTable,
|
||||
MappingMode: MappingModeMultiTable,
|
||||
SingleTableDimensionNameForTelegrafMeasurementName: testSingleTableDim,
|
||||
Log: testutil.Logger{},
|
||||
}
|
||||
|
|
@ -100,25 +96,25 @@ func TestConnectValidatesConfigParameters(t *testing.T) {
|
|||
"SingleTableDimensionNameForTelegrafMeasurementName")
|
||||
|
||||
// single-table arguments
|
||||
noTableNameMappingModeSingleTable := ts.Timestream{
|
||||
noTableNameMappingModeSingleTable := Timestream{
|
||||
DatabaseName: tsDbName,
|
||||
MappingMode: ts.MappingModeSingleTable,
|
||||
MappingMode: MappingModeSingleTable,
|
||||
Log: testutil.Logger{},
|
||||
}
|
||||
assertions.Contains(noTableNameMappingModeSingleTable.Connect().Error(), "SingleTableName")
|
||||
|
||||
noDimensionNameMappingModeSingleTable := ts.Timestream{
|
||||
noDimensionNameMappingModeSingleTable := Timestream{
|
||||
DatabaseName: tsDbName,
|
||||
MappingMode: ts.MappingModeSingleTable,
|
||||
MappingMode: MappingModeSingleTable,
|
||||
SingleTableName: testSingleTableName,
|
||||
Log: testutil.Logger{},
|
||||
}
|
||||
assertions.Contains(noDimensionNameMappingModeSingleTable.Connect().Error(),
|
||||
"SingleTableDimensionNameForTelegrafMeasurementName")
|
||||
|
||||
validConfigurationMappingModeSingleTable := ts.Timestream{
|
||||
validConfigurationMappingModeSingleTable := Timestream{
|
||||
DatabaseName: tsDbName,
|
||||
MappingMode: ts.MappingModeSingleTable,
|
||||
MappingMode: MappingModeSingleTable,
|
||||
SingleTableName: testSingleTableName,
|
||||
SingleTableDimensionNameForTelegrafMeasurementName: testSingleTableDim,
|
||||
Log: testutil.Logger{},
|
||||
|
|
@ -126,18 +122,18 @@ func TestConnectValidatesConfigParameters(t *testing.T) {
|
|||
assertions.Nil(validConfigurationMappingModeSingleTable.Connect())
|
||||
|
||||
// create table arguments
|
||||
createTableNoMagneticRetention := ts.Timestream{
|
||||
createTableNoMagneticRetention := Timestream{
|
||||
DatabaseName: tsDbName,
|
||||
MappingMode: ts.MappingModeMultiTable,
|
||||
MappingMode: MappingModeMultiTable,
|
||||
CreateTableIfNotExists: true,
|
||||
Log: testutil.Logger{},
|
||||
}
|
||||
assertions.Contains(createTableNoMagneticRetention.Connect().Error(),
|
||||
"CreateTableMagneticStoreRetentionPeriodInDays")
|
||||
|
||||
createTableNoMemoryRetention := ts.Timestream{
|
||||
createTableNoMemoryRetention := Timestream{
|
||||
DatabaseName: tsDbName,
|
||||
MappingMode: ts.MappingModeMultiTable,
|
||||
MappingMode: MappingModeMultiTable,
|
||||
CreateTableIfNotExists: true,
|
||||
CreateTableMagneticStoreRetentionPeriodInDays: 3,
|
||||
Log: testutil.Logger{},
|
||||
|
|
@ -145,9 +141,9 @@ func TestConnectValidatesConfigParameters(t *testing.T) {
|
|||
assertions.Contains(createTableNoMemoryRetention.Connect().Error(),
|
||||
"CreateTableMemoryStoreRetentionPeriodInHours")
|
||||
|
||||
createTableValid := ts.Timestream{
|
||||
createTableValid := Timestream{
|
||||
DatabaseName: tsDbName,
|
||||
MappingMode: ts.MappingModeMultiTable,
|
||||
MappingMode: MappingModeMultiTable,
|
||||
CreateTableIfNotExists: true,
|
||||
CreateTableMagneticStoreRetentionPeriodInDays: 3,
|
||||
CreateTableMemoryStoreRetentionPeriodInHours: 3,
|
||||
|
|
@ -156,9 +152,9 @@ func TestConnectValidatesConfigParameters(t *testing.T) {
|
|||
assertions.Nil(createTableValid.Connect())
|
||||
|
||||
// describe table on start arguments
|
||||
describeTableInvoked := ts.Timestream{
|
||||
describeTableInvoked := Timestream{
|
||||
DatabaseName: tsDbName,
|
||||
MappingMode: ts.MappingModeMultiTable,
|
||||
MappingMode: MappingModeMultiTable,
|
||||
DescribeDatabaseOnStart: true,
|
||||
Log: testutil.Logger{},
|
||||
}
|
||||
|
|
@ -169,31 +165,30 @@ type mockTimestreamErrorClient struct {
|
|||
ErrorToReturnOnWriteRecords error
|
||||
}
|
||||
|
||||
func (m *mockTimestreamErrorClient) CreateTable(*timestreamwrite.CreateTableInput) (*timestreamwrite.CreateTableOutput, error) {
|
||||
func (m *mockTimestreamErrorClient) CreateTable(context.Context, *timestreamwrite.CreateTableInput, ...func(*timestreamwrite.Options)) (*timestreamwrite.CreateTableOutput, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (m *mockTimestreamErrorClient) WriteRecords(*timestreamwrite.WriteRecordsInput) (*timestreamwrite.WriteRecordsOutput, error) {
|
||||
func (m *mockTimestreamErrorClient) WriteRecords(context.Context, *timestreamwrite.WriteRecordsInput, ...func(*timestreamwrite.Options)) (*timestreamwrite.WriteRecordsOutput, error) {
|
||||
return nil, m.ErrorToReturnOnWriteRecords
|
||||
}
|
||||
func (m *mockTimestreamErrorClient) DescribeDatabase(*timestreamwrite.DescribeDatabaseInput) (*timestreamwrite.DescribeDatabaseOutput, error) {
|
||||
func (m *mockTimestreamErrorClient) DescribeDatabase(context.Context, *timestreamwrite.DescribeDatabaseInput, ...func(*timestreamwrite.Options)) (*timestreamwrite.DescribeDatabaseOutput, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func TestThrottlingErrorIsReturnedToTelegraf(t *testing.T) {
|
||||
assertions := assert.New(t)
|
||||
|
||||
ts.WriteFactory = func(credentialConfig *internalaws.CredentialConfig) (ts.WriteClient, error) {
|
||||
WriteFactory = func(credentialConfig *internalaws.CredentialConfig) (WriteClient, error) {
|
||||
return &mockTimestreamErrorClient{
|
||||
awserr.New(timestreamwrite.ErrCodeThrottlingException,
|
||||
"Throttling Test", nil),
|
||||
ErrorToReturnOnWriteRecords: &types.ThrottlingException{Message: aws.String("Throttling Test")},
|
||||
}, nil
|
||||
}
|
||||
plugin := ts.Timestream{
|
||||
MappingMode: ts.MappingModeMultiTable,
|
||||
|
||||
plugin := Timestream{
|
||||
MappingMode: MappingModeMultiTable,
|
||||
DatabaseName: tsDbName,
|
||||
Log: testutil.Logger{},
|
||||
}
|
||||
plugin.Connect()
|
||||
assertions.NoError(plugin.Connect())
|
||||
input := testutil.MustMetric(
|
||||
metricName1,
|
||||
map[string]string{"tag1": "value1"},
|
||||
|
|
@ -209,19 +204,18 @@ func TestThrottlingErrorIsReturnedToTelegraf(t *testing.T) {
|
|||
|
||||
func TestRejectedRecordsErrorResultsInMetricsBeingSkipped(t *testing.T) {
|
||||
assertions := assert.New(t)
|
||||
|
||||
ts.WriteFactory = func(credentialConfig *internalaws.CredentialConfig) (ts.WriteClient, error) {
|
||||
WriteFactory = func(credentialConfig *internalaws.CredentialConfig) (WriteClient, error) {
|
||||
return &mockTimestreamErrorClient{
|
||||
awserr.New(timestreamwrite.ErrCodeRejectedRecordsException,
|
||||
"RejectedRecords Test", nil),
|
||||
ErrorToReturnOnWriteRecords: &types.RejectedRecordsException{Message: aws.String("RejectedRecords Test")},
|
||||
}, nil
|
||||
}
|
||||
plugin := ts.Timestream{
|
||||
MappingMode: ts.MappingModeMultiTable,
|
||||
|
||||
plugin := Timestream{
|
||||
MappingMode: MappingModeMultiTable,
|
||||
DatabaseName: tsDbName,
|
||||
Log: testutil.Logger{},
|
||||
}
|
||||
plugin.Connect()
|
||||
assertions.NoError(plugin.Connect())
|
||||
input := testutil.MustMetric(
|
||||
metricName1,
|
||||
map[string]string{"tag1": "value1"},
|
||||
|
|
@ -271,7 +265,7 @@ func TestTransformMetricsSkipEmptyMetric(t *testing.T) {
|
|||
dimensions: map[string]string{testSingleTableDim: metricName1},
|
||||
measureValues: map[string]string{"value": "20"},
|
||||
})
|
||||
comparisonTest(t, ts.MappingModeSingleTable,
|
||||
comparisonTest(t, MappingModeSingleTable,
|
||||
[]telegraf.Metric{input1, input2, input3},
|
||||
[]*timestreamwrite.WriteRecordsInput{expectedResult1SingleTable, expectedResult2SingleTable})
|
||||
|
||||
|
|
@ -287,7 +281,7 @@ func TestTransformMetricsSkipEmptyMetric(t *testing.T) {
|
|||
dimensions: map[string]string{},
|
||||
measureValues: map[string]string{"value": "20"},
|
||||
})
|
||||
comparisonTest(t, ts.MappingModeMultiTable,
|
||||
comparisonTest(t, MappingModeMultiTable,
|
||||
[]telegraf.Metric{input1, input2, input3},
|
||||
[]*timestreamwrite.WriteRecordsInput{expectedResult1MultiTable, expectedResult2MultiTable})
|
||||
}
|
||||
|
|
@ -326,7 +320,7 @@ func TestTransformMetricsRequestsAboveLimitAreSplit(t *testing.T) {
|
|||
dimensions: map[string]string{"tag1": "value1", testSingleTableDim: metricName1},
|
||||
measureValues: map[string]string{"value_supported" + strconv.Itoa(maxRecordsInWriteRecordsCall+1): "10"},
|
||||
})
|
||||
comparisonTest(t, ts.MappingModeSingleTable,
|
||||
comparisonTest(t, MappingModeSingleTable,
|
||||
inputs,
|
||||
[]*timestreamwrite.WriteRecordsInput{expectedResult1SingleTable, expectedResult2SingleTable})
|
||||
|
||||
|
|
@ -342,7 +336,7 @@ func TestTransformMetricsRequestsAboveLimitAreSplit(t *testing.T) {
|
|||
dimensions: map[string]string{"tag1": "value1"},
|
||||
measureValues: map[string]string{"value_supported" + strconv.Itoa(maxRecordsInWriteRecordsCall+1): "10"},
|
||||
})
|
||||
comparisonTest(t, ts.MappingModeMultiTable,
|
||||
comparisonTest(t, MappingModeMultiTable,
|
||||
inputs,
|
||||
[]*timestreamwrite.WriteRecordsInput{expectedResult1MultiTable, expectedResult2MultiTable})
|
||||
}
|
||||
|
|
@ -378,7 +372,7 @@ func TestTransformMetricsDifferentDimensionsSameTimestampsAreWrittenSeparate(t *
|
|||
measureValues: map[string]string{"value_supported3": "30"},
|
||||
})
|
||||
|
||||
comparisonTest(t, ts.MappingModeSingleTable,
|
||||
comparisonTest(t, MappingModeSingleTable,
|
||||
[]telegraf.Metric{input1, input2},
|
||||
[]*timestreamwrite.WriteRecordsInput{expectedResult1SingleTable, expectedResult2SingleTable})
|
||||
|
||||
|
|
@ -395,7 +389,7 @@ func TestTransformMetricsDifferentDimensionsSameTimestampsAreWrittenSeparate(t *
|
|||
measureValues: map[string]string{"value_supported3": "30"},
|
||||
})
|
||||
|
||||
comparisonTest(t, ts.MappingModeMultiTable,
|
||||
comparisonTest(t, MappingModeMultiTable,
|
||||
[]telegraf.Metric{input1, input2},
|
||||
[]*timestreamwrite.WriteRecordsInput{expectedResult1MultiTable, expectedResult2MultiTable})
|
||||
}
|
||||
|
|
@ -431,7 +425,7 @@ func TestTransformMetricsSameDimensionsDifferentDimensionValuesAreWrittenSeparat
|
|||
measureValues: map[string]string{"value_supported1": "20"},
|
||||
})
|
||||
|
||||
comparisonTest(t, ts.MappingModeSingleTable,
|
||||
comparisonTest(t, MappingModeSingleTable,
|
||||
[]telegraf.Metric{input1, input2},
|
||||
[]*timestreamwrite.WriteRecordsInput{expectedResult1SingleTable, expectedResult2SingleTable})
|
||||
|
||||
|
|
@ -448,7 +442,7 @@ func TestTransformMetricsSameDimensionsDifferentDimensionValuesAreWrittenSeparat
|
|||
measureValues: map[string]string{"value_supported1": "20"},
|
||||
})
|
||||
|
||||
comparisonTest(t, ts.MappingModeMultiTable,
|
||||
comparisonTest(t, MappingModeMultiTable,
|
||||
[]telegraf.Metric{input1, input2},
|
||||
[]*timestreamwrite.WriteRecordsInput{expectedResult1MultiTable, expectedResult2MultiTable})
|
||||
}
|
||||
|
|
@ -484,7 +478,7 @@ func TestTransformMetricsSameDimensionsDifferentTimestampsAreWrittenSeparate(t *
|
|||
measureValues: map[string]string{"value_supported3": "30"},
|
||||
})
|
||||
|
||||
comparisonTest(t, ts.MappingModeSingleTable,
|
||||
comparisonTest(t, MappingModeSingleTable,
|
||||
[]telegraf.Metric{input1, input2},
|
||||
[]*timestreamwrite.WriteRecordsInput{expectedResult1SingleTable, expectedResult2SingleTable})
|
||||
|
||||
|
|
@ -501,7 +495,7 @@ func TestTransformMetricsSameDimensionsDifferentTimestampsAreWrittenSeparate(t *
|
|||
measureValues: map[string]string{"value_supported3": "30"},
|
||||
})
|
||||
|
||||
comparisonTest(t, ts.MappingModeMultiTable,
|
||||
comparisonTest(t, MappingModeMultiTable,
|
||||
[]telegraf.Metric{input1, input2},
|
||||
[]*timestreamwrite.WriteRecordsInput{expectedResult1MultiTable, expectedResult2MultiTable})
|
||||
}
|
||||
|
|
@ -531,7 +525,7 @@ func TestTransformMetricsSameDimensionsSameTimestampsAreWrittenTogether(t *testi
|
|||
measureValues: map[string]string{"value_supported1": "10", "value_supported2": "20", "value_supported3": "30"},
|
||||
})
|
||||
|
||||
comparisonTest(t, ts.MappingModeSingleTable,
|
||||
comparisonTest(t, MappingModeSingleTable,
|
||||
[]telegraf.Metric{input1, input2},
|
||||
[]*timestreamwrite.WriteRecordsInput{expectedResultSingleTable})
|
||||
|
||||
|
|
@ -542,7 +536,7 @@ func TestTransformMetricsSameDimensionsSameTimestampsAreWrittenTogether(t *testi
|
|||
measureValues: map[string]string{"value_supported1": "10", "value_supported2": "20", "value_supported3": "30"},
|
||||
})
|
||||
|
||||
comparisonTest(t, ts.MappingModeMultiTable,
|
||||
comparisonTest(t, MappingModeMultiTable,
|
||||
[]telegraf.Metric{input1, input2},
|
||||
[]*timestreamwrite.WriteRecordsInput{expectedResultMultiTable})
|
||||
}
|
||||
|
|
@ -578,7 +572,7 @@ func TestTransformMetricsDifferentMetricsAreWrittenToDifferentTablesInMultiTable
|
|||
measureValues: map[string]string{"value_supported3": "30"},
|
||||
})
|
||||
|
||||
comparisonTest(t, ts.MappingModeSingleTable,
|
||||
comparisonTest(t, MappingModeSingleTable,
|
||||
[]telegraf.Metric{input1, input2},
|
||||
[]*timestreamwrite.WriteRecordsInput{expectedResult1SingleTable, expectedResult2SingleTable})
|
||||
|
||||
|
|
@ -595,7 +589,7 @@ func TestTransformMetricsDifferentMetricsAreWrittenToDifferentTablesInMultiTable
|
|||
measureValues: map[string]string{"value_supported3": "30"},
|
||||
})
|
||||
|
||||
comparisonTest(t, ts.MappingModeMultiTable,
|
||||
comparisonTest(t, MappingModeMultiTable,
|
||||
[]telegraf.Metric{input1, input2},
|
||||
[]*timestreamwrite.WriteRecordsInput{expectedResult1MultiTable, expectedResult2MultiTable})
|
||||
}
|
||||
|
|
@ -616,7 +610,7 @@ func TestTransformMetricsUnsupportedFieldsAreSkipped(t *testing.T) {
|
|||
measureValues: map[string]string{"value_supported1": "10"},
|
||||
})
|
||||
|
||||
comparisonTest(t, ts.MappingModeSingleTable,
|
||||
comparisonTest(t, MappingModeSingleTable,
|
||||
[]telegraf.Metric{metricWithUnsupportedField},
|
||||
[]*timestreamwrite.WriteRecordsInput{expectedResultSingleTable})
|
||||
|
||||
|
|
@ -627,7 +621,7 @@ func TestTransformMetricsUnsupportedFieldsAreSkipped(t *testing.T) {
|
|||
measureValues: map[string]string{"value_supported1": "10"},
|
||||
})
|
||||
|
||||
comparisonTest(t, ts.MappingModeMultiTable,
|
||||
comparisonTest(t, MappingModeMultiTable,
|
||||
[]telegraf.Metric{metricWithUnsupportedField},
|
||||
[]*timestreamwrite.WriteRecordsInput{expectedResultMultiTable})
|
||||
}
|
||||
|
|
@ -637,10 +631,10 @@ func comparisonTest(t *testing.T,
|
|||
telegrafMetrics []telegraf.Metric,
|
||||
timestreamRecords []*timestreamwrite.WriteRecordsInput,
|
||||
) {
|
||||
var plugin ts.Timestream
|
||||
var plugin Timestream
|
||||
switch mappingMode {
|
||||
case ts.MappingModeSingleTable:
|
||||
plugin = ts.Timestream{
|
||||
case MappingModeSingleTable:
|
||||
plugin = Timestream{
|
||||
MappingMode: mappingMode,
|
||||
DatabaseName: tsDbName,
|
||||
|
||||
|
|
@ -648,8 +642,8 @@ func comparisonTest(t *testing.T,
|
|||
SingleTableDimensionNameForTelegrafMeasurementName: testSingleTableDim,
|
||||
Log: testutil.Logger{},
|
||||
}
|
||||
case ts.MappingModeMultiTable:
|
||||
plugin = ts.Timestream{
|
||||
case MappingModeMultiTable:
|
||||
plugin = Timestream{
|
||||
MappingMode: mappingMode,
|
||||
DatabaseName: tsDbName,
|
||||
Log: testutil.Logger{},
|
||||
|
|
@ -710,20 +704,20 @@ type SimpleInput struct {
|
|||
}
|
||||
|
||||
func buildExpectedRecords(i SimpleInput) *timestreamwrite.WriteRecordsInput {
|
||||
var tsDimensions []*timestreamwrite.Dimension
|
||||
var tsDimensions []types.Dimension
|
||||
for k, v := range i.dimensions {
|
||||
tsDimensions = append(tsDimensions, ×treamwrite.Dimension{
|
||||
tsDimensions = append(tsDimensions, types.Dimension{
|
||||
Name: aws.String(k),
|
||||
Value: aws.String(v),
|
||||
})
|
||||
}
|
||||
|
||||
var tsRecords []*timestreamwrite.Record
|
||||
var tsRecords []types.Record
|
||||
for k, v := range i.measureValues {
|
||||
tsRecords = append(tsRecords, ×treamwrite.Record{
|
||||
tsRecords = append(tsRecords, types.Record{
|
||||
MeasureName: aws.String(k),
|
||||
MeasureValue: aws.String(v),
|
||||
MeasureValueType: aws.String("DOUBLE"),
|
||||
MeasureValueType: types.MeasureValueTypeDouble,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -731,10 +725,10 @@ func buildExpectedRecords(i SimpleInput) *timestreamwrite.WriteRecordsInput {
|
|||
DatabaseName: aws.String(tsDbName),
|
||||
TableName: aws.String(i.tableName),
|
||||
Records: tsRecords,
|
||||
CommonAttributes: ×treamwrite.Record{
|
||||
CommonAttributes: &types.Record{
|
||||
Dimensions: tsDimensions,
|
||||
Time: aws.String(i.t),
|
||||
TimeUnit: aws.String(timeUnit),
|
||||
TimeUnit: types.TimeUnitSeconds,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue