Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aws
GitHub Repository: aws/aws-cli
Path: blob/develop/awscli/customizations/putmetricdata.py
1566 views
1
# Copyright 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
#
3
# Licensed under the Apache License, Version 2.0 (the "License"). You
4
# may not use this file except in compliance with the License. A copy of
5
# the License is located at
6
#
7
# http://aws.amazon.com/apache2.0/
8
#
9
# or in the "license" file accompanying this file. This file is
10
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11
# ANY KIND, either express or implied. See the License for the specific
12
# language governing permissions and limitations under the License.
13
"""
14
This customization adds the following scalar parameters to the
15
cloudwatch put-metric-data operation:
16
17
* --metric-name
18
* --dimensions
19
* --timestamp
20
* --value
21
* --statistic-values
22
* --unit
23
* --storage-resolution
24
25
"""
26
import decimal
27
28
from awscli.arguments import CustomArgument
29
from awscli.utils import split_on_commas
30
from awscli.customizations.utils import validate_mutually_exclusive_handler
31
32
33
def register_put_metric_data(event_handler):
34
event_handler.register(
35
'building-argument-table.cloudwatch.put-metric-data', _promote_args)
36
event_handler.register(
37
'operation-args-parsed.cloudwatch.put-metric-data',
38
validate_mutually_exclusive_handler(
39
['metric_data'], ['metric_name', 'timestamp', 'unit', 'value',
40
'dimensions', 'statistic_values']))
41
42
43
def _promote_args(argument_table, operation_model, **kwargs):
44
# We're providing top level params for metric-data. This means
45
# that metric-data is now longer a required arg. We do need
46
# to check that either metric-data or the complex args we've added
47
# have been provided.
48
argument_table['metric-data'].required = False
49
50
argument_table['metric-name'] = PutMetricArgument(
51
'metric-name', help_text='The name of the metric.')
52
argument_table['timestamp'] = PutMetricArgument(
53
'timestamp', help_text='The time stamp used for the metric. '
54
'If not specified, the default value is '
55
'set to the time the metric data was '
56
'received.')
57
argument_table['unit'] = PutMetricArgument(
58
'unit', help_text='The unit of metric.')
59
argument_table['value'] = PutMetricArgument(
60
'value', help_text='The value for the metric. Although the --value '
61
'parameter accepts numbers of type Double, '
62
'Amazon CloudWatch truncates values with very '
63
'large exponents. Values with base-10 exponents '
64
'greater than 126 (1 x 10^126) are truncated. '
65
'Likewise, values with base-10 exponents less '
66
'than -130 (1 x 10^-130) are also truncated.')
67
68
argument_table['dimensions'] = PutMetricArgument(
69
'dimensions', help_text=(
70
'The --dimensions argument further expands '
71
'on the identity of a metric using a Name=Value '
72
'pair, separated by commas, for example: '
73
'<code>--dimensions InstanceID=1-23456789,InstanceType=m1.small'
74
'</code>. Note that the <code>--dimensions</code> argument has a '
75
'different format when used in <code>get-metric-data</code>, '
76
'where for the same example you would use the format '
77
'<code>--dimensions Name=InstanceID,Value=i-aaba32d4 '
78
'Name=InstanceType,value=m1.small </code>.'
79
)
80
)
81
argument_table['statistic-values'] = PutMetricArgument(
82
'statistic-values', help_text='A set of statistical values describing '
83
'the metric.')
84
85
metric_data = operation_model.input_shape.members['MetricData'].member
86
storage_resolution = metric_data.members['StorageResolution']
87
argument_table['storage-resolution'] = PutMetricArgument(
88
'storage-resolution', help_text=storage_resolution.documentation
89
)
90
91
92
def insert_first_element(name):
93
def _wrap_add_to_params(func):
94
def _add_to_params(self, parameters, value):
95
if value is None:
96
return
97
if name not in parameters:
98
# We're taking a shortcut here and assuming that the first
99
# element is a struct type, hence the default value of
100
# a dict. If this was going to be more general we'd need
101
# to have this parameterized, i.e. you pass in some sort of
102
# factory function that creates the initial starting value.
103
parameters[name] = [{}]
104
first_element = parameters[name][0]
105
return func(self, first_element, value)
106
return _add_to_params
107
return _wrap_add_to_params
108
109
110
class PutMetricArgument(CustomArgument):
111
def add_to_params(self, parameters, value):
112
method_name = '_add_param_%s' % self.name.replace('-', '_')
113
return getattr(self, method_name)(parameters, value)
114
115
@insert_first_element('MetricData')
116
def _add_param_metric_name(self, first_element, value):
117
first_element['MetricName'] = value
118
119
@insert_first_element('MetricData')
120
def _add_param_unit(self, first_element, value):
121
first_element['Unit'] = value
122
123
@insert_first_element('MetricData')
124
def _add_param_timestamp(self, first_element, value):
125
first_element['Timestamp'] = value
126
127
@insert_first_element('MetricData')
128
def _add_param_value(self, first_element, value):
129
# Use a Decimal to avoid loss in precision.
130
first_element['Value'] = decimal.Decimal(value)
131
132
@insert_first_element('MetricData')
133
def _add_param_dimensions(self, first_element, value):
134
# Dimensions needs a little more processing. We support
135
# the key=value,key2=value syntax so we need to parse
136
# that.
137
dimensions = []
138
for pair in split_on_commas(value):
139
key, value = pair.split('=')
140
dimensions.append({'Name': key, 'Value': value})
141
first_element['Dimensions'] = dimensions
142
143
@insert_first_element('MetricData')
144
def _add_param_statistic_values(self, first_element, value):
145
# StatisticValues is a struct type so we are parsing
146
# a csv keyval list into a dict.
147
statistics = {}
148
for pair in split_on_commas(value):
149
key, value = pair.split('=')
150
# There are four supported values: Maximum, Minimum, SampleCount,
151
# and Sum. All of them are documented as a type double so we can
152
# convert these to a decimal value to preserve precision.
153
statistics[key] = decimal.Decimal(value)
154
first_element['StatisticValues'] = statistics
155
156
@insert_first_element('MetricData')
157
def _add_param_storage_resolution(self, first_element, value):
158
first_element['StorageResolution'] = int(value)
159
160