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