Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CloudWatch.PutMetricData - Issue with StatisticSet & Value #332

Closed
jitcompile opened this issue Jul 31, 2015 · 2 comments
Closed

CloudWatch.PutMetricData - Issue with StatisticSet & Value #332

jitcompile opened this issue Jul 31, 2015 · 2 comments
Labels
guidance Question that needs advice or information.

Comments

@jitcompile
Copy link

StatisticValues and Value are mutually exclusive when trying the PutMetricData of cloudwatch. I've tried the following and all the 4 attempts have failed with the same exception:-

  • StatisticValues are set and Value is not set
  • StatisticValues are set and Value is set to aws.Float64(0)
  • StatisticValues are set and Value is set to aws.Float64(null) where null is initialized as below
    • var null float64 (since go zero values it, its same as previous attempt)
  • StatisticValues are set and Value is explicitly set to nil

In all the above cases, I receive the same exception

InvalidParameterCombination: The parameters MetricData.member.1.Value and MetricData.member.1.StatisticValues are mutually exclusive and you have specified both.

This is a code migration from .Net to golang. In .net sdk, I used to set the Value field to default(double) and it worked.

Here's the go code

    client := cloudwatch.New(a.config)
    input := cloudwatch.PutMetricDataInput{}
    input.Namespace = aws.String("test")

    instanceNameDimension := cloudwatch.Dimension{Name: aws.String("InstanceName"), Value: aws.String("i-abcd")}

    for _, stat := range stats {
        datum := cloudwatch.MetricDatum{MetricName: aws.String(stat.Name), Timestamp: aws.Time(stat.Timestamp), Unit: aws.String(stat.Unit)}
        datum.Dimensions = append(datum.Dimensions, &runIDDimension)
        datum.StatisticValues = &cloudwatch.StatisticSet{Maximum: aws.Float64(stat.Maximum), Minimum: aws.Float64(stat.Minimum), SampleCount: aws.Float64(stat.SampleCount), Sum: aws.Float64(stat.Sum)}
        input.MetricData = append(input.MetricData, &datum)
    }
    _, err := client.PutMetricData(&input)
@jasdel
Copy link
Contributor

jasdel commented Aug 4, 2015

Hi @jitcompile I'm having a little difficulty reproducing the issue you're encountering. The following example based on your above code is able to report metrics correctly to CloudWatch. Are you able to reproduce your issue using this example? Leaving the Value field unset (nil) should be the correct action.

package main

import (
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/service/cloudwatch"
    "log"
    "time"
)

type Stat struct {
    Name, Unit                         string
    Timestamp                          time.Time
    Minimum, Maximum, SampleCount, Sum float64
}

var stats = []Stat{
    {"Name", "Seconds", time.Now().Add(-1 * time.Second), 0, 5, 10, 100},
    {"Name", "Seconds", time.Now().Add(-2 * time.Second), 1, 5, 10, 100},
    {"Name", "Seconds", time.Now().Add(-3 * time.Second), 2, 5, 10, 100},
    {"Name", "Seconds", time.Now().Add(-3 * time.Second), 3, 5, 10, 100},
    {"Name", "Seconds", time.Now().Add(-4 * time.Second), 4, 6, 10, 100},
    {"Name", "Seconds", time.Now().Add(-5 * time.Second), 5, 7, 10, 100},
    {"Name", "Seconds", time.Now().Add(-6 * time.Second), 6, 8, 10, 100},
    {"Name", "Seconds", time.Now().Add(-7 * time.Second), 6, 9, 10, 100},
}

var runIDDimension = cloudwatch.Dimension{
    Name:  aws.String("DimName"),
    Value: aws.String("i-dcba"),
}

func main() {
    client := cloudwatch.New(nil)
    input := cloudwatch.PutMetricDataInput{}
    input.Namespace = aws.String("test")

    instanceNameDimension := cloudwatch.Dimension{
        Name:  aws.String("InstanceName"),
        Value: aws.String("i-abcd"),
    }

    for _, stat := range stats {
        datum := cloudwatch.MetricDatum{
            MetricName: aws.String(stat.Name),
            Timestamp:  aws.Time(stat.Timestamp),
            Unit:       aws.String(stat.Unit),
        }
        datum.Dimensions = append(datum.Dimensions, &instanceNameDimension)
        datum.StatisticValues = &cloudwatch.StatisticSet{
            Maximum:     aws.Float64(stat.Maximum),
            Minimum:     aws.Float64(stat.Minimum),
            SampleCount: aws.Float64(stat.SampleCount),
            Sum:         aws.Float64(stat.Sum),
        }
        input.MetricData = append(input.MetricData, &datum)
    }
    _, err := client.PutMetricData(&input)
    if err != nil {
        log.Fatalln(err)
    }
}

I suggest updating your config to print out wire logs of requests. With that we'll be able to see what the SDK is sending. You can use the following options to enable logging.

client := cloudwatch.New(aws.NewConfig().WithLogLevel(aws.LogDebugWithHTTPBody))
...

@jasdel jasdel added guidance Question that needs advice or information. response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. labels Aug 4, 2015
@jitcompile
Copy link
Author

I updated the version of sdk from 0.7.0 to 0.7.1 and it seems to work. Weird. Also it could be a combination of issues due to for-range and pointer of values. I've updated to 0.7.1 and using aws.String implementation, it works as expected. Thanks. I'm closing the issue.

@diehlaws diehlaws removed response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. labels Jan 30, 2019
skotambkar added a commit to skotambkar/aws-sdk-go that referenced this issue May 20, 2021
aws#337)

Updated shape marshal model to handle the empty map vs nil map behavior.
Adding a test case to assert behavior when a user sends an empty map vs nil map.

Fix aws#332
skotambkar pushed a commit to skotambkar/aws-sdk-go that referenced this issue May 20, 2021
Services
===
* Synced the V2 SDK with latest AWS service API definitions.
* Fixes [aws#341](aws/aws-sdk-go-v2#341)
* Fixes [aws#342](aws/aws-sdk-go-v2#342)

SDK Breaking Changes
===
* `aws`: Add default HTTP client instead of http.DefaultClient/Transport ([aws#315](aws/aws-sdk-go-v2#315))
  * Adds a new BuildableHTTPClient type to the SDK's aws package. The type uses the builder pattern with immutable changes. Modifications to the buildable client create copies of the client.  Adds a HTTPClient interface to the aws package that the SDK will use as an abstraction over the specific HTTP client implementation. The SDK will default to the BuildableHTTPClient, but a *http.Client can be also provided for custom configuration.  When the SDK's aws.Config.HTTPClient value is a BuildableHTTPClient the SDK will be able to use API client specific request timeout options.
  * Fixes [aws#279](aws/aws-sdk-go-v2#279)
  * Fixes [aws#269](aws/aws-sdk-go-v2#269)

SDK Enhancements
===
* `service/s3/s3manager`: Update S3 Upload Multipart location ([aws#324](aws/aws-sdk-go-v2#324))
  * Updates the Location returned value of S3 Upload's Multipart UploadOutput type to be consistent with single part upload URL. This update also brings the multipart upload Location inline with the S3 object URLs created by the SDK.
  * Fixes [aws#323](aws/aws-sdk-go-v2#323)
  * V2 Port [aws#2453](aws#2453)

SDK Bugs
===
* `private/model`: Handles empty map vs unset map behavior in send request ([aws#337](aws/aws-sdk-go-v2#337))
  * Updated shape marshal model to handle the empty map vs nil map behavior. Adding a test case to assert behavior when a user sends an empty map vs nil map.
  * Fix [aws#332](aws/aws-sdk-go-v2#332)
* `service/rds`: Fix presign URL for same region ([aws#331](aws/aws-sdk-go-v2#331))
  * Fixes RDS no-autopresign URL for same region issue for aws-sdk-go-v2. Solves the issue by making sure that the presigned URLs are not created, when the source and destination regions are the same. Added and updated the tests accordingly.
  * Fix [aws#271](aws/aws-sdk-go-v2#271)
* `private/protocola/json/jsonutil`: Fix Unmarshal map[string]bool ([aws#320](aws/aws-sdk-go-v2#320))
  * Fixes the JSON unmarshaling of maps of bools. The unmarshal case was missing the condition for bool value, in addition the bool pointer.
  * Fix [aws#319](aws/aws-sdk-go-v2#319)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
guidance Question that needs advice or information.
Projects
None yet
Development

No branches or pull requests

3 participants