0
# Metrics & Monitoring
1
2
The AWS Java SDK Core provides comprehensive metrics collection and monitoring capabilities, including client-side monitoring (CSM), request metrics, JMX integration, and custom metric collection for performance analysis and operational insights.
3
4
## Core Metrics Framework
5
6
### SDK Metrics
7
8
```java { .api }
9
// Main SDK metrics class
10
class AwsSdkMetrics {
11
// Global metrics control
12
public static boolean isDefaultMetricsEnabled();
13
public static void setDefaultMetricsEnabled(boolean enabled);
14
15
// Request metric collector management
16
public static RequestMetricCollector getRequestMetricCollector();
17
public static void setRequestMetricCollector(RequestMetricCollector requestMetricCollector);
18
19
// Machine metrics
20
public static boolean isMachineMetricExcluded(MetricType metricType);
21
public static void setMachineMetricExcluded(MetricType metricType, boolean exclude);
22
23
// Predefined collectors
24
public static final RequestMetricCollector NONE;
25
}
26
27
// Request metric collector interface
28
interface RequestMetricCollector {
29
void collectMetrics(Request<?> request, Response<?> response);
30
void collectMetrics(Request<?> request, Response<?> response, Exception exception);
31
32
// Default implementation
33
RequestMetricCollector NONE = new RequestMetricCollector() {
34
public void collectMetrics(Request<?> request, Response<?> response) {}
35
public void collectMetrics(Request<?> request, Response<?> response, Exception exception) {}
36
};
37
}
38
```
39
40
### Metric Types
41
42
```java { .api }
43
// Base metric type interface
44
interface MetricType {
45
String name();
46
}
47
48
// Request metric types enumeration
49
enum RequestMetricType implements MetricType {
50
// HTTP client metrics
51
HttpClientRetryCount("HttpClientRetryCount"),
52
HttpClientPoolAvailableCount("HttpClientPoolAvailableCount"),
53
HttpClientPoolLeasedCount("HttpClientPoolLeasedCount"),
54
HttpClientPoolPendingCount("HttpClientPoolPendingCount"),
55
56
// Timing metrics
57
HttpRequestTime("HttpRequestTime"),
58
HttpResponseTime("HttpResponseTime"),
59
ResponseProcessingTime("ResponseProcessingTime"),
60
RequestExecutionTime("RequestExecutionTime"),
61
RequestSigningTime("RequestSigningTime"),
62
63
// Data transfer metrics
64
RequestCount("RequestCount"),
65
RetryCount("RetryCount"),
66
ThrottledRetryCount("ThrottledRetryCount"),
67
ResponseSize("ResponseSize"),
68
RequestSize("RequestSize"),
69
70
// Error metrics
71
ClientExecuteTime("ClientExecuteTime"),
72
Exception("Exception"),
73
ThrottleException("ThrottleException");
74
75
private final String metricName;
76
77
RequestMetricType(String metricName) {
78
this.metricName = metricName;
79
}
80
81
public String name() {
82
return metricName;
83
}
84
}
85
86
// Service-specific metric type interface
87
interface ServiceMetricType extends MetricType {
88
String getServiceName();
89
}
90
91
// Simple service metric implementation
92
class SimpleServiceMetricType implements ServiceMetricType {
93
public SimpleServiceMetricType(String metricName, String serviceName);
94
public String name();
95
public String getServiceName();
96
}
97
98
// Throughput metric type interface
99
interface ThroughputMetricType extends MetricType {
100
// Marker interface for throughput metrics
101
}
102
103
// Simple throughput metric implementation
104
class SimpleThroughputMetricType implements ThroughputMetricType {
105
public SimpleThroughputMetricType(String metricName);
106
public String name();
107
}
108
```
109
110
## Metrics Administration
111
112
### Metrics Admin Interface
113
114
```java { .api }
115
// Administrative interface for metrics
116
interface MetricAdmin {
117
// Region management
118
String getRegion();
119
void setRegion(String region);
120
121
// Metric collection control
122
boolean isEnabled();
123
void setEnabled(boolean enabled);
124
125
// Queue management
126
Integer getRequestMetricQueueSize();
127
void setRequestMetricQueueSize(Integer requestMetricQueueSize);
128
129
// Predicate management
130
String getRequestMetricQueueSizePredicate();
131
void setRequestMetricQueueSizePredicate(String requestMetricQueueSizePredicate);
132
133
// Host management
134
String getMetricNameSpace();
135
void setMetricNameSpace(String metricNameSpace);
136
137
String getJvmMetricName();
138
void setJvmMetricName(String jvmMetricName);
139
140
String getHostMetricName();
141
void setHostMetricName(String hostMetricName);
142
143
// Credential provider
144
String getCredentialProvider();
145
void setCredentialProvider(String credentialProvider);
146
}
147
148
// JMX MBean for metrics administration
149
interface MetricAdminMBean extends MetricAdmin {
150
// Inherits all MetricAdmin methods for JMX exposure
151
}
152
153
// Service latency provider interface
154
interface ServiceLatencyProvider {
155
Double getServiceLatency(ServiceMetricType serviceMetricType);
156
int getSampleCount(ServiceMetricType serviceMetricType);
157
boolean isEnabled();
158
}
159
```
160
161
## Metrics Collection
162
163
### Specialized Metric Streams
164
165
```java { .api }
166
// Input stream with metrics collection
167
class MetricFilterInputStream extends FilterInputStream {
168
public MetricFilterInputStream(InputStream in);
169
170
public int read() throws IOException;
171
public int read(byte[] b, int off, int len) throws IOException;
172
public long skip(long n) throws IOException;
173
public void close() throws IOException;
174
175
// Metrics access
176
public long getBytesRead();
177
public long getReadCount();
178
}
179
180
// HTTP entity with metrics collection
181
class MetricInputStreamEntity extends InputStreamEntity {
182
public MetricInputStreamEntity(InputStream instream, long length);
183
public MetricInputStreamEntity(InputStream instream, long length, ContentType contentType);
184
185
public InputStream getContent() throws IOException;
186
public void writeTo(OutputStream outstream) throws IOException;
187
188
// Metrics access
189
public long getBytesRead();
190
public long getBytesWritten();
191
}
192
```
193
194
## Client-Side Monitoring (CSM)
195
196
### Monitoring Events
197
198
```java { .api }
199
// Base class for monitoring events
200
abstract class MonitoringEvent {
201
public abstract String toJsonString();
202
public abstract MonitoringEvent withTimestamp(Date timestamp);
203
204
public Date getTimestamp();
205
public String getVersion();
206
public String getUserAgent();
207
}
208
209
// Monitoring event for API calls
210
class ApiCallMonitoringEvent extends MonitoringEvent {
211
// Service information
212
public ApiCallMonitoringEvent withService(String service);
213
public ApiCallMonitoringEvent withApi(String api);
214
public ApiCallMonitoringEvent withVersion(int version);
215
public ApiCallMonitoringEvent withUserAgent(String userAgent);
216
public ApiCallMonitoringEvent withRegion(String region);
217
218
// Timing information
219
public ApiCallMonitoringEvent withTimestamp(Date timestamp);
220
public ApiCallMonitoringEvent withLatency(Integer latency);
221
222
// Attempt information
223
public ApiCallMonitoringEvent withAttemptCount(Integer attemptCount);
224
public ApiCallMonitoringEvent withMaxRetriesExceeded(Integer maxRetriesExceeded);
225
226
// Result information
227
public ApiCallMonitoringEvent withFinalHttpStatusCode(Integer finalHttpStatusCode);
228
public ApiCallMonitoringEvent withFinalAwsException(String finalAwsException);
229
public ApiCallMonitoringEvent withFinalAwsExceptionMessage(String finalAwsExceptionMessage);
230
public ApiCallMonitoringEvent withFinalSdkException(String finalSdkException);
231
public ApiCallMonitoringEvent withFinalSdkExceptionMessage(String finalSdkExceptionMessage);
232
233
// Getters
234
public String getService();
235
public String getApi();
236
public Integer getVersion();
237
public String getRegion();
238
public Integer getLatency();
239
public Integer getAttemptCount();
240
public Integer getMaxRetriesExceeded();
241
public Integer getFinalHttpStatusCode();
242
public String getFinalAwsException();
243
public String getFinalAwsExceptionMessage();
244
public String getFinalSdkException();
245
public String getFinalSdkExceptionMessage();
246
247
public String toJsonString();
248
}
249
250
// Monitoring event for API call attempts
251
class ApiCallAttemptMonitoringEvent extends MonitoringEvent {
252
// Service information
253
public ApiCallAttemptMonitoringEvent withService(String service);
254
public ApiCallAttemptMonitoringEvent withApi(String api);
255
public ApiCallAttemptMonitoringEvent withVersion(int version);
256
public ApiCallAttemptMonitoringEvent withUserAgent(String userAgent);
257
public ApiCallAttemptMonitoringEvent withRegion(String region);
258
259
// Timing information
260
public ApiCallAttemptMonitoringEvent withTimestamp(Date timestamp);
261
public ApiCallAttemptMonitoringEvent withLatency(Integer latency);
262
263
// Attempt information
264
public ApiCallAttemptMonitoringEvent withAttemptLatency(Integer attemptLatency);
265
public ApiCallAttemptMonitoringEvent withFqdn(String fqdn);
266
267
// HTTP information
268
public ApiCallAttemptMonitoringEvent withHttpStatusCode(Integer httpStatusCode);
269
public ApiCallAttemptMonitoringEvent withAwsException(String awsException);
270
public ApiCallAttemptMonitoringEvent withAwsExceptionMessage(String awsExceptionMessage);
271
public ApiCallAttemptMonitoringEvent withSdkException(String sdkException);
272
public ApiCallAttemptMonitoringEvent withSdkExceptionMessage(String sdkExceptionMessage);
273
274
// Getters
275
public String getService();
276
public String getApi();
277
public Integer getVersion();
278
public String getRegion();
279
public Integer getLatency();
280
public Integer getAttemptLatency();
281
public String getFqdn();
282
public Integer getHttpStatusCode();
283
public String getAwsException();
284
public String getAwsExceptionMessage();
285
public String getSdkException();
286
public String getSdkExceptionMessage();
287
288
public String toJsonString();
289
}
290
```
291
292
### CSM Configuration
293
294
```java { .api }
295
// Client-side monitoring configuration
296
class CsmConfiguration {
297
// Configuration parameters
298
public CsmConfiguration withEnabled(boolean enabled);
299
public CsmConfiguration withHost(String host);
300
public CsmConfiguration withPort(int port);
301
public CsmConfiguration withClientId(String clientId);
302
303
// Getters
304
public boolean isEnabled();
305
public String getHost();
306
public int getPort();
307
public String getClientId();
308
309
// Default values
310
public static final String DEFAULT_HOST = "127.0.0.1";
311
public static final int DEFAULT_PORT = 31000;
312
public static final boolean DEFAULT_ENABLED = false;
313
}
314
315
// CSM configuration provider interface
316
interface CsmConfigurationProvider {
317
CsmConfiguration getConfiguration() throws SdkClientException;
318
}
319
320
// CSM configuration provider chain
321
class CsmConfigurationProviderChain implements CsmConfigurationProvider {
322
public CsmConfigurationProviderChain(CsmConfigurationProvider... providers);
323
public CsmConfiguration getConfiguration() throws SdkClientException;
324
}
325
326
// Static CSM configuration provider
327
class StaticCsmConfigurationProvider implements CsmConfigurationProvider {
328
public StaticCsmConfigurationProvider(CsmConfiguration configuration);
329
public CsmConfiguration getConfiguration();
330
}
331
332
// Default CSM configuration provider chain
333
class DefaultCsmConfigurationProviderChain extends CsmConfigurationProviderChain {
334
public static DefaultCsmConfigurationProviderChain getInstance();
335
public CsmConfiguration getConfiguration() throws SdkClientException;
336
}
337
```
338
339
## Usage Examples
340
341
### Basic Metrics Collection
342
343
```java
344
import com.amazonaws.metrics.*;
345
import com.amazonaws.*;
346
347
// Enable default metrics collection
348
AwsSdkMetrics.setDefaultMetricsEnabled(true);
349
350
// Check if metrics are enabled
351
boolean metricsEnabled = AwsSdkMetrics.isDefaultMetricsEnabled();
352
System.out.println("Metrics enabled: " + metricsEnabled);
353
354
// Get current metric collector
355
RequestMetricCollector collector = AwsSdkMetrics.getRequestMetricCollector();
356
System.out.println("Current collector: " + collector.getClass().getSimpleName());
357
```
358
359
### Custom Request Metric Collector
360
361
```java
362
import com.amazonaws.metrics.*;
363
import com.amazonaws.*;
364
import java.util.concurrent.ConcurrentHashMap;
365
import java.util.concurrent.atomic.AtomicLong;
366
367
public class CustomMetricCollector implements RequestMetricCollector {
368
private final Map<MetricType, AtomicLong> counters = new ConcurrentHashMap<>();
369
private final Map<MetricType, AtomicLong> timings = new ConcurrentHashMap<>();
370
371
@Override
372
public void collectMetrics(Request<?> request, Response<?> response) {
373
// Collect successful request metrics
374
incrementCounter(RequestMetricType.RequestCount);
375
376
if (response != null && response.getAwsResponse() != null) {
377
// Track response processing time
378
Long processingTime = getTimingValue(request, RequestMetricType.ResponseProcessingTime);
379
if (processingTime != null) {
380
addTiming(RequestMetricType.ResponseProcessingTime, processingTime);
381
}
382
383
// Track HTTP response time
384
Long httpTime = getTimingValue(request, RequestMetricType.HttpResponseTime);
385
if (httpTime != null) {
386
addTiming(RequestMetricType.HttpResponseTime, httpTime);
387
}
388
}
389
}
390
391
@Override
392
public void collectMetrics(Request<?> request, Response<?> response, Exception exception) {
393
// Collect error metrics
394
incrementCounter(RequestMetricType.Exception);
395
396
if (exception instanceof AmazonServiceException) {
397
AmazonServiceException ase = (AmazonServiceException) exception;
398
if (ase.getErrorCode() != null && ase.getErrorCode().contains("Throttl")) {
399
incrementCounter(RequestMetricType.ThrottleException);
400
}
401
}
402
403
// Track retry count
404
Integer retryCount = getRetryCount(request);
405
if (retryCount != null && retryCount > 0) {
406
addTiming(RequestMetricType.RetryCount, retryCount.longValue());
407
}
408
}
409
410
private void incrementCounter(MetricType metricType) {
411
counters.computeIfAbsent(metricType, k -> new AtomicLong(0)).incrementAndGet();
412
}
413
414
private void addTiming(MetricType metricType, long value) {
415
timings.computeIfAbsent(metricType, k -> new AtomicLong(0)).addAndGet(value);
416
}
417
418
private Long getTimingValue(Request<?> request, MetricType metricType) {
419
// Extract timing values from request context
420
// Implementation depends on specific metric collection setup
421
return null;
422
}
423
424
private Integer getRetryCount(Request<?> request) {
425
// Extract retry count from request
426
// Implementation depends on request context setup
427
return null;
428
}
429
430
// Metrics reporting methods
431
public long getCounter(MetricType metricType) {
432
AtomicLong counter = counters.get(metricType);
433
return counter != null ? counter.get() : 0;
434
}
435
436
public long getTiming(MetricType metricType) {
437
AtomicLong timing = timings.get(metricType);
438
return timing != null ? timing.get() : 0;
439
}
440
441
public void printMetrics() {
442
System.out.println("=== Request Metrics ===");
443
444
for (Map.Entry<MetricType, AtomicLong> entry : counters.entrySet()) {
445
System.out.println(entry.getKey().name() + ": " + entry.getValue().get());
446
}
447
448
System.out.println("=== Timing Metrics ===");
449
for (Map.Entry<MetricType, AtomicLong> entry : timings.entrySet()) {
450
System.out.println(entry.getKey().name() + ": " + entry.getValue().get() + "ms");
451
}
452
}
453
}
454
455
// Use custom collector
456
CustomMetricCollector customCollector = new CustomMetricCollector();
457
AwsSdkMetrics.setRequestMetricCollector(customCollector);
458
459
// After some AWS operations...
460
customCollector.printMetrics();
461
```
462
463
### Service-Specific Metrics
464
465
```java
466
import com.amazonaws.metrics.*;
467
468
// Define service-specific metrics
469
ServiceMetricType s3PutObjectMetric = new SimpleServiceMetricType("PutObjectLatency", "S3");
470
ServiceMetricType dynamoQueryMetric = new SimpleServiceMetricType("QueryLatency", "DynamoDB");
471
ThroughputMetricType uploadThroughput = new SimpleThroughputMetricType("UploadThroughput");
472
473
// Custom service metric collector
474
public class ServiceMetricCollector implements RequestMetricCollector {
475
private final Map<ServiceMetricType, List<Double>> serviceLatencies = new ConcurrentHashMap<>();
476
477
@Override
478
public void collectMetrics(Request<?> request, Response<?> response) {
479
String serviceName = extractServiceName(request);
480
String operationName = extractOperationName(request);
481
Long latency = extractLatency(request);
482
483
if (serviceName != null && operationName != null && latency != null) {
484
ServiceMetricType metricType = new SimpleServiceMetricType(
485
operationName + "Latency", serviceName
486
);
487
488
serviceLatencies.computeIfAbsent(metricType, k -> new ArrayList<>())
489
.add(latency.doubleValue());
490
}
491
}
492
493
@Override
494
public void collectMetrics(Request<?> request, Response<?> response, Exception exception) {
495
// Handle error metrics for services
496
String serviceName = extractServiceName(request);
497
if (serviceName != null) {
498
ServiceMetricType errorMetric = new SimpleServiceMetricType(
499
"ErrorCount", serviceName
500
);
501
// Track error counts...
502
}
503
}
504
505
public double getAverageLatency(ServiceMetricType metricType) {
506
List<Double> latencies = serviceLatencies.get(metricType);
507
if (latencies == null || latencies.isEmpty()) {
508
return 0.0;
509
}
510
return latencies.stream().mapToDouble(Double::doubleValue).average().orElse(0.0);
511
}
512
513
public double getMaxLatency(ServiceMetricType metricType) {
514
List<Double> latencies = serviceLatencies.get(metricType);
515
if (latencies == null || latencies.isEmpty()) {
516
return 0.0;
517
}
518
return latencies.stream().mapToDouble(Double::doubleValue).max().orElse(0.0);
519
}
520
521
private String extractServiceName(Request<?> request) {
522
// Extract service name from request
523
return request.getServiceName();
524
}
525
526
private String extractOperationName(Request<?> request) {
527
// Extract operation name from request
528
return request.getOriginalRequest().getClass().getSimpleName();
529
}
530
531
private Long extractLatency(Request<?> request) {
532
// Extract latency from request timing
533
// Implementation depends on request context
534
return null;
535
}
536
}
537
```
538
539
### Client-Side Monitoring Setup
540
541
```java
542
import com.amazonaws.monitoring.*;
543
544
// Enable CSM via environment variables or system properties
545
// Environment: AWS_CSM_ENABLED=true, AWS_CSM_PORT=31000, AWS_CSM_HOST=127.0.0.1
546
547
// Programmatic CSM configuration
548
CsmConfiguration csmConfig = new CsmConfiguration()
549
.withEnabled(true)
550
.withHost("127.0.0.1")
551
.withPort(31000)
552
.withClientId("my-application");
553
554
// Static CSM configuration provider
555
CsmConfigurationProvider staticProvider = new StaticCsmConfigurationProvider(csmConfig);
556
557
// Use default provider chain (checks env vars, system properties, etc.)
558
CsmConfigurationProvider defaultProvider = DefaultCsmConfigurationProviderChain.getInstance();
559
560
try {
561
CsmConfiguration resolvedConfig = defaultProvider.getConfiguration();
562
System.out.println("CSM enabled: " + resolvedConfig.isEnabled());
563
System.out.println("CSM host: " + resolvedConfig.getHost());
564
System.out.println("CSM port: " + resolvedConfig.getPort());
565
} catch (SdkClientException e) {
566
System.err.println("CSM configuration error: " + e.getMessage());
567
}
568
```
569
570
### Monitoring Event Creation
571
572
```java
573
import com.amazonaws.monitoring.*;
574
import java.util.Date;
575
576
// Create API call monitoring event
577
ApiCallMonitoringEvent apiCallEvent = new ApiCallMonitoringEvent()
578
.withService("S3")
579
.withApi("PutObject")
580
.withVersion(1)
581
.withRegion("us-east-1")
582
.withTimestamp(new Date())
583
.withLatency(150)
584
.withAttemptCount(1)
585
.withFinalHttpStatusCode(200);
586
587
String apiCallJson = apiCallEvent.toJsonString();
588
System.out.println("API Call Event: " + apiCallJson);
589
590
// Create API call attempt monitoring event
591
ApiCallAttemptMonitoringEvent attemptEvent = new ApiCallAttemptMonitoringEvent()
592
.withService("S3")
593
.withApi("PutObject")
594
.withVersion(1)
595
.withRegion("us-east-1")
596
.withTimestamp(new Date())
597
.withLatency(150)
598
.withAttemptLatency(145)
599
.withFqdn("s3.amazonaws.com")
600
.withHttpStatusCode(200);
601
602
String attemptJson = attemptEvent.toJsonString();
603
System.out.println("Attempt Event: " + attemptJson);
604
```
605
606
### Metrics Stream Collection
607
608
```java
609
import com.amazonaws.metrics.*;
610
import java.io.*;
611
612
// Wrap input stream with metrics collection
613
InputStream originalStream = new FileInputStream("large-file.dat");
614
MetricFilterInputStream metricsStream = new MetricFilterInputStream(originalStream);
615
616
try {
617
// Read from the stream
618
byte[] buffer = new byte[8192];
619
int totalBytes = 0;
620
int bytesRead;
621
622
while ((bytesRead = metricsStream.read(buffer)) != -1) {
623
totalBytes += bytesRead;
624
// Process data...
625
}
626
627
// Get metrics after reading
628
long totalBytesRead = metricsStream.getBytesRead();
629
long readOperations = metricsStream.getReadCount();
630
631
System.out.println("Total bytes read: " + totalBytesRead);
632
System.out.println("Read operations: " + readOperations);
633
System.out.println("Average bytes per read: " + (totalBytesRead / readOperations));
634
635
} finally {
636
metricsStream.close();
637
}
638
639
// HTTP entity with metrics
640
InputStream entityStream = new ByteArrayInputStream("HTTP entity content".getBytes());
641
MetricInputStreamEntity metricsEntity = new MetricInputStreamEntity(entityStream, -1);
642
643
// Use in HTTP request...
644
ByteArrayOutputStream output = new ByteArrayOutputStream();
645
metricsEntity.writeTo(output);
646
647
System.out.println("Bytes written: " + metricsEntity.getBytesWritten());
648
```
649
650
### JMX Integration
651
652
```java
653
import com.amazonaws.metrics.*;
654
import javax.management.*;
655
import java.lang.management.ManagementFactory;
656
657
// Custom metrics MBean implementation
658
public class CustomMetricsMBean implements MetricAdminMBean {
659
private boolean enabled = true;
660
private String region = "us-east-1";
661
private Integer queueSize = 1000;
662
663
@Override
664
public String getRegion() { return region; }
665
666
@Override
667
public void setRegion(String region) { this.region = region; }
668
669
@Override
670
public boolean isEnabled() { return enabled; }
671
672
@Override
673
public void setEnabled(boolean enabled) {
674
this.enabled = enabled;
675
AwsSdkMetrics.setDefaultMetricsEnabled(enabled);
676
}
677
678
@Override
679
public Integer getRequestMetricQueueSize() { return queueSize; }
680
681
@Override
682
public void setRequestMetricQueueSize(Integer queueSize) {
683
this.queueSize = queueSize;
684
}
685
686
// Implement other MetricAdmin methods...
687
public String getRequestMetricQueueSizePredicate() { return null; }
688
public void setRequestMetricQueueSizePredicate(String predicate) {}
689
public String getMetricNameSpace() { return "AWS/SDK"; }
690
public void setMetricNameSpace(String nameSpace) {}
691
public String getJvmMetricName() { return "JVM"; }
692
public void setJvmMetricName(String name) {}
693
public String getHostMetricName() { return "Host"; }
694
public void setHostMetricName(String name) {}
695
public String getCredentialProvider() { return "DefaultProvider"; }
696
public void setCredentialProvider(String provider) {}
697
}
698
699
// Register MBean
700
try {
701
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
702
ObjectName objectName = new ObjectName("com.amazonaws.metrics:type=MetricsAdmin");
703
CustomMetricsMBean mbean = new CustomMetricsMBean();
704
705
if (!server.isRegistered(objectName)) {
706
server.registerMBean(mbean, objectName);
707
System.out.println("Metrics MBean registered successfully");
708
}
709
} catch (Exception e) {
710
System.err.println("Failed to register metrics MBean: " + e.getMessage());
711
}
712
```
713
714
## Best Practices
715
716
1. **Performance Impact**: Be aware that metrics collection adds overhead; enable only necessary metrics in production.
717
718
2. **Memory Management**: Implement bounded collections for metric storage to prevent memory leaks.
719
720
3. **Aggregation**: Aggregate metrics over time windows rather than storing individual data points.
721
722
4. **Sampling**: Use sampling for high-volume operations to reduce metrics overhead.
723
724
5. **Error Handling**: Ensure metrics collection failures don't impact application functionality.
725
726
6. **Storage**: Consider external metrics storage systems (CloudWatch, Prometheus) for production use.
727
728
7. **Monitoring**: Monitor the metrics system itself for health and performance.
729
730
8. **Security**: Protect sensitive information in metrics (don't log credentials or PII).
731
732
9. **Alerting**: Set up alerts based on key metrics thresholds for operational awareness.
733
734
10. **Documentation**: Document custom metrics for operational teams and monitoring setup.
735
736
The metrics and monitoring system provides comprehensive observability into AWS SDK operations, enabling performance optimization, troubleshooting, and operational insights for production applications.