Saturday, May 18, 2024
HomeJavaUtilizing the New Consumer-Aspect Metrics function within the AWS SDK for Java...

Utilizing the New Consumer-Aspect Metrics function within the AWS SDK for Java v2


We’re happy to announce the preview launch of the metrics module for AWS SDK for Java v2!

The metrics module allows you to accumulate and publish key efficiency metrics recorded robotically by the SDK as you employ it. These metrics will show you how to detect and diagnose points in your purposes like elevated API name latency and startup time. You’ll be able to even use the metrics to observe traits in your SDK utilization over time and tune the SDK for optimum efficiency and useful resource utilization.

Gathering and Publishing Metrics

Out of the field, you can begin gathering and publishing metrics to Amazon CloudWatch with just some traces of code:

First add cloudwatch-metric-publisher to your pom.xml:


<dependency>
    <groupId>software program.amazon.awssdk</groupId>
    <artifactId>cloudwatch-metric-publisher</artifactId>
    <model>2.13.52-PREVIEW</model>
</dependency>

Then, create and set the writer on the purchasers you need to publish metrics for:

CloudWatchMetricPublisher cloudWatchMetricPublisher = CloudWatchMetricPublisher.create();
S3Client s3 = S3Client.builder()
        .overrideConfiguration(o -> o.addMetricPublisher(cloudWatchMetricPublisher))
        .construct();

That’s all there may be to it. Now, as you employ the SDK, the CloudWatchMetricsPublisher will accumulate metrics within the background and hand them to the CloudWatch writer to be despatched to the CloudWatch service. You’ll be able to view and entry knowledge by way of the CloudWatch SDK or Console, or create dashboards and alarms to observe your SDK utilization.

 

Publishing Metrics to Customized Location

Should you’d wish to publish the SDK’s metrics to a spot aside from CloudWatch, we’ve acquired you lined. You’d must implement the MetricPublisher to publish metrics to a location of your alternative. A easy writer that logs the metrics to a file is just some traces of code away:

public class LoggingPublisher implements MetricPublisher {
personal static last Logger LOG = LoggerFactory.getLogger("software program.amazon.awssdk.instance.metrics");

@Override
public void publish(MetricCollection metricCollection) {
LOG.information("Metrics: {}", metricCollection);
}

@Override
public void shut() {
}
}

We’ll see under that because of the perception we get from the metrics recorded by the SDK, even a easy writer like this one could be a large assist.

Metrics in motion

Let’s think about we now have a easy software that downloads a file from S3, utilizing a given STS position.

public class TestApp {
    
    ...

    public static void foremost(String[] args) throws IOException {
        TestApp testApp = new TestApp();
        for (int i = 0; i < 3; ++i) {
            Recordsdata.delete(Paths.get(KEY));
            testApp.downloadToFile(BUCKET, KEY, ROLE_ARN);
        }
    }
}

Right here, the downloadToFile technique merely downloads the item utilizing the given position ARN:

public void downloadToFile(String bucket, String key, String roleArn) {
    AwsCredentialsProvider roleProvider = getRoleProvider(roleArn);
    GetObjectRequest request = createGetObjectRequest(bucket, key, roleProvider);
    s3.getObject(request, ResponseTransformer.toFile(Paths.get(key)));
}

As superior engineers, we wish this technique to be as environment friendly as doable. With out metrics nonetheless, it’s troublesome to know what we should be change or optimize to decrease the latency with out numerous digging. That is the place metrics involves the rescue.

Wanting on the output of our easy LoggingPublisher, we are able to see that a big portion of time is spent fetching credentials. The primary fetch is particularly lengthy at .84 seconds due to the extra overhead to ascertain a TCP connection to STS.

2020-06-25 17:22:55,363 [main] INFO  software program.amazon.awssdk.instance.metrics -  Metrics: MetricCollection(identify=ApiCall,
metrics=[MetricRecord(metric=ServiceId, value=S3), MetricRecord(metric=OperationName, value=GetObject),
MetricRecord(metric=CredentialsFetchDuration, value=PT0.841487422S), ...

020-06-25 17:22:55,739 [main] INFO  software program.amazon.awssdk.instance.metrics -  Metrics: MetricCollection(identify=ApiCall,
metrics=[MetricRecord(metric=ServiceId, value=S3), MetricRecord(metric=OperationName, value=GetObject),
MetricRecord(metric=CredentialsFetchDuration, value=PT0.325807755S), ...

2020-06-25 17:22:56,141 [main] INFO  software program.amazon.awssdk.instance.metrics -  Metrics: MetricCollection(identify=ApiCall,
metrics=[MetricRecord(metric=ServiceId, value=S3), MetricRecord(metric=OperationName, value=GetObject),
MetricRecord(metric=CredentialsFetchDuration, value=PT0.321498448S), ...

A cool thing about the StsAssumeRoleCredentialsProvider we’re using is that it actually caches credentials to avoid making unnecessary extra API requests. With this in mind, we can make a quick and simple optimization so that we can reuse the credentials provider rather than creating a new one for each S3 request:

public void downloadToFile(String bucket, String key, String roleArn) {
    AwsCredentialsProvider roleProvider = getCachedCredentialsProvider(roleArn);
    GetObjectRequest request = createGetObjectRequest(bucket, key, roleProvider);
    s3.getObject(request, ResponseTransformer.toFile(Paths.get(key)));
}

...

private AwsCredentialsProvider getCachedCredentialsProvider(String roleArn) {
    AwsCredentialsProvider cached = providerCache.get(roleArn);
    if (cached == null) {
        cached = getRoleProvider(roleArn);
        providerCache.put(roleArn, cached);
    }
    return cached;
} 

Looks good! Let’s run the code again to see how it performs now.

2020-06-25 17:27:47,045 [main] INFO  software program.amazon.awssdk.instance.metrics -  Metrics: MetricCollection(identify=ApiCall,
metrics=[MetricRecord(metric=ServiceId, value=S3), MetricRecord(metric=OperationName, value=GetObject),
MetricRecord(metric=CredentialsFetchDuration, value=PT0.953062913S), ...

2020-06-25 17:27:47,082 [main] INFO  software program.amazon.awssdk.instance.metrics -  Metrics: MetricCollection(identify=ApiCall,
metrics=[MetricRecord(metric=ServiceId, value=S3), MetricRecord(metric=OperationName, value=GetObject),
MetricRecord(metric=CredentialsFetchDuration, value=PT0.000030022S), ...

2020-06-25 17:27:47,115 [main] INFO  software program.amazon.awssdk.instance.metrics -  Metrics: MetricCollection(identify=ApiCall,
metrics=[MetricRecord(metric=ServiceId, value=S3), MetricRecord(metric=OperationName, value=GetObject),
MetricRecord(metric=CredentialsFetchDuration, value=PT0.000014517S), ...

We can see that the first request still takes a while to fetch credentials because it doesn’t have cached credentials yet. However, the following two requests spend virtually no time fetching credentials because we’re reusing the same provider that already has the credentials cached internally. Nice!

Conclusion

I hope that this short post and example have shown the utility of having detailed metrics to monitor, diagnose, and optimize SDK usage and performance, and invite you try it out for yourself! Head over to our GitHub where you can find the SDK and give feedback through the Issues page. Be sure to check out our developer guide as well which has more in depth information on using the metrics module.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments