Repository: aws/aws-cli

Issue:
Add support for high resolution metrics in CloudWatch
Cloudwatch API supports high-resolution metrics, AWS CLI does not.

https://aws.amazon.com/blogs/aws/new-high-resolution-custom-metrics-and-alarms-for-amazon-cloudwatch/


Discussion:
It does via `--metric-data`, but we haven't pulled it out to the top like we do with most of the other bits in there.

Resolving patch:
diff --git a/awscli/customizations/putmetricdata.py b/awscli/customizations/putmetricdata.py
--- a/awscli/customizations/putmetricdata.py
+++ b/awscli/customizations/putmetricdata.py
@@ -20,6 +20,7 @@
 * --value
 * --statistic-values
 * --unit
+* --storage-resolution
 
 """
 import decimal
@@ -30,8 +31,8 @@
 
 
 def register_put_metric_data(event_handler):
-    event_handler.register('building-argument-table.cloudwatch.put-metric-data',
-                           _promote_args)
+    event_handler.register(
+        'building-argument-table.cloudwatch.put-metric-data', _promote_args)
     event_handler.register(
         'operation-args-parsed.cloudwatch.put-metric-data',
         validate_mutually_exclusive_handler(
@@ -39,7 +40,7 @@ def register_put_metric_data(event_handler):
                               'dimensions', 'statistic_values']))
 
 
-def _promote_args(argument_table, **kwargs):
+def _promote_args(argument_table, operation_model, **kwargs):
     # We're providing top level params for metric-data.  This means
     # that metric-data is now longer a required arg.  We do need
     # to check that either metric-data or the complex args we've added
@@ -69,14 +70,25 @@ def _promote_args(argument_table, **kwargs):
             'The --dimensions argument further expands '
             'on the identity of a metric using a Name=Value '
             'pair, separated by commas, for example: '
-            '<code>--dimensions InstanceID=1-23456789 InstanceType=m1.small</code>. '
-            'Note that the <code>--dimensions</code> argument has a different '
-            'format when used in <code>get-metric-data</code>, where for the same example you would '
-            'use the format <code>--dimensions Name=InstanceID,Value=i-aaba32d4 Name=InstanceType,value=m1.small </code>.'))
+            '<code>--dimensions InstanceID=1-23456789 '
+            'InstanceType=m1.small</code>. Note that the '
+            '<code>--dimensions</code> argument has a different format when '
+            'used in <code>get-metric-data</code>, where for the same example '
+            'you would use the format <code>--dimensions '
+            'Name=InstanceID,Value=i-aaba32d4 '
+            'Name=InstanceType,value=m1.small </code>.'
+        )
+    )
     argument_table['statistic-values'] = PutMetricArgument(
         'statistic-values', help_text='A set of statistical values describing '
                                       'the metric.')
 
+    metric_data = operation_model.input_shape.members['MetricData'].member
+    storage_resolution = metric_data.members['StorageResolution']
+    argument_table['storage-resolution'] = PutMetricArgument(
+        'storage-resolution', help_text=storage_resolution.documentation
+    )
+
 
 def insert_first_element(name):
     def _wrap_add_to_params(func):
@@ -141,3 +153,7 @@ def _add_param_statistic_values(self, first_element, value):
             # convert these to a decimal value to preserve precision.
             statistics[key] = decimal.Decimal(value)
         first_element['StatisticValues'] = statistics
+
+    @insert_first_element('MetricData')
+    def _add_param_storage_resolution(self, first_element, value):
+        first_element['StorageResolution'] = int(value)


Test patch:
diff --git a/tests/functional/cloudwatch/test_put_metric_data.py b/tests/functional/cloudwatch/test_put_metric_data.py
--- a/tests/functional/cloudwatch/test_put_metric_data.py
+++ b/tests/functional/cloudwatch/test_put_metric_data.py
@@ -70,3 +70,21 @@ def test_using_shorthand_syntax(self):
             'Namespace': 'MyService'
         }
         self.assert_params_for_cmd(cmdline, expected)
+
+    def test_using_storage_resolution(self):
+        args = (
+            '--metric-name Foo '
+            '--namespace Bar '
+            '--value 5 '
+            '--storage-resolution 1 '
+        )
+        cmdline = self.prefix + args
+        expected = {
+            'MetricData': [{
+                'MetricName': 'Foo',
+                'Value': decimal.Decimal('5'),
+                'StorageResolution': 1
+            }],
+            'Namespace': 'Bar'
+        }
+        self.assert_params_for_cmd(cmdline, expected)