1 /*
2 * Copyright 2010-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License").
5 * You may not use this file except in compliance with the License.
6 * A copy of the License is located at
7 *
8 * http://aws.amazon.com/apache2.0
9 *
10 * or in the "license" file accompanying this file. This file is distributed
11 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 * express or implied. See the License for the specific language governing
13 * permissions and limitations under the License.
14 */
15
16 package com.amazonaws.util;
17
18 import com.amazonaws.annotation.NotThreadSafe;
19 import com.amazonaws.metrics.MetricType;
20 import com.amazonaws.metrics.RequestMetricType;
21
22 import java.util.Collections;
23 import java.util.List;
24
25 /**
26 * Used as both a base class and a minimal support of AWS SDK request metrics.
27 * The base class of supporting AWS SDK request metrics.
28 * <p>
29 * In contrast to {@link AWSRequestMetricsFullSupport}, which is intended to be
30 * a full support of AWS SDK request metrics, this class only provides access to
31 * a {@link TimingInfo} instance that only has minimal support for start and end
32 * time (ie with no-ops for sub-event measurements) for backward compatibility
33 * reason. The other methods related to properties and counters in this class
34 * are effectively no-ops.
35 * <p>
36 * This class is instantiated instead of {@link AWSRequestMetricsFullSupport}
37 * when request metric collection is not required during a particular service
38 * request/response cycle.
39 */
40 @NotThreadSafe
41 public class AWSRequestMetrics {
42 /**
43 * If the class name is required for logging and metrics we should use this
44 * constant version instead of the expensive function call.
45 */
46 public static final String SIMPLE_NAME = AWSRequestMetrics.class.getSimpleName();
47
48 /**
49 * Predefined AWS SDK metric types general across all AWS clients. Client
50 * specific predefined metrics like S3 or DynamoDB are defined in the client
51 * specific packages.
52 */
53 public enum Field implements RequestMetricType {
54 AWSErrorCode,
55 AWSRequestID,
56 /**
57 * The specific request subtype, such as PutItemRequest, PutObjectRequest, etc.
58 */
59 RequestType,
60 BytesProcessed,
61 /**
62 * Total number of milliseconds taken for a request/response including
63 * the time taken to execute the request handlers, round trip to AWS,
64 * and the time taken to execute the response handlers.
65 */
66 ClientExecuteTime,
67 CredentialsRequestTime,
68
69 Exception,
70 /**
71 * Used to count and preserve the throttle related exceptions.
72 */
73 ThrottleException,
74 /**
75 * Number of milliseconds taken for a request/response round trip to AWS.
76 */
77 HttpRequestTime,
78 RedirectLocation,
79 RequestMarshallTime,
80 /**
81 * Number of milliseconds taken to sign a request.
82 */
83 RequestSigningTime,
84 /**
85 * Number of milliseconds taken to execute the response handler for a response from AWS.
86 */
87 ResponseProcessingTime,
88 /**
89 * Number of requests to AWS.
90 */
91 RequestCount,
92 /**
93 * Number of retries of AWS SDK sending a request to AWS.
94 */
95 RetryCount, // captured via the RequestCount since (RetryCount = RequestCount - 1)
96 /**
97 * Snapshot of currently consumed retry capacity.
98 */
99 RetryCapacityConsumed,
100 /**
101 * Number of retries that were not attempted due to retry throttling.
102 */
103 ThrottledRetryCount,
104 /**
105 * Number of retries of the underlying http client library in sending a
106 * request to AWS.
107 */
108 HttpClientRetryCount,
109 /**
110 * Time taken to send a request to AWS by the http client library,
111 * excluding any retry.
112 */
113 HttpClientSendRequestTime,
114 /**
115 * Time taken to receive a response from AWS by the http client library,
116 * excluding any retry.
117 */
118 HttpClientReceiveResponseTime,
119
120 /**
121 * Time taken for socket to read.
122 */
123 HttpSocketReadTime,
124
125 /**
126 * The number of idle persistent connections.
127 * <p>
128 * Reference: https://hc.apache
129 * .org/httpcomponents-core-ga/httpcore/apidocs/org/apache
130 * /http/pool/PoolStats.html
131 */
132 HttpClientPoolAvailableCount,
133 /**
134 * The number of persistent connections tracked by the connection
135 * manager currently being used to execute requests.
136 * <p>
137 * Reference: https://hc
138 * .apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache
139 * /http/pool/PoolStats.html
140 */
141 HttpClientPoolLeasedCount,
142 /**
143 * The number of connection requests being blocked awaiting a free
144 * connection.
145 * <p>
146 * Reference: https://hc.apache.org/httpcomponents-core-ga/httpcore
147 * /apidocs/org/apache/http/pool/PoolStats.html
148 */
149 HttpClientPoolPendingCount,
150 RetryPauseTime,
151 ServiceEndpoint,
152 ServiceName,
153 StatusCode, // The http status code
154 ;
155 }
156
157 protected final TimingInfo timingInfo;
158
159 /**
160 * This constructor should be used only in the case when AWS SDK metrics
161 * collector is disabled, when minimal timing info is supported for backward
162 * compatibility reasons.
163 *
164 * @see AWSRequestMetricsFullSupport
165 */
166 public AWSRequestMetrics() {
167 this.timingInfo = TimingInfo.startTiming();
168 }
169
170 protected AWSRequestMetrics(TimingInfo timingInfo) {
171 this.timingInfo = timingInfo;
172 }
173
174 public final TimingInfo getTimingInfo() {
175 return timingInfo;
176 }
177 /**
178 * Returns true if this metrics is enabled; false otherwise.
179 * Returns false by default.
180 * */
181 public boolean isEnabled() {
182 return false;
183 }
184
185 public void startEvent(String eventName) {}
186 public void startEvent(MetricType f) {}
187 public void endEvent(String eventName) {}
188 public void endEvent(MetricType f) {}
189
190 public void incrementCounter(String event) {}
191 public void incrementCounter(MetricType f) {}
192 /** Fluent API of {@link #incrementCounter(String)} */
193 public final AWSRequestMetrics incrementCounterWith(String event) {
194 incrementCounter(event);
195 return this;
196 }
197 /** Fluent API of {@link #incrementCounter(MetricType)} */
198 public final AWSRequestMetrics incrementCounterWith(MetricType f) {
199 incrementCounter(f);
200 return this;
201 }
202
203 public void setCounter(String counterName, long count) {}
204 public void setCounter(MetricType f, long count) {}
205 /** Fluent API of {@link #setCounter(String, long)} */
206 public final AWSRequestMetrics withCounter(String counterName, long count) {
207 setCounter(counterName, count);
208 return this;
209 }
210 /** Fluent API of {@link #setCounter(MetricType, long)} */
211 public final AWSRequestMetrics withCounter(MetricType f, long count) {
212 setCounter(f, count);
213 return this;
214 }
215
216 public void addProperty(String propertyName, Object value) {}
217 public void addProperty(MetricType f, Object value) {}
218 /** Fluent API of {@link #addProperty(String, Object)} */
219 public final AWSRequestMetrics addPropertyWith(String propertyName, Object value) {
220 addProperty(propertyName, value);
221 return this;
222 }
223 /** Fluent API of {@link #addProperty(MetricType, Object)} */
224 public final AWSRequestMetrics addPropertyWith(MetricType f, Object value) {
225 addProperty(f, value);
226 return this;
227 }
228
229 public void log() {}
230 public List<Object> getProperty(String propertyName){ return Collections.emptyList(); }
231 public List<Object> getProperty(MetricType f) { return Collections.emptyList(); }
232 }
233