CloudWatch 用SDK于 Java 2.x 的示例 - Amazon SDK for Java 2.x
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

CloudWatch 用SDK于 Java 2.x 的示例

以下代码示例向您展示了如何使用with来执行操作和实现常见场景 CloudWatch。 Amazon SDK for Java 2.x

基础知识是向您展示如何在服务中执行基本操作的代码示例。

操作是大型程序的代码摘录,必须在上下文中运行。您可以通过操作了解如何调用单个服务函数,还可以通过函数相关场景的上下文查看操作。

场景是向您展示如何通过在一个服务中调用多个函数或与其他 Amazon Web Services 服务结合来完成特定任务的代码示例。

每个示例都包含一个指向完整源代码的链接,您可以在其中找到有关如何在上下文中设置和运行代码的说明。

开始使用

以下代码示例展示了如何开始使用 CloudWatch。

SDK适用于 Java 2.x
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 Amazon 代码示例存储库中进行设置和运行。

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.cloudwatch.CloudWatchClient; import software.amazon.awssdk.services.cloudwatch.model.CloudWatchException; import software.amazon.awssdk.services.cloudwatch.model.ListMetricsRequest; import software.amazon.awssdk.services.cloudwatch.paginators.ListMetricsIterable; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class HelloService { public static void main(String[] args) { final String usage = """ Usage: <namespace>\s Where: namespace - The namespace to filter against (for example, AWS/EC2).\s """; if (args.length != 1) { System.out.println(usage); System.exit(1); } String namespace = args[0]; Region region = Region.US_EAST_1; CloudWatchClient cw = CloudWatchClient.builder() .region(region) .build(); listMets(cw, namespace); cw.close(); } public static void listMets(CloudWatchClient cw, String namespace) { try { ListMetricsRequest request = ListMetricsRequest.builder() .namespace(namespace) .build(); ListMetricsIterable listRes = cw.listMetricsPaginator(request); listRes.stream() .flatMap(r -> r.metrics().stream()) .forEach(metrics -> System.out.println(" Retrieved metric is: " + metrics.metricName())); } catch (CloudWatchException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } }
  • 有关API详细信息,请参阅 “Amazon SDK for Java 2.x API参考 ListMetrics” 中的。

基础知识

以下代码示例展示了如何:

  • 列出 CloudWatch 命名空间和指标。

  • 获取指标和预估账单的统计数据。

  • 创建和更新控制面板。

  • 创建数据并将数据添加到指标。

  • 创建并触发告警,然后查看告警历史记录。

  • 添加异常检测器

  • 获取指标映像,然后清理资源。

SDK适用于 Java 2.x
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 Amazon 代码示例存储库中进行设置和运行。

运行演示 CloudWatch 功能的交互式场景。

import org.slf4j.Logger; import org.slf4j.LoggerFactory; import software.amazon.awssdk.services.cloudwatch.model.CloudWatchException; import software.amazon.awssdk.services.cloudwatch.model.DashboardInvalidInputErrorException; import software.amazon.awssdk.services.cloudwatch.model.DeleteAlarmsResponse; import software.amazon.awssdk.services.cloudwatch.model.DeleteAnomalyDetectorResponse; import software.amazon.awssdk.services.cloudwatch.model.DeleteDashboardsResponse; import software.amazon.awssdk.services.cloudwatch.model.Dimension; import software.amazon.awssdk.services.cloudwatch.model.GetMetricStatisticsResponse; import software.amazon.awssdk.services.cloudwatch.model.LimitExceededException; import software.amazon.awssdk.services.cloudwatch.model.PutDashboardResponse; import software.amazon.awssdk.services.cloudwatch.model.PutMetricDataResponse; import java.io.IOException; import java.util.ArrayList; import java.util.Scanner; import java.util.concurrent.CompletableFuture; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html * * To enable billing metrics and statistics for this example, make sure billing * alerts are enabled for your account: * https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/monitor_estimated_charges_with_cloudwatch.html#turning_on_billing_metrics * * This Java code example performs the following tasks: * * 1. List available namespaces from Amazon CloudWatch. * 2. List available metrics within the selected Namespace. * 3. Get statistics for the selected metric over the last day. * 4. Get CloudWatch estimated billing for the last week. * 5. Create a new CloudWatch dashboard with metrics. * 6. List dashboards using a paginator. * 7. Create a new custom metric by adding data for it. * 8. Add the custom metric to the dashboard. * 9. Create an alarm for the custom metric. * 10. Describe current alarms. * 11. Get current data for the new custom metric. * 12. Push data into the custom metric to trigger the alarm. * 13. Check the alarm state using the action DescribeAlarmsForMetric. * 14. Get alarm history for the new alarm. * 15. Add an anomaly detector for the custom metric. * 16. Describe current anomaly detectors. * 17. Get a metric image for the custom metric. * 18. Clean up the Amazon CloudWatch resources. */ public class CloudWatchScenario { public static final String DASHES = new String(new char[80]).replace("\0", "-"); static CloudWatchActions cwActions = new CloudWatchActions(); private static final Logger logger = LoggerFactory.getLogger(CloudWatchScenario.class); static Scanner scanner = new Scanner(System.in); public static void main(String[] args) throws Throwable { final String usage = """ Usage: <myDate> <costDateWeek> <dashboardName> <dashboardJson> <dashboardAdd> <settings> <metricImage> \s Where: myDate - The start date to use to get metric statistics. (For example, 2023-01-11T18:35:24.00Z.)\s costDateWeek - The start date to use to get AWS/Billing statistics. (For example, 2023-01-11T18:35:24.00Z.)\s dashboardName - The name of the dashboard to create.\s dashboardJson - The location of a JSON file to use to create a dashboard. (See jsonWidgets.json in javav2/example_code/cloudwatch.)\s dashboardAdd - The location of a JSON file to use to update a dashboard. (See CloudDashboard.json in javav2/example_code/cloudwatch.)\s settings - The location of a JSON file from which various values are read. (See settings.json in javav2/example_code/cloudwatch.)\s metricImage - The location of a BMP file that is used to create a graph.\s """; if (args.length != 7) { logger.info(usage); return; } String myDate = args[0]; String costDateWeek = args[1]; String dashboardName = args[2]; String dashboardJson = args[3]; String dashboardAdd = args[4]; String settings = args[5]; String metricImage = args[6]; logger.info(DASHES); logger.info("Welcome to the Amazon CloudWatch Basics scenario."); logger.info(""" Amazon CloudWatch is a comprehensive monitoring and observability service provided by Amazon Web Services (AWS). It is designed to help you monitor your AWS resources, applications, and services, as well as on-premises resources, in real-time. CloudWatch collects and tracks various types of data, including metrics, logs, and events, from your AWS and on-premises resources. It allows you to set alarms and automatically respond to changes in your environment, enabling you to quickly identify and address issues before they impact your applications or services. With CloudWatch, you can gain visibility into your entire infrastructure, from the cloud to the edge, and use this information to make informed decisions and optimize your resource utilization. This scenario guides you through how to perform Amazon CloudWatch tasks by using the AWS SDK for Java v2. Let's get started... """); waitForInputToContinue(scanner); try { runScenario(myDate, costDateWeek, dashboardName, dashboardJson, dashboardAdd, settings, metricImage); } catch (RuntimeException e) { e.printStackTrace(); } logger.info(DASHES); } private static void runScenario(String myDate, String costDateWeek, String dashboardName, String dashboardJson, String dashboardAdd, String settings, String metricImage ) throws Throwable { Double dataPoint = Double.parseDouble("10.0"); logger.info(DASHES); logger.info(""" 1. List at least five available unique namespaces from Amazon CloudWatch. Select one from the list. """); String selectedNamespace; String selectedMetrics; int num; try { CompletableFuture<ArrayList<String>> future = cwActions.listNameSpacesAsync(); ArrayList<String> list = future.join(); for (int z = 0; z < 5; z++) { int index = z + 1; logger.info(" " + index + ". {}", list.get(z)); } num = Integer.parseInt(scanner.nextLine()); if (1 <= num && num <= 5) { selectedNamespace = list.get(num - 1); } else { logger.info("You did not select a valid option."); return; } logger.info("You selected {}", selectedNamespace); } catch (RuntimeException rt) { Throwable cause = rt.getCause(); if (cause instanceof CloudWatchException cwEx) { logger.info("CloudWatch error occurred: Error message: {}, Error code {}", cwEx.getMessage(), cwEx.awsErrorDetails().errorCode()); } else { logger.info("An unexpected error occurred: " + rt.getMessage()); } throw cause; } waitForInputToContinue(scanner); logger.info(DASHES); logger.info(DASHES); logger.info("2. List available metrics within the selected namespace."); logger.info(""" A metric is a measure of the performance or health of your AWS resources, applications, or custom resources. Metrics are the basic building blocks of CloudWatch and provide data points that represent a specific aspect of your system or application over time. Select a metric from the list. """); Dimension myDimension = null; try { CompletableFuture<ArrayList<String>> future = cwActions.listMetsAsync(selectedNamespace); ArrayList<String> metList = future.join(); logger.info("Metrics successfully retrieved. Total metrics: {}", metList.size()); for (int z = 0; z < 5; z++) { int index = z + 1; logger.info(" " + index + ". " + metList.get(z)); } num = Integer.parseInt(scanner.nextLine()); if (1 <= num && num <= 5) { selectedMetrics = metList.get(num - 1); } else { logger.info("You did not select a valid option."); return; } logger.info("You selected {}", selectedMetrics); } catch (RuntimeException rt) { Throwable cause = rt.getCause(); if (cause instanceof CloudWatchException cwEx) { logger.info("CloudWatch error occurred: Error message: {}, Error code {}", cwEx.getMessage(), cwEx.awsErrorDetails().errorCode()); } else { logger.info("An unexpected error occurred: {}", rt.getMessage()); } throw cause; } try { myDimension = cwActions.getSpecificMetAsync(selectedNamespace).join(); logger.info("Metric statistics successfully retrieved and displayed."); } catch (RuntimeException rt) { Throwable cause = rt.getCause(); if (cause instanceof CloudWatchException cwEx) { logger.info("CloudWatch error occurred: Error message: {}, Error code {}", cwEx.getMessage(), cwEx.awsErrorDetails().errorCode()); } else { logger.info("An unexpected error occurred: {}", rt.getMessage()); } throw cause; } waitForInputToContinue(scanner); logger.info(DASHES); logger.info(DASHES); logger.info("3. Get statistics for the selected metric over the last day."); logger.info(""" Statistics refer to the various mathematical calculations that can be performed on the collected metrics to derive meaningful insights. Statistics provide a way to summarize and analyze the data collected for a specific metric over a specified time period. """); waitForInputToContinue(scanner); String metricOption = ""; ArrayList<String> statTypes = new ArrayList<>(); statTypes.add("SampleCount"); statTypes.add("Average"); statTypes.add("Sum"); statTypes.add("Minimum"); statTypes.add("Maximum"); for (int t = 0; t < 5; t++) { logger.info(" " + (t + 1) + ". {}", statTypes.get(t)); } logger.info("Select a metric statistic by entering a number from the preceding list:"); num = Integer.parseInt(scanner.nextLine()); if (1 <= num && num <= 5) { metricOption = statTypes.get(num - 1); } else { logger.info("You did not select a valid option."); return; } logger.info("You selected " + metricOption); waitForInputToContinue(scanner); try { CompletableFuture<GetMetricStatisticsResponse> future = cwActions.getAndDisplayMetricStatisticsAsync(selectedNamespace, selectedMetrics, metricOption, myDate, myDimension); future.join(); logger.info("Metric statistics retrieved successfully."); } catch (RuntimeException rt) { Throwable cause = rt.getCause(); if (cause instanceof CloudWatchException cwEx) { logger.info("CloudWatch error occurred: Error message: {}, Error code {}", cwEx.getMessage(), cwEx.awsErrorDetails().errorCode()); } else { logger.info("An unexpected error occurred: {}", rt.getMessage()); } throw cause; } waitForInputToContinue(scanner); logger.info(DASHES); logger.info(DASHES); logger.info("4. Get CloudWatch estimated billing for the last week."); waitForInputToContinue(scanner); try { CompletableFuture<GetMetricStatisticsResponse> future = cwActions.getMetricStatisticsAsync(costDateWeek); future.join(); logger.info("Metric statistics successfully retrieved and displayed."); } catch (RuntimeException rt) { Throwable cause = rt.getCause(); if (cause instanceof CloudWatchException cwEx) { logger.info("CloudWatch error occurred: Error message: {}, Error code {}", cwEx.getMessage(), cwEx.awsErrorDetails().errorCode()); } else { logger.info("An unexpected error occurred: {}", rt.getMessage()); } throw cause; } waitForInputToContinue(scanner); logger.info(DASHES); logger.info(DASHES); logger.info("5. Create a new CloudWatch dashboard with metrics."); waitForInputToContinue(scanner); try { CompletableFuture<PutDashboardResponse> future = cwActions.createDashboardWithMetricsAsync(dashboardName, dashboardJson); future.join(); } catch (RuntimeException | IOException rt) { Throwable cause = rt.getCause(); if (cause instanceof DashboardInvalidInputErrorException cwEx) { logger.info("Invalid CloudWatch data. Error message: {}, Error code {}", cwEx.getMessage(), cwEx.awsErrorDetails().errorCode()); } else { logger.info("An unexpected error occurred: {}", rt.getMessage()); } throw cause; } waitForInputToContinue(scanner); logger.info(DASHES); logger.info(DASHES); logger.info("6. List dashboards using a paginator."); waitForInputToContinue(scanner); try { CompletableFuture<Void> future = cwActions.listDashboardsAsync(); future.join(); } catch (RuntimeException rt) { Throwable cause = rt.getCause(); if (cause instanceof CloudWatchException cwEx) { logger.info("CloudWatch error occurred: Error message: {}, Error code {}", cwEx.getMessage(), cwEx.awsErrorDetails().errorCode()); } else { logger.info("An unexpected error occurred: {}", rt.getMessage()); } throw cause; } waitForInputToContinue(scanner); logger.info(DASHES); logger.info(DASHES); logger.info("7. Create a new custom metric by adding data to it."); logger.info(""" The primary benefit of using a custom metric in Amazon CloudWatch is the ability to monitor and collect data that is specific to your application or infrastructure. """); waitForInputToContinue(scanner); try { CompletableFuture<PutMetricDataResponse> future = cwActions.createNewCustomMetricAsync(dataPoint); future.join(); } catch (RuntimeException rt) { Throwable cause = rt.getCause(); if (cause instanceof CloudWatchException cwEx) { logger.info("CloudWatch error occurred: Error message: {}, Error code {}", cwEx.getMessage(), cwEx.awsErrorDetails().errorCode()); } else { logger.info("An unexpected error occurred: {}", rt.getMessage()); } throw cause; } waitForInputToContinue(scanner); logger.info(DASHES); logger.info(DASHES); logger.info("8. Add an additional metric to the dashboard."); waitForInputToContinue(scanner); try { CompletableFuture<PutDashboardResponse> future = cwActions.addMetricToDashboardAsync(dashboardAdd, dashboardName); future.join(); } catch (RuntimeException rt) { Throwable cause = rt.getCause(); if (cause instanceof DashboardInvalidInputErrorException cwEx) { logger.info("Invalid CloudWatch data. Error message: {}, Error code {}", cwEx.getMessage(), cwEx.awsErrorDetails().errorCode()); } else { logger.info("An unexpected error occurred: {}", rt.getMessage()); } throw cause; } logger.info(DASHES); logger.info(DASHES); logger.info("9. Create an alarm for the custom metric."); waitForInputToContinue(scanner); String alarmName = "" ; try { CompletableFuture<String> future = cwActions.createAlarmAsync(settings); alarmName = future.join(); } catch (RuntimeException rt) { Throwable cause = rt.getCause(); if (cause instanceof LimitExceededException cwEx) { logger.info("The quota for alarms has been reached: Error message: {}, Error code {}", cwEx.getMessage(), cwEx.awsErrorDetails().errorCode()); } else { logger.info("An unexpected error occurred: {}", rt.getMessage()); } throw cause; } waitForInputToContinue(scanner); logger.info(DASHES); logger.info(DASHES); logger.info("10. Describe ten current alarms."); waitForInputToContinue(scanner); try { CompletableFuture<Void> future = cwActions.describeAlarmsAsync(); future.join(); } catch (RuntimeException rt) { Throwable cause = rt.getCause(); if (cause instanceof CloudWatchException cwEx) { logger.info("CloudWatch error occurred: Error message: {}, Error code {}", cwEx.getMessage(), cwEx.awsErrorDetails().errorCode()); } else { logger.info("An unexpected error occurred: {}", rt.getMessage()); } throw cause; } waitForInputToContinue(scanner); logger.info(DASHES); logger.info(DASHES); logger.info("11. Get current data for new custom metric."); try { CompletableFuture<Void> future = cwActions.getCustomMetricDataAsync(settings); future.join(); } catch (RuntimeException rt) { Throwable cause = rt.getCause(); if (cause instanceof CloudWatchException cwEx) { logger.info("CloudWatch error occurred: Error message: {}, Error code {}", cwEx.getMessage(), cwEx.awsErrorDetails().errorCode()); } else { logger.info("An unexpected error occurred: {}", rt.getMessage()); } throw cause; } waitForInputToContinue(scanner); logger.info(DASHES); logger.info(DASHES); logger.info("12. Push data into the custom metric to trigger the alarm."); waitForInputToContinue(scanner); try { CompletableFuture<PutMetricDataResponse> future = cwActions.addMetricDataForAlarmAsync(settings); future.join(); } catch (RuntimeException rt) { Throwable cause = rt.getCause(); if (cause instanceof CloudWatchException cwEx) { logger.info("CloudWatch error occurred: Error message: {}, Error code {}", cwEx.getMessage(), cwEx.awsErrorDetails().errorCode()); } else { logger.info("An unexpected error occurred: {}", rt.getMessage()); } throw cause; } waitForInputToContinue(scanner); logger.info(DASHES); logger.info(DASHES); logger.info("13. Check the alarm state using the action DescribeAlarmsForMetric."); waitForInputToContinue(scanner); try { CompletableFuture<Void> future = cwActions.checkForMetricAlarmAsync(settings); future.join(); } catch (RuntimeException rt) { Throwable cause = rt.getCause(); if (cause instanceof CloudWatchException cwEx) { logger.info("CloudWatch error occurred: Error message: {}, Error code {}", cwEx.getMessage(), cwEx.awsErrorDetails().errorCode()); } else { logger.info("An unexpected error occurred: {}", rt.getMessage()); } throw cause; } waitForInputToContinue(scanner); logger.info(DASHES); logger.info(DASHES); logger.info("14. Get alarm history for the new alarm."); waitForInputToContinue(scanner); try { CompletableFuture<Void> future = cwActions.getAlarmHistoryAsync(settings, myDate); future.join(); } catch (RuntimeException rt) { Throwable cause = rt.getCause(); if (cause instanceof CloudWatchException cwEx) { logger.info("CloudWatch error occurred: Error message: {}, Error code {}", cwEx.getMessage(), cwEx.awsErrorDetails().errorCode()); } else { logger.info("An unexpected error occurred: {}", rt.getMessage()); } throw cause; } logger.info(DASHES); logger.info(DASHES); logger.info("15. Add an anomaly detector for the custom metric."); logger.info(""" An anomaly detector is a feature that automatically detects unusual patterns or deviations in your monitored metrics. It uses machine learning algorithms to analyze the historical behavior of your metrics and establish a baseline. The anomaly detector then compares the current metric values against this baseline and identifies any anomalies or outliers that may indicate potential issues or unexpected changes in your system's performance or behavior. """); waitForInputToContinue(scanner); try { CompletableFuture<Void> future = cwActions.addAnomalyDetectorAsync(settings); future.join(); } catch (RuntimeException rt) { Throwable cause = rt.getCause(); if (cause instanceof CloudWatchException cwEx) { logger.info("CloudWatch error occurred: Error message: {}, Error code {}", cwEx.getMessage(), cwEx.awsErrorDetails().errorCode()); } else { logger.info("An unexpected error occurred: {}", rt.getMessage()); } throw cause; } waitForInputToContinue(scanner); logger.info(DASHES); logger.info(DASHES); logger.info("16. Describe current anomaly detectors."); waitForInputToContinue(scanner); try { CompletableFuture<Void> future = cwActions.describeAnomalyDetectorsAsync(settings); future.join(); } catch (RuntimeException rt) { Throwable cause = rt.getCause(); if (cause instanceof CloudWatchException cwEx) { logger.info("CloudWatch error occurred: Error message: {}, Error code {}", cwEx.getMessage(), cwEx.awsErrorDetails().errorCode()); } else { logger.info("An unexpected error occurred: {}", rt.getMessage()); } throw cause; } waitForInputToContinue(scanner); logger.info(DASHES); logger.info(DASHES); logger.info("17. Get a metric image for the custom metric."); try { CompletableFuture<Void> future = cwActions.downloadAndSaveMetricImageAsync(metricImage); future.join(); } catch (RuntimeException rt) { Throwable cause = rt.getCause(); if (cause instanceof CloudWatchException cwEx) { logger.info("CloudWatch error occurred: Error message: {}, Error code {}", cwEx.getMessage(), cwEx.awsErrorDetails().errorCode()); } else { logger.info("An unexpected error occurred: {}", rt.getMessage()); } throw cause; } logger.info(DASHES); logger.info(DASHES); logger.info("18. Clean up the Amazon CloudWatch resources."); try { logger.info(". Delete the Dashboard."); waitForInputToContinue(scanner); CompletableFuture<DeleteDashboardsResponse> future = cwActions.deleteDashboardAsync(dashboardName); future.join(); } catch (RuntimeException rt) { Throwable cause = rt.getCause(); if (cause instanceof CloudWatchException cwEx) { logger.info("CloudWatch error occurred: Error message: {}, Error code {}", cwEx.getMessage(), cwEx.awsErrorDetails().errorCode()); } else { logger.info("An unexpected error occurred: {}", rt.getMessage()); } throw cause; } try { logger.info("Delete the alarm."); waitForInputToContinue(scanner); CompletableFuture<DeleteAlarmsResponse> future = cwActions.deleteCWAlarmAsync(alarmName); future.join(); } catch (RuntimeException rt) { Throwable cause = rt.getCause(); if (cause instanceof CloudWatchException cwEx) { logger.info("CloudWatch error occurred: Error message: {}, Error code {}", cwEx.getMessage(), cwEx.awsErrorDetails().errorCode()); } else { logger.info("An unexpected error occurred: {}", rt.getMessage()); } throw cause; } try { logger.info("Delete the anomaly detector."); waitForInputToContinue(scanner); CompletableFuture<DeleteAnomalyDetectorResponse> future = cwActions.deleteAnomalyDetectorAsync(settings); future.join(); } catch (RuntimeException rt) { Throwable cause = rt.getCause(); if (cause instanceof CloudWatchException cwEx) { logger.info("CloudWatch error occurred: Error message: {}, Error code {}", cwEx.getMessage(), cwEx.awsErrorDetails().errorCode()); } else { logger.info("An unexpected error occurred: {}", rt.getMessage()); } throw cause; } waitForInputToContinue(scanner); logger.info(DASHES); logger.info(DASHES); logger.info("The Amazon CloudWatch example scenario is complete."); logger.info(DASHES); } private static void waitForInputToContinue(Scanner scanner) { while (true) { logger.info(""); logger.info("Enter 'c' followed by <ENTER> to continue:"); String input = scanner.nextLine(); if (input.trim().equalsIgnoreCase("c")) { logger.info("Continuing with the program..."); logger.info(""); break; } else { // Handle invalid input. logger.info("Invalid input. Please try again."); } } } }

CloudWatch SDK方法的包装器类。

public class CloudWatchActions { private static CloudWatchAsyncClient cloudWatchAsyncClient; private static final Logger logger = LoggerFactory.getLogger(CloudWatchActions.class); /** * Retrieves an asynchronous CloudWatch client instance. * * <p> * This method ensures that the CloudWatch client is initialized with the following configurations: * <ul> * <li>Maximum concurrency: 100</li> * <li>Connection timeout: 60 seconds</li> * <li>Read timeout: 60 seconds</li> * <li>Write timeout: 60 seconds</li> * <li>API call timeout: 2 minutes</li> * <li>API call attempt timeout: 90 seconds</li> * <li>Retry strategy: STANDARD</li> * </ul> * </p> * * @return the asynchronous CloudWatch client instance */ private static CloudWatchAsyncClient getAsyncClient() { if (cloudWatchAsyncClient == null) { SdkAsyncHttpClient httpClient = NettyNioAsyncHttpClient.builder() .maxConcurrency(100) .connectionTimeout(Duration.ofSeconds(60)) .readTimeout(Duration.ofSeconds(60)) .writeTimeout(Duration.ofSeconds(60)) .build(); ClientOverrideConfiguration overrideConfig = ClientOverrideConfiguration.builder() .apiCallTimeout(Duration.ofMinutes(2)) .apiCallAttemptTimeout(Duration.ofSeconds(90)) .retryStrategy(RetryMode.STANDARD) .build(); cloudWatchAsyncClient = CloudWatchAsyncClient.builder() .httpClient(httpClient) .overrideConfiguration(overrideConfig) .build(); } return cloudWatchAsyncClient; } /** * Deletes an Anomaly Detector. * * @param fileName the name of the file containing the Anomaly Detector configuration * @return a CompletableFuture that represents the asynchronous deletion of the Anomaly Detector */ public CompletableFuture<DeleteAnomalyDetectorResponse> deleteAnomalyDetectorAsync(String fileName) { CompletableFuture<JsonNode> readFileFuture = CompletableFuture.supplyAsync(() -> { try { JsonParser parser = new JsonFactory().createParser(new File(fileName)); return new ObjectMapper().readTree(parser); // Return the root node } catch (IOException e) { throw new RuntimeException("Failed to read or parse the file", e); } }); return readFileFuture.thenCompose(rootNode -> { String customMetricNamespace = rootNode.findValue("customMetricNamespace").asText(); String customMetricName = rootNode.findValue("customMetricName").asText(); SingleMetricAnomalyDetector singleMetricAnomalyDetector = SingleMetricAnomalyDetector.builder() .metricName(customMetricName) .namespace(customMetricNamespace) .stat("Maximum") .build(); DeleteAnomalyDetectorRequest request = DeleteAnomalyDetectorRequest.builder() .singleMetricAnomalyDetector(singleMetricAnomalyDetector) .build(); return getAsyncClient().deleteAnomalyDetector(request); }).whenComplete((result, exception) -> { if (exception != null) { throw new RuntimeException("Failed to delete the Anomaly Detector", exception); } else { logger.info("Successfully deleted the Anomaly Detector."); } }); } /** * Deletes a CloudWatch alarm. * * @param alarmName the name of the alarm to be deleted * @return a {@link CompletableFuture} representing the asynchronous operation to delete the alarm * the {@link DeleteAlarmsResponse} is returned when the operation completes successfully, * or a {@link RuntimeException} is thrown if the operation fails */ public CompletableFuture<DeleteAlarmsResponse> deleteCWAlarmAsync(String alarmName) { DeleteAlarmsRequest request = DeleteAlarmsRequest.builder() .alarmNames(alarmName) .build(); return getAsyncClient().deleteAlarms(request) .whenComplete((response, exception) -> { if (exception != null) { throw new RuntimeException("Failed to delete the alarm:{} " + alarmName, exception); } else { logger.info("Successfully deleted alarm {} ", alarmName); } }); } /** * Deletes the specified dashboard. * * @param dashboardName the name of the dashboard to be deleted * @return a {@link CompletableFuture} representing the asynchronous operation of deleting the dashboard * @throws RuntimeException if the dashboard deletion fails */ public CompletableFuture<DeleteDashboardsResponse> deleteDashboardAsync(String dashboardName) { DeleteDashboardsRequest dashboardsRequest = DeleteDashboardsRequest.builder() .dashboardNames(dashboardName) .build(); return getAsyncClient().deleteDashboards(dashboardsRequest) .whenComplete((response, exception) -> { if (exception != null) { throw new RuntimeException("Failed to delete the dashboard: " + dashboardName, exception); } else { logger.info("{} was successfully deleted.", dashboardName); } }); } /** * Retrieves and saves a custom metric image to a file. * * @param fileName the name of the file to save the metric image to * @return a {@link CompletableFuture} that completes when the image has been saved to the file */ public CompletableFuture<Void> downloadAndSaveMetricImageAsync(String fileName) { logger.info("Getting Image data for custom metric."); String myJSON = """ { "title": "Example Metric Graph", "view": "timeSeries", "stacked ": false, "period": 10, "width": 1400, "height": 600, "metrics": [ [ "AWS/Billing", "EstimatedCharges", "Currency", "USD" ] ] } """; GetMetricWidgetImageRequest imageRequest = GetMetricWidgetImageRequest.builder() .metricWidget(myJSON) .build(); return getAsyncClient().getMetricWidgetImage(imageRequest) .thenCompose(response -> { SdkBytes sdkBytes = response.metricWidgetImage(); byte[] bytes = sdkBytes.asByteArray(); return CompletableFuture.runAsync(() -> { try { File outputFile = new File(fileName); try (FileOutputStream outputStream = new FileOutputStream(outputFile)) { outputStream.write(bytes); } } catch (IOException e) { throw new RuntimeException("Failed to write image to file", e); } }); }) .whenComplete((result, exception) -> { if (exception != null) { throw new RuntimeException("Error getting and saving metric image", exception); } else { logger.info("Image data saved successfully to {}", fileName); } }); } /** * Describes the anomaly detectors based on the specified JSON file. * * @param fileName the name of the JSON file containing the custom metric namespace and name * @return a {@link CompletableFuture} that completes when the anomaly detectors have been described * @throws RuntimeException if there is a failure during the operation, such as when reading or parsing the JSON file, * or when describing the anomaly detectors */ public CompletableFuture<Void> describeAnomalyDetectorsAsync(String fileName) { CompletableFuture<JsonNode> readFileFuture = CompletableFuture.supplyAsync(() -> { try { JsonParser parser = new JsonFactory().createParser(new File(fileName)); return new ObjectMapper().readTree(parser); } catch (IOException e) { throw new RuntimeException("Failed to read or parse the file", e); } }); return readFileFuture.thenCompose(rootNode -> { try { String customMetricNamespace = rootNode.findValue("customMetricNamespace").asText(); String customMetricName = rootNode.findValue("customMetricName").asText(); DescribeAnomalyDetectorsRequest detectorsRequest = DescribeAnomalyDetectorsRequest.builder() .maxResults(10) .metricName(customMetricName) .namespace(customMetricNamespace) .build(); return getAsyncClient().describeAnomalyDetectors(detectorsRequest).thenAccept(response -> { List<AnomalyDetector> anomalyDetectorList = response.anomalyDetectors(); for (AnomalyDetector detector : anomalyDetectorList) { logger.info("Metric name: {} ", detector.singleMetricAnomalyDetector().metricName()); logger.info("State: {} ", detector.stateValue()); } }); } catch (RuntimeException e) { throw new RuntimeException("Failed to describe anomaly detectors", e); } }).whenComplete((result, exception) -> { if (exception != null) { throw new RuntimeException("Error describing anomaly detectors", exception); } }); } /** * Adds an anomaly detector for the given file. * * @param fileName the name of the file containing the anomaly detector configuration * @return a {@link CompletableFuture} that completes when the anomaly detector has been added */ public CompletableFuture<Void> addAnomalyDetectorAsync(String fileName) { CompletableFuture<JsonNode> readFileFuture = CompletableFuture.supplyAsync(() -> { try { JsonParser parser = new JsonFactory().createParser(new File(fileName)); return new ObjectMapper().readTree(parser); // Return the root node } catch (IOException e) { throw new RuntimeException("Failed to read or parse the file", e); } }); return readFileFuture.thenCompose(rootNode -> { try { String customMetricNamespace = rootNode.findValue("customMetricNamespace").asText(); String customMetricName = rootNode.findValue("customMetricName").asText(); SingleMetricAnomalyDetector singleMetricAnomalyDetector = SingleMetricAnomalyDetector.builder() .metricName(customMetricName) .namespace(customMetricNamespace) .stat("Maximum") .build(); PutAnomalyDetectorRequest anomalyDetectorRequest = PutAnomalyDetectorRequest.builder() .singleMetricAnomalyDetector(singleMetricAnomalyDetector) .build(); return getAsyncClient().putAnomalyDetector(anomalyDetectorRequest).thenAccept(response -> { logger.info("Added anomaly detector for metric {}", customMetricName); }); } catch (Exception e) { throw new RuntimeException("Failed to create anomaly detector", e); } }).whenComplete((result, exception) -> { if (exception != null) { throw new RuntimeException("Error adding anomaly detector", exception); } }); } /** * Retrieves the alarm history for a given alarm name and date range. * * @param fileName the path to the JSON file containing the alarm name * @param date the date to start the alarm history search (in the format "yyyy-MM-dd'T'HH:mm:ss'Z'") * @return a {@code CompletableFuture<Void>} that completes when the alarm history has been retrieved and processed */ public CompletableFuture<Void> getAlarmHistoryAsync(String fileName, String date) { CompletableFuture<String> readFileFuture = CompletableFuture.supplyAsync(() -> { try { JsonParser parser = new JsonFactory().createParser(new File(fileName)); com.fasterxml.jackson.databind.JsonNode rootNode = new ObjectMapper().readTree(parser); return rootNode.findValue("exampleAlarmName").asText(); // Return alarmName from the JSON file } catch (IOException e) { throw new RuntimeException("Failed to read or parse the file", e); } }); // Use the alarm name to describe alarm history with a paginator. return readFileFuture.thenCompose(alarmName -> { try { Instant start = Instant.parse(date); Instant endDate = Instant.now(); DescribeAlarmHistoryRequest historyRequest = DescribeAlarmHistoryRequest.builder() .startDate(start) .endDate(endDate) .alarmName(alarmName) .historyItemType(HistoryItemType.ACTION) .build(); // Use the paginator to paginate through alarm history pages. DescribeAlarmHistoryPublisher historyPublisher = getAsyncClient().describeAlarmHistoryPaginator(historyRequest); CompletableFuture<Void> future = historyPublisher .subscribe(response -> response.alarmHistoryItems().forEach(item -> { logger.info("History summary: {}", item.historySummary()); logger.info("Timestamp: {}", item.timestamp()); })) .whenComplete((result, exception) -> { if (exception != null) { logger.error("Error occurred while getting alarm history: " + exception.getMessage(), exception); } else { logger.info("Successfully retrieved all alarm history."); } }); // Return the future to the calling code for further handling return future; } catch (Exception e) { throw new RuntimeException("Failed to process alarm history", e); } }).whenComplete((result, exception) -> { if (exception != null) { throw new RuntimeException("Error completing alarm history processing", exception); } }); } /** * Checks for a metric alarm in AWS CloudWatch. * * @param fileName the name of the file containing the JSON configuration for the custom metric * @return a {@link CompletableFuture} that completes when the check for the metric alarm is complete */ public CompletableFuture<Void> checkForMetricAlarmAsync(String fileName) { CompletableFuture<String> readFileFuture = CompletableFuture.supplyAsync(() -> { try { JsonParser parser = new JsonFactory().createParser(new File(fileName)); com.fasterxml.jackson.databind.JsonNode rootNode = new ObjectMapper().readTree(parser); return rootNode.toString(); // Return JSON as a string for further processing } catch (IOException e) { throw new RuntimeException("Failed to read file", e); } }); return readFileFuture.thenCompose(jsonContent -> { try { com.fasterxml.jackson.databind.JsonNode rootNode = new ObjectMapper().readTree(jsonContent); String customMetricNamespace = rootNode.findValue("customMetricNamespace").asText(); String customMetricName = rootNode.findValue("customMetricName").asText(); DescribeAlarmsForMetricRequest metricRequest = DescribeAlarmsForMetricRequest.builder() .metricName(customMetricName) .namespace(customMetricNamespace) .build(); return checkForAlarmAsync(metricRequest, customMetricName, 10); } catch (IOException e) { throw new RuntimeException("Failed to parse JSON content", e); } }).whenComplete((result, exception) -> { if (exception != null) { throw new RuntimeException("Error checking metric alarm", exception); } }); } // Recursive method to check for the alarm. /** * Checks for the existence of an alarm asynchronously for the specified metric. * * @param metricRequest the request to describe the alarms for the specified metric * @param customMetricName the name of the custom metric to check for an alarm * @param retries the number of retries to perform if no alarm is found * @return a {@link CompletableFuture} that completes when an alarm is found or the maximum number of retries has been reached */ private static CompletableFuture<Void> checkForAlarmAsync(DescribeAlarmsForMetricRequest metricRequest, String customMetricName, int retries) { if (retries == 0) { return CompletableFuture.completedFuture(null).thenRun(() -> logger.info("No Alarm state found for {} after 10 retries.", customMetricName) ); } return (getAsyncClient().describeAlarmsForMetric(metricRequest).thenCompose(response -> { if (response.hasMetricAlarms()) { logger.info("Alarm state found for {}", customMetricName); return CompletableFuture.completedFuture(null); // Alarm found, complete the future } else { return CompletableFuture.runAsync(() -> { try { Thread.sleep(20000); logger.info("."); } catch (InterruptedException e) { throw new RuntimeException("Interrupted while waiting to retry", e); } }).thenCompose(v -> checkForAlarmAsync(metricRequest, customMetricName, retries - 1)); // Recursive call } })); } /** * Adds metric data for an alarm asynchronously. * * @param fileName the name of the JSON file containing the metric data * @return a CompletableFuture that asynchronously returns the PutMetricDataResponse */ public CompletableFuture<PutMetricDataResponse> addMetricDataForAlarmAsync(String fileName) { CompletableFuture<String> readFileFuture = CompletableFuture.supplyAsync(() -> { try { JsonParser parser = new JsonFactory().createParser(new File(fileName)); com.fasterxml.jackson.databind.JsonNode rootNode = new ObjectMapper().readTree(parser); return rootNode.toString(); // Return JSON as a string for further processing } catch (IOException e) { throw new RuntimeException("Failed to read file", e); } }); return readFileFuture.thenCompose(jsonContent -> { try { com.fasterxml.jackson.databind.JsonNode rootNode = new ObjectMapper().readTree(jsonContent); String customMetricNamespace = rootNode.findValue("customMetricNamespace").asText(); String customMetricName = rootNode.findValue("customMetricName").asText(); Instant instant = Instant.now(); // Create MetricDatum objects. MetricDatum datum1 = MetricDatum.builder() .metricName(customMetricName) .unit(StandardUnit.NONE) .value(1001.00) .timestamp(instant) .build(); MetricDatum datum2 = MetricDatum.builder() .metricName(customMetricName) .unit(StandardUnit.NONE) .value(1002.00) .timestamp(instant) .build(); List<MetricDatum> metricDataList = new ArrayList<>(); metricDataList.add(datum1); metricDataList.add(datum2); // Build the PutMetricData request. PutMetricDataRequest request = PutMetricDataRequest.builder() .namespace(customMetricNamespace) .metricData(metricDataList) .build(); // Send the request asynchronously. return getAsyncClient().putMetricData(request); } catch (IOException e) { CompletableFuture<PutMetricDataResponse> failedFuture = new CompletableFuture<>(); failedFuture.completeExceptionally(new RuntimeException("Failed to parse JSON content", e)); return failedFuture; } }).whenComplete((response, exception) -> { if (exception != null) { logger.error("Failed to put metric data: " + exception.getMessage(), exception); } else { logger.info("Added metric values for metric."); } }); } /** * Retrieves custom metric data from the AWS CloudWatch service. * * @param fileName the name of the file containing the custom metric information * @return a {@link CompletableFuture} that completes when the metric data has been retrieved */ public CompletableFuture<Void> getCustomMetricDataAsync(String fileName) { CompletableFuture<String> readFileFuture = CompletableFuture.supplyAsync(() -> { try { // Read values from the JSON file. JsonParser parser = new JsonFactory().createParser(new File(fileName)); com.fasterxml.jackson.databind.JsonNode rootNode = new ObjectMapper().readTree(parser); return rootNode.toString(); // Return JSON as a string for further processing } catch (IOException e) { throw new RuntimeException("Failed to read file", e); } }); return readFileFuture.thenCompose(jsonContent -> { try { // Parse the JSON string to extract relevant values. com.fasterxml.jackson.databind.JsonNode rootNode = new ObjectMapper().readTree(jsonContent); String customMetricNamespace = rootNode.findValue("customMetricNamespace").asText(); String customMetricName = rootNode.findValue("customMetricName").asText(); // Set the current time and date range for metric query. Instant nowDate = Instant.now(); long hours = 1; long minutes = 30; Instant endTime = nowDate.plus(hours, ChronoUnit.HOURS).plus(minutes, ChronoUnit.MINUTES); Metric met = Metric.builder() .metricName(customMetricName) .namespace(customMetricNamespace) .build(); MetricStat metStat = MetricStat.builder() .stat("Maximum") .period(60) // Assuming period in seconds .metric(met) .build(); MetricDataQuery dataQuery = MetricDataQuery.builder() .metricStat(metStat) .id("foo2") .returnData(true) .build(); List<MetricDataQuery> dq = new ArrayList<>(); dq.add(dataQuery); GetMetricDataRequest getMetricDataRequest = GetMetricDataRequest.builder() .maxDatapoints(10) .scanBy(ScanBy.TIMESTAMP_DESCENDING) .startTime(nowDate) .endTime(endTime) .metricDataQueries(dq) .build(); // Call the async method for CloudWatch data retrieval. return getAsyncClient().getMetricData(getMetricDataRequest); } catch (IOException e) { throw new RuntimeException("Failed to parse JSON content", e); } }).thenAccept(response -> { List<MetricDataResult> data = response.metricDataResults(); for (MetricDataResult item : data) { logger.info("The label is: {}", item.label()); logger.info("The status code is: {}", item.statusCode().toString()); } }).exceptionally(exception -> { throw new RuntimeException("Failed to get metric data", exception); }); } /** * Describes the CloudWatch alarms of the 'METRIC_ALARM' type. * * @return a {@link CompletableFuture} that represents the asynchronous operation * of describing the CloudWatch alarms. The future completes when the * operation is finished, either successfully or with an error. */ public CompletableFuture<Void> describeAlarmsAsync() { List<AlarmType> typeList = new ArrayList<>(); typeList.add(AlarmType.METRIC_ALARM); DescribeAlarmsRequest alarmsRequest = DescribeAlarmsRequest.builder() .alarmTypes(typeList) .maxRecords(10) .build(); return getAsyncClient().describeAlarms(alarmsRequest) .thenAccept(response -> { List<MetricAlarm> alarmList = response.metricAlarms(); for (MetricAlarm alarm : alarmList) { logger.info("Alarm name: {}", alarm.alarmName()); logger.info("Alarm description: {} ", alarm.alarmDescription()); } }) .whenComplete((response, ex) -> { if (ex != null) { logger.info("Failed to describe alarms: {}", ex.getMessage()); } else { logger.info("Successfully described alarms."); } }); } /** * Creates an alarm based on the configuration provided in a JSON file. * * @param fileName the name of the JSON file containing the alarm configuration * @return a CompletableFuture that represents the asynchronous operation of creating the alarm * @throws RuntimeException if an exception occurs while reading the JSON file or creating the alarm */ public CompletableFuture<String> createAlarmAsync(String fileName) { com.fasterxml.jackson.databind.JsonNode rootNode; try { JsonParser parser = new JsonFactory().createParser(new File(fileName)); rootNode = new ObjectMapper().readTree(parser); } catch (IOException e) { throw new RuntimeException("Failed to read the alarm configuration file", e); } // Extract values from the JSON node. String customMetricNamespace = rootNode.findValue("customMetricNamespace").asText(); String customMetricName = rootNode.findValue("customMetricName").asText(); String alarmName = rootNode.findValue("exampleAlarmName").asText(); String emailTopic = rootNode.findValue("emailTopic").asText(); String accountId = rootNode.findValue("accountId").asText(); String region = rootNode.findValue("region").asText(); // Create a List for alarm actions. List<String> alarmActions = new ArrayList<>(); alarmActions.add("arn:aws:sns:" + region + ":" + accountId + ":" + emailTopic); PutMetricAlarmRequest alarmRequest = PutMetricAlarmRequest.builder() .alarmActions(alarmActions) .alarmDescription("Example metric alarm") .alarmName(alarmName) .comparisonOperator(ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD) .threshold(100.00) .metricName(customMetricName) .namespace(customMetricNamespace) .evaluationPeriods(1) .period(10) .statistic("Maximum") .datapointsToAlarm(1) .treatMissingData("ignore") .build(); // Call the putMetricAlarm asynchronously and handle the result. return getAsyncClient().putMetricAlarm(alarmRequest) .handle((response, ex) -> { if (ex != null) { logger.info("Failed to create alarm: {}", ex.getMessage()); throw new RuntimeException("Failed to create alarm", ex); } else { logger.info("{} was successfully created!", alarmName); return alarmName; } }); } /** * Adds a metric to a dashboard asynchronously. * * @param fileName the name of the file containing the dashboard content * @param dashboardName the name of the dashboard to be updated * @return a {@link CompletableFuture} representing the asynchronous operation, which will complete with a * {@link PutDashboardResponse} when the dashboard is successfully updated */ public CompletableFuture<PutDashboardResponse> addMetricToDashboardAsync(String fileName, String dashboardName) { String dashboardBody; try { dashboardBody = readFileAsString(fileName); } catch (IOException e) { throw new RuntimeException("Failed to read the dashboard file", e); } PutDashboardRequest dashboardRequest = PutDashboardRequest.builder() .dashboardName(dashboardName) .dashboardBody(dashboardBody) .build(); return getAsyncClient().putDashboard(dashboardRequest) .handle((response, ex) -> { if (ex != null) { logger.info("Failed to update dashboard: {}", ex.getMessage()); throw new RuntimeException("Error updating dashboard", ex); } else { logger.info("{} was successfully updated.", dashboardName); return response; } }); } /** * Creates a new custom metric. * * @param dataPoint the data point to be added to the custom metric * @return a {@link CompletableFuture} representing the asynchronous operation of adding the custom metric */ public CompletableFuture<PutMetricDataResponse> createNewCustomMetricAsync(Double dataPoint) { Dimension dimension = Dimension.builder() .name("UNIQUE_PAGES") .value("URLS") .build(); // Set an Instant object for the current time in UTC. String time = ZonedDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ISO_INSTANT); Instant instant = Instant.parse(time); // Create the MetricDatum. MetricDatum datum = MetricDatum.builder() .metricName("PAGES_VISITED") .unit(StandardUnit.NONE) .value(dataPoint) .timestamp(instant) .dimensions(dimension) .build(); PutMetricDataRequest request = PutMetricDataRequest.builder() .namespace("SITE/TRAFFIC") .metricData(datum) .build(); return getAsyncClient().putMetricData(request) .whenComplete((response, ex) -> { if (ex != null) { throw new RuntimeException("Error adding custom metric", ex); } else { logger.info("Successfully added metric values for PAGES_VISITED."); } }); } /** * Lists the available dashboards. * * @return a {@link CompletableFuture} that completes when the operation is finished. * The future will complete exceptionally if an error occurs while listing the dashboards. */ public CompletableFuture<Void> listDashboardsAsync() { ListDashboardsRequest listDashboardsRequest = ListDashboardsRequest.builder().build(); ListDashboardsPublisher paginator = getAsyncClient().listDashboardsPaginator(listDashboardsRequest); return paginator.subscribe(response -> { response.dashboardEntries().forEach(entry -> { logger.info("Dashboard name is: {} ", entry.dashboardName()); logger.info("Dashboard ARN is: {} ", entry.dashboardArn()); }); }).exceptionally(ex -> { logger.info("Failed to list dashboards: {} ", ex.getMessage()); throw new RuntimeException("Error occurred while listing dashboards", ex); }); } /** * Creates a new dashboard with the specified name and metrics from the given file. * * @param dashboardName the name of the dashboard to be created * @param fileName the name of the file containing the dashboard body * @return a {@link CompletableFuture} representing the asynchronous operation of creating the dashboard * @throws IOException if there is an error reading the dashboard body from the file */ public CompletableFuture<PutDashboardResponse> createDashboardWithMetricsAsync(String dashboardName, String fileName) throws IOException { String dashboardBody = readFileAsString(fileName); PutDashboardRequest dashboardRequest = PutDashboardRequest.builder() .dashboardName(dashboardName) .dashboardBody(dashboardBody) .build(); return getAsyncClient().putDashboard(dashboardRequest) .handle((response, ex) -> { if (ex != null) { logger.info("Failed to create dashboard: {}", ex.getMessage()); throw new RuntimeException("Dashboard creation failed", ex); } else { // Handle the normal response case logger.info("{} was successfully created.", dashboardName); List<DashboardValidationMessage> messages = response.dashboardValidationMessages(); if (messages.isEmpty()) { logger.info("There are no messages in the new Dashboard."); } else { for (DashboardValidationMessage message : messages) { logger.info("Message: {}", message.message()); } } return response; // Return the response for further use } }); } /** * Retrieves the metric statistics for the "EstimatedCharges" metric in the "AWS/Billing" namespace. * * @param costDateWeek the start date for the metric statistics, in the format of an ISO-8601 date string (e.g., "2023-04-05") * @return a {@link CompletableFuture} that, when completed, contains the {@link GetMetricStatisticsResponse} with the retrieved metric statistics * @throws RuntimeException if the metric statistics cannot be retrieved successfully */ public CompletableFuture<GetMetricStatisticsResponse> getMetricStatisticsAsync(String costDateWeek) { Instant start = Instant.parse(costDateWeek); Instant endDate = Instant.now(); // Define dimension Dimension dimension = Dimension.builder() .name("Currency") .value("USD") .build(); List<Dimension> dimensionList = new ArrayList<>(); dimensionList.add(dimension); GetMetricStatisticsRequest statisticsRequest = GetMetricStatisticsRequest.builder() .metricName("EstimatedCharges") .namespace("AWS/Billing") .dimensions(dimensionList) .statistics(Statistic.MAXIMUM) .startTime(start) .endTime(endDate) .period(86400) // One day period .build(); return getAsyncClient().getMetricStatistics(statisticsRequest) .whenComplete((response, exception) -> { if (response != null) { List<Datapoint> data = response.datapoints(); if (!data.isEmpty()) { for (Datapoint datapoint : data) { logger.info("Timestamp: {} Maximum value: {})", datapoint.timestamp(), datapoint.maximum()); } } else { logger.info("The returned data list is empty"); } } else { throw new RuntimeException("Failed to get metric statistics: " + exception.getMessage(), exception); } }); } /** * Retrieves and displays metric statistics for the specified parameters. * * @param nameSpace the namespace for the metric * @param metVal the name of the metric * @param metricOption the statistic to retrieve for the metric (e.g., "Maximum", "Average") * @param date the date for which to retrieve the metric statistics, in the format "yyyy-MM-dd'T'HH:mm:ss'Z'" * @param myDimension the dimension(s) to filter the metric statistics by * @return a {@link CompletableFuture} that completes when the metric statistics have been retrieved and displayed */ public CompletableFuture<GetMetricStatisticsResponse> getAndDisplayMetricStatisticsAsync(String nameSpace, String metVal, String metricOption, String date, Dimension myDimension) { Instant start = Instant.parse(date); Instant endDate = Instant.now(); // Building the request for metric statistics. GetMetricStatisticsRequest statisticsRequest = GetMetricStatisticsRequest.builder() .endTime(endDate) .startTime(start) .dimensions(myDimension) .metricName(metVal) .namespace(nameSpace) .period(86400) // 1 day period .statistics(Statistic.fromValue(metricOption)) .build(); return getAsyncClient().getMetricStatistics(statisticsRequest) .whenComplete((response, exception) -> { if (response != null) { List<Datapoint> data = response.datapoints(); if (!data.isEmpty()) { for (Datapoint datapoint : data) { logger.info("Timestamp: {} Maximum value: {}", datapoint.timestamp(), datapoint.maximum()); } } else { logger.info("The returned data list is empty"); } } else { logger.info("Failed to get metric statistics: {} ", exception.getMessage()); } }) .exceptionally(exception -> { throw new RuntimeException("Error while getting metric statistics: " + exception.getMessage(), exception); }); } /** * Retrieves a list of metric names for the specified namespace. * * @param namespace the namespace for which to retrieve the metric names * @return a {@link CompletableFuture} that, when completed, contains an {@link ArrayList} of * the metric names in the specified namespace * @throws RuntimeException if an error occurs while listing the metrics */ public CompletableFuture<ArrayList<String>> listMetsAsync(String namespace) { ListMetricsRequest request = ListMetricsRequest.builder() .namespace(namespace) .build(); ListMetricsPublisher metricsPaginator = getAsyncClient().listMetricsPaginator(request); Set<String> metSet = new HashSet<>(); CompletableFuture<Void> future = metricsPaginator.subscribe(response -> { response.metrics().forEach(metric -> { String metricName = metric.metricName(); metSet.add(metricName); }); }); return future .thenApply(ignored -> new ArrayList<>(metSet)) .exceptionally(exception -> { throw new RuntimeException("Failed to list metrics: " + exception.getMessage(), exception); }); } /** * Lists the available namespaces for the current AWS account. * * @return a {@link CompletableFuture} that, when completed, contains an {@link ArrayList} of the available namespace names. * @throws RuntimeException if an error occurs while listing the namespaces. */ public CompletableFuture<ArrayList<String>> listNameSpacesAsync() { ArrayList<String> nameSpaceList = new ArrayList<>(); ListMetricsRequest request = ListMetricsRequest.builder().build(); ListMetricsPublisher metricsPaginator = getAsyncClient().listMetricsPaginator(request); CompletableFuture<Void> future = metricsPaginator.subscribe(response -> { response.metrics().forEach(metric -> { String namespace = metric.namespace(); if (!nameSpaceList.contains(namespace)) { nameSpaceList.add(namespace); } }); }); return future .thenApply(ignored -> nameSpaceList) .exceptionally(exception -> { throw new RuntimeException("Failed to list namespaces: " + exception.getMessage(), exception); }); } /** * Retrieves the specific metric asynchronously. * * @param namespace the namespace of the metric to retrieve * @return a CompletableFuture that completes with the first dimension of the first metric found in the specified namespace, * or throws a RuntimeException if an error occurs or no metrics or dimensions are found */ public CompletableFuture<Dimension> getSpecificMetAsync(String namespace) { ListMetricsRequest request = ListMetricsRequest.builder() .namespace(namespace) .build(); return getAsyncClient().listMetrics(request).handle((response, exception) -> { if (exception != null) { logger.info("Error occurred while listing metrics: {} ", exception.getMessage()); throw new RuntimeException("Failed to retrieve specific metric dimension", exception); } else { List<Metric> myList = response.metrics(); if (!myList.isEmpty()) { Metric metric = myList.get(0); if (!metric.dimensions().isEmpty()) { return metric.dimensions().get(0); // Return the first dimension } } throw new RuntimeException("No metrics or dimensions found"); } }); } public static String readFileAsString(String file) throws IOException { return new String(Files.readAllBytes(Paths.get(file))); } }

操作

以下代码示例演示如何使用 DeleteAlarms

SDK适用于 Java 2.x
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 Amazon 代码示例存储库中进行设置和运行。

/** * Deletes a CloudWatch alarm. * * @param alarmName the name of the alarm to be deleted * @return a {@link CompletableFuture} representing the asynchronous operation to delete the alarm * the {@link DeleteAlarmsResponse} is returned when the operation completes successfully, * or a {@link RuntimeException} is thrown if the operation fails */ public CompletableFuture<DeleteAlarmsResponse> deleteCWAlarmAsync(String alarmName) { DeleteAlarmsRequest request = DeleteAlarmsRequest.builder() .alarmNames(alarmName) .build(); return getAsyncClient().deleteAlarms(request) .whenComplete((response, exception) -> { if (exception != null) { throw new RuntimeException("Failed to delete the alarm:{} " + alarmName, exception); } else { logger.info("Successfully deleted alarm {} ", alarmName); } }); }
  • 有关API详细信息,请参阅 “Amazon SDK for Java 2.x API参考 DeleteAlarms” 中的。

以下代码示例演示如何使用 DeleteAnomalyDetector

SDK适用于 Java 2.x
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 Amazon 代码示例存储库中进行设置和运行。

/** * Deletes an Anomaly Detector. * * @param fileName the name of the file containing the Anomaly Detector configuration * @return a CompletableFuture that represents the asynchronous deletion of the Anomaly Detector */ public CompletableFuture<DeleteAnomalyDetectorResponse> deleteAnomalyDetectorAsync(String fileName) { CompletableFuture<JsonNode> readFileFuture = CompletableFuture.supplyAsync(() -> { try { JsonParser parser = new JsonFactory().createParser(new File(fileName)); return new ObjectMapper().readTree(parser); // Return the root node } catch (IOException e) { throw new RuntimeException("Failed to read or parse the file", e); } }); return readFileFuture.thenCompose(rootNode -> { String customMetricNamespace = rootNode.findValue("customMetricNamespace").asText(); String customMetricName = rootNode.findValue("customMetricName").asText(); SingleMetricAnomalyDetector singleMetricAnomalyDetector = SingleMetricAnomalyDetector.builder() .metricName(customMetricName) .namespace(customMetricNamespace) .stat("Maximum") .build(); DeleteAnomalyDetectorRequest request = DeleteAnomalyDetectorRequest.builder() .singleMetricAnomalyDetector(singleMetricAnomalyDetector) .build(); return getAsyncClient().deleteAnomalyDetector(request); }).whenComplete((result, exception) -> { if (exception != null) { throw new RuntimeException("Failed to delete the Anomaly Detector", exception); } else { logger.info("Successfully deleted the Anomaly Detector."); } }); }
  • 有关API详细信息,请参阅 “Amazon SDK for Java 2.x API参考 DeleteAnomalyDetector” 中的。

以下代码示例演示如何使用 DeleteDashboards

SDK适用于 Java 2.x
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 Amazon 代码示例存储库中进行设置和运行。

/** * Deletes the specified dashboard. * * @param dashboardName the name of the dashboard to be deleted * @return a {@link CompletableFuture} representing the asynchronous operation of deleting the dashboard * @throws RuntimeException if the dashboard deletion fails */ public CompletableFuture<DeleteDashboardsResponse> deleteDashboardAsync(String dashboardName) { DeleteDashboardsRequest dashboardsRequest = DeleteDashboardsRequest.builder() .dashboardNames(dashboardName) .build(); return getAsyncClient().deleteDashboards(dashboardsRequest) .whenComplete((response, exception) -> { if (exception != null) { throw new RuntimeException("Failed to delete the dashboard: " + dashboardName, exception); } else { logger.info("{} was successfully deleted.", dashboardName); } }); }
  • 有关API详细信息,请参阅 “Amazon SDK for Java 2.x API参考 DeleteDashboards” 中的。

以下代码示例演示如何使用 DescribeAlarmHistory

SDK适用于 Java 2.x
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 Amazon 代码示例存储库中进行设置和运行。

/** * Retrieves the alarm history for a given alarm name and date range. * * @param fileName the path to the JSON file containing the alarm name * @param date the date to start the alarm history search (in the format "yyyy-MM-dd'T'HH:mm:ss'Z'") * @return a {@code CompletableFuture<Void>} that completes when the alarm history has been retrieved and processed */ public CompletableFuture<Void> getAlarmHistoryAsync(String fileName, String date) { CompletableFuture<String> readFileFuture = CompletableFuture.supplyAsync(() -> { try { JsonParser parser = new JsonFactory().createParser(new File(fileName)); com.fasterxml.jackson.databind.JsonNode rootNode = new ObjectMapper().readTree(parser); return rootNode.findValue("exampleAlarmName").asText(); // Return alarmName from the JSON file } catch (IOException e) { throw new RuntimeException("Failed to read or parse the file", e); } }); // Use the alarm name to describe alarm history with a paginator. return readFileFuture.thenCompose(alarmName -> { try { Instant start = Instant.parse(date); Instant endDate = Instant.now(); DescribeAlarmHistoryRequest historyRequest = DescribeAlarmHistoryRequest.builder() .startDate(start) .endDate(endDate) .alarmName(alarmName) .historyItemType(HistoryItemType.ACTION) .build(); // Use the paginator to paginate through alarm history pages. DescribeAlarmHistoryPublisher historyPublisher = getAsyncClient().describeAlarmHistoryPaginator(historyRequest); CompletableFuture<Void> future = historyPublisher .subscribe(response -> response.alarmHistoryItems().forEach(item -> { logger.info("History summary: {}", item.historySummary()); logger.info("Timestamp: {}", item.timestamp()); })) .whenComplete((result, exception) -> { if (exception != null) { logger.error("Error occurred while getting alarm history: " + exception.getMessage(), exception); } else { logger.info("Successfully retrieved all alarm history."); } }); // Return the future to the calling code for further handling return future; } catch (Exception e) { throw new RuntimeException("Failed to process alarm history", e); } }).whenComplete((result, exception) -> { if (exception != null) { throw new RuntimeException("Error completing alarm history processing", exception); } }); }
  • 有关API详细信息,请参阅 “Amazon SDK for Java 2.x API参考 DescribeAlarmHistory” 中的。

以下代码示例演示如何使用 DescribeAlarms

SDK适用于 Java 2.x
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 Amazon 代码示例存储库中进行设置和运行。

/** * Describes the CloudWatch alarms of the 'METRIC_ALARM' type. * * @return a {@link CompletableFuture} that represents the asynchronous operation * of describing the CloudWatch alarms. The future completes when the * operation is finished, either successfully or with an error. */ public CompletableFuture<Void> describeAlarmsAsync() { List<AlarmType> typeList = new ArrayList<>(); typeList.add(AlarmType.METRIC_ALARM); DescribeAlarmsRequest alarmsRequest = DescribeAlarmsRequest.builder() .alarmTypes(typeList) .maxRecords(10) .build(); return getAsyncClient().describeAlarms(alarmsRequest) .thenAccept(response -> { List<MetricAlarm> alarmList = response.metricAlarms(); for (MetricAlarm alarm : alarmList) { logger.info("Alarm name: {}", alarm.alarmName()); logger.info("Alarm description: {} ", alarm.alarmDescription()); } }) .whenComplete((response, ex) -> { if (ex != null) { logger.info("Failed to describe alarms: {}", ex.getMessage()); } else { logger.info("Successfully described alarms."); } }); }
  • 有关API详细信息,请参阅 “Amazon SDK for Java 2.x API参考 DescribeAlarms” 中的。

以下代码示例演示如何使用 DescribeAlarmsForMetric

SDK适用于 Java 2.x
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 Amazon 代码示例存储库中进行设置和运行。

/** * Checks for a metric alarm in AWS CloudWatch. * * @param fileName the name of the file containing the JSON configuration for the custom metric * @return a {@link CompletableFuture} that completes when the check for the metric alarm is complete */ public CompletableFuture<Void> checkForMetricAlarmAsync(String fileName) { CompletableFuture<String> readFileFuture = CompletableFuture.supplyAsync(() -> { try { JsonParser parser = new JsonFactory().createParser(new File(fileName)); com.fasterxml.jackson.databind.JsonNode rootNode = new ObjectMapper().readTree(parser); return rootNode.toString(); // Return JSON as a string for further processing } catch (IOException e) { throw new RuntimeException("Failed to read file", e); } }); return readFileFuture.thenCompose(jsonContent -> { try { com.fasterxml.jackson.databind.JsonNode rootNode = new ObjectMapper().readTree(jsonContent); String customMetricNamespace = rootNode.findValue("customMetricNamespace").asText(); String customMetricName = rootNode.findValue("customMetricName").asText(); DescribeAlarmsForMetricRequest metricRequest = DescribeAlarmsForMetricRequest.builder() .metricName(customMetricName) .namespace(customMetricNamespace) .build(); return checkForAlarmAsync(metricRequest, customMetricName, 10); } catch (IOException e) { throw new RuntimeException("Failed to parse JSON content", e); } }).whenComplete((result, exception) -> { if (exception != null) { throw new RuntimeException("Error checking metric alarm", exception); } }); } // Recursive method to check for the alarm. /** * Checks for the existence of an alarm asynchronously for the specified metric. * * @param metricRequest the request to describe the alarms for the specified metric * @param customMetricName the name of the custom metric to check for an alarm * @param retries the number of retries to perform if no alarm is found * @return a {@link CompletableFuture} that completes when an alarm is found or the maximum number of retries has been reached */ private static CompletableFuture<Void> checkForAlarmAsync(DescribeAlarmsForMetricRequest metricRequest, String customMetricName, int retries) { if (retries == 0) { return CompletableFuture.completedFuture(null).thenRun(() -> logger.info("No Alarm state found for {} after 10 retries.", customMetricName) ); } return (getAsyncClient().describeAlarmsForMetric(metricRequest).thenCompose(response -> { if (response.hasMetricAlarms()) { logger.info("Alarm state found for {}", customMetricName); return CompletableFuture.completedFuture(null); // Alarm found, complete the future } else { return CompletableFuture.runAsync(() -> { try { Thread.sleep(20000); logger.info("."); } catch (InterruptedException e) { throw new RuntimeException("Interrupted while waiting to retry", e); } }).thenCompose(v -> checkForAlarmAsync(metricRequest, customMetricName, retries - 1)); // Recursive call } })); }

以下代码示例演示如何使用 DescribeAnomalyDetectors

SDK适用于 Java 2.x
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 Amazon 代码示例存储库中进行设置和运行。

/** * Describes the anomaly detectors based on the specified JSON file. * * @param fileName the name of the JSON file containing the custom metric namespace and name * @return a {@link CompletableFuture} that completes when the anomaly detectors have been described * @throws RuntimeException if there is a failure during the operation, such as when reading or parsing the JSON file, * or when describing the anomaly detectors */ public CompletableFuture<Void> describeAnomalyDetectorsAsync(String fileName) { CompletableFuture<JsonNode> readFileFuture = CompletableFuture.supplyAsync(() -> { try { JsonParser parser = new JsonFactory().createParser(new File(fileName)); return new ObjectMapper().readTree(parser); } catch (IOException e) { throw new RuntimeException("Failed to read or parse the file", e); } }); return readFileFuture.thenCompose(rootNode -> { try { String customMetricNamespace = rootNode.findValue("customMetricNamespace").asText(); String customMetricName = rootNode.findValue("customMetricName").asText(); DescribeAnomalyDetectorsRequest detectorsRequest = DescribeAnomalyDetectorsRequest.builder() .maxResults(10) .metricName(customMetricName) .namespace(customMetricNamespace) .build(); return getAsyncClient().describeAnomalyDetectors(detectorsRequest).thenAccept(response -> { List<AnomalyDetector> anomalyDetectorList = response.anomalyDetectors(); for (AnomalyDetector detector : anomalyDetectorList) { logger.info("Metric name: {} ", detector.singleMetricAnomalyDetector().metricName()); logger.info("State: {} ", detector.stateValue()); } }); } catch (RuntimeException e) { throw new RuntimeException("Failed to describe anomaly detectors", e); } }).whenComplete((result, exception) -> { if (exception != null) { throw new RuntimeException("Error describing anomaly detectors", exception); } }); }

以下代码示例演示如何使用 DisableAlarmActions

SDK适用于 Java 2.x
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 Amazon 代码示例存储库中进行设置和运行。

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.cloudwatch.CloudWatchClient; import software.amazon.awssdk.services.cloudwatch.model.CloudWatchException; import software.amazon.awssdk.services.cloudwatch.model.DisableAlarmActionsRequest; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class DisableAlarmActions { public static void main(String[] args) { final String usage = """ Usage: <alarmName> Where: alarmName - An alarm name to disable (for example, MyAlarm). """; if (args.length != 1) { System.out.println(usage); System.exit(1); } String alarmName = args[0]; Region region = Region.US_EAST_1; CloudWatchClient cw = CloudWatchClient.builder() .region(region) .build(); disableActions(cw, alarmName); cw.close(); } public static void disableActions(CloudWatchClient cw, String alarmName) { try { DisableAlarmActionsRequest request = DisableAlarmActionsRequest.builder() .alarmNames(alarmName) .build(); cw.disableAlarmActions(request); System.out.printf("Successfully disabled actions on alarm %s", alarmName); } catch (CloudWatchException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } }
  • 有关API详细信息,请参阅 “Amazon SDK for Java 2.x API参考 DisableAlarmActions” 中的。

以下代码示例演示如何使用 EnableAlarmActions

SDK适用于 Java 2.x
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 Amazon 代码示例存储库中进行设置和运行。

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.cloudwatch.CloudWatchClient; import software.amazon.awssdk.services.cloudwatch.model.CloudWatchException; import software.amazon.awssdk.services.cloudwatch.model.EnableAlarmActionsRequest; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class EnableAlarmActions { public static void main(String[] args) { final String usage = """ Usage: <alarmName> Where: alarmName - An alarm name to enable (for example, MyAlarm). """; if (args.length != 1) { System.out.println(usage); System.exit(1); } String alarm = args[0]; Region region = Region.US_EAST_1; CloudWatchClient cw = CloudWatchClient.builder() .region(region) .build(); enableActions(cw, alarm); cw.close(); } public static void enableActions(CloudWatchClient cw, String alarm) { try { EnableAlarmActionsRequest request = EnableAlarmActionsRequest.builder() .alarmNames(alarm) .build(); cw.enableAlarmActions(request); System.out.printf("Successfully enabled actions on alarm %s", alarm); } catch (CloudWatchException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } }
  • 有关API详细信息,请参阅 “Amazon SDK for Java 2.x API参考 EnableAlarmActions” 中的。

以下代码示例演示如何使用 GetMetricData

SDK适用于 Java 2.x
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 Amazon 代码示例存储库中进行设置和运行。

/** * Retrieves custom metric data from the AWS CloudWatch service. * * @param fileName the name of the file containing the custom metric information * @return a {@link CompletableFuture} that completes when the metric data has been retrieved */ public CompletableFuture<Void> getCustomMetricDataAsync(String fileName) { CompletableFuture<String> readFileFuture = CompletableFuture.supplyAsync(() -> { try { // Read values from the JSON file. JsonParser parser = new JsonFactory().createParser(new File(fileName)); com.fasterxml.jackson.databind.JsonNode rootNode = new ObjectMapper().readTree(parser); return rootNode.toString(); // Return JSON as a string for further processing } catch (IOException e) { throw new RuntimeException("Failed to read file", e); } }); return readFileFuture.thenCompose(jsonContent -> { try { // Parse the JSON string to extract relevant values. com.fasterxml.jackson.databind.JsonNode rootNode = new ObjectMapper().readTree(jsonContent); String customMetricNamespace = rootNode.findValue("customMetricNamespace").asText(); String customMetricName = rootNode.findValue("customMetricName").asText(); // Set the current time and date range for metric query. Instant nowDate = Instant.now(); long hours = 1; long minutes = 30; Instant endTime = nowDate.plus(hours, ChronoUnit.HOURS).plus(minutes, ChronoUnit.MINUTES); Metric met = Metric.builder() .metricName(customMetricName) .namespace(customMetricNamespace) .build(); MetricStat metStat = MetricStat.builder() .stat("Maximum") .period(60) // Assuming period in seconds .metric(met) .build(); MetricDataQuery dataQuery = MetricDataQuery.builder() .metricStat(metStat) .id("foo2") .returnData(true) .build(); List<MetricDataQuery> dq = new ArrayList<>(); dq.add(dataQuery); GetMetricDataRequest getMetricDataRequest = GetMetricDataRequest.builder() .maxDatapoints(10) .scanBy(ScanBy.TIMESTAMP_DESCENDING) .startTime(nowDate) .endTime(endTime) .metricDataQueries(dq) .build(); // Call the async method for CloudWatch data retrieval. return getAsyncClient().getMetricData(getMetricDataRequest); } catch (IOException e) { throw new RuntimeException("Failed to parse JSON content", e); } }).thenAccept(response -> { List<MetricDataResult> data = response.metricDataResults(); for (MetricDataResult item : data) { logger.info("The label is: {}", item.label()); logger.info("The status code is: {}", item.statusCode().toString()); } }).exceptionally(exception -> { throw new RuntimeException("Failed to get metric data", exception); }); }
  • 有关API详细信息,请参阅 “Amazon SDK for Java 2.x API参考 GetMetricData” 中的。

以下代码示例演示如何使用 GetMetricStatistics

SDK适用于 Java 2.x
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 Amazon 代码示例存储库中进行设置和运行。

/** * Retrieves and displays metric statistics for the specified parameters. * * @param nameSpace the namespace for the metric * @param metVal the name of the metric * @param metricOption the statistic to retrieve for the metric (e.g., "Maximum", "Average") * @param date the date for which to retrieve the metric statistics, in the format "yyyy-MM-dd'T'HH:mm:ss'Z'" * @param myDimension the dimension(s) to filter the metric statistics by * @return a {@link CompletableFuture} that completes when the metric statistics have been retrieved and displayed */ public CompletableFuture<GetMetricStatisticsResponse> getAndDisplayMetricStatisticsAsync(String nameSpace, String metVal, String metricOption, String date, Dimension myDimension) { Instant start = Instant.parse(date); Instant endDate = Instant.now(); // Building the request for metric statistics. GetMetricStatisticsRequest statisticsRequest = GetMetricStatisticsRequest.builder() .endTime(endDate) .startTime(start) .dimensions(myDimension) .metricName(metVal) .namespace(nameSpace) .period(86400) // 1 day period .statistics(Statistic.fromValue(metricOption)) .build(); return getAsyncClient().getMetricStatistics(statisticsRequest) .whenComplete((response, exception) -> { if (response != null) { List<Datapoint> data = response.datapoints(); if (!data.isEmpty()) { for (Datapoint datapoint : data) { logger.info("Timestamp: {} Maximum value: {}", datapoint.timestamp(), datapoint.maximum()); } } else { logger.info("The returned data list is empty"); } } else { logger.info("Failed to get metric statistics: {} ", exception.getMessage()); } }) .exceptionally(exception -> { throw new RuntimeException("Error while getting metric statistics: " + exception.getMessage(), exception); }); }
  • 有关API详细信息,请参阅 “Amazon SDK for Java 2.x API参考 GetMetricStatistics” 中的。

以下代码示例演示如何使用 GetMetricWidgetImage

SDK适用于 Java 2.x
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 Amazon 代码示例存储库中进行设置和运行。

/** * Retrieves and saves a custom metric image to a file. * * @param fileName the name of the file to save the metric image to * @return a {@link CompletableFuture} that completes when the image has been saved to the file */ public CompletableFuture<Void> downloadAndSaveMetricImageAsync(String fileName) { logger.info("Getting Image data for custom metric."); String myJSON = """ { "title": "Example Metric Graph", "view": "timeSeries", "stacked ": false, "period": 10, "width": 1400, "height": 600, "metrics": [ [ "AWS/Billing", "EstimatedCharges", "Currency", "USD" ] ] } """; GetMetricWidgetImageRequest imageRequest = GetMetricWidgetImageRequest.builder() .metricWidget(myJSON) .build(); return getAsyncClient().getMetricWidgetImage(imageRequest) .thenCompose(response -> { SdkBytes sdkBytes = response.metricWidgetImage(); byte[] bytes = sdkBytes.asByteArray(); return CompletableFuture.runAsync(() -> { try { File outputFile = new File(fileName); try (FileOutputStream outputStream = new FileOutputStream(outputFile)) { outputStream.write(bytes); } } catch (IOException e) { throw new RuntimeException("Failed to write image to file", e); } }); }) .whenComplete((result, exception) -> { if (exception != null) { throw new RuntimeException("Error getting and saving metric image", exception); } else { logger.info("Image data saved successfully to {}", fileName); } }); }
  • 有关API详细信息,请参阅 “Amazon SDK for Java 2.x API参考 GetMetricWidgetImage” 中的。

以下代码示例演示如何使用 ListDashboards

SDK适用于 Java 2.x
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 Amazon 代码示例存储库中进行设置和运行。

/** * Lists the available dashboards. * * @return a {@link CompletableFuture} that completes when the operation is finished. * The future will complete exceptionally if an error occurs while listing the dashboards. */ public CompletableFuture<Void> listDashboardsAsync() { ListDashboardsRequest listDashboardsRequest = ListDashboardsRequest.builder().build(); ListDashboardsPublisher paginator = getAsyncClient().listDashboardsPaginator(listDashboardsRequest); return paginator.subscribe(response -> { response.dashboardEntries().forEach(entry -> { logger.info("Dashboard name is: {} ", entry.dashboardName()); logger.info("Dashboard ARN is: {} ", entry.dashboardArn()); }); }).exceptionally(ex -> { logger.info("Failed to list dashboards: {} ", ex.getMessage()); throw new RuntimeException("Error occurred while listing dashboards", ex); }); }
  • 有关API详细信息,请参阅 “Amazon SDK for Java 2.x API参考 ListDashboards” 中的。

以下代码示例演示如何使用 ListMetrics

SDK适用于 Java 2.x
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 Amazon 代码示例存储库中进行设置和运行。

/** * Retrieves a list of metric names for the specified namespace. * * @param namespace the namespace for which to retrieve the metric names * @return a {@link CompletableFuture} that, when completed, contains an {@link ArrayList} of * the metric names in the specified namespace * @throws RuntimeException if an error occurs while listing the metrics */ public CompletableFuture<ArrayList<String>> listMetsAsync(String namespace) { ListMetricsRequest request = ListMetricsRequest.builder() .namespace(namespace) .build(); ListMetricsPublisher metricsPaginator = getAsyncClient().listMetricsPaginator(request); Set<String> metSet = new HashSet<>(); CompletableFuture<Void> future = metricsPaginator.subscribe(response -> { response.metrics().forEach(metric -> { String metricName = metric.metricName(); metSet.add(metricName); }); }); return future .thenApply(ignored -> new ArrayList<>(metSet)) .exceptionally(exception -> { throw new RuntimeException("Failed to list metrics: " + exception.getMessage(), exception); }); }
  • 有关API详细信息,请参阅 “Amazon SDK for Java 2.x API参考 ListMetrics” 中的。

以下代码示例演示如何使用 PutAnomalyDetector

SDK适用于 Java 2.x
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 Amazon 代码示例存储库中进行设置和运行。

/** * Adds an anomaly detector for the given file. * * @param fileName the name of the file containing the anomaly detector configuration * @return a {@link CompletableFuture} that completes when the anomaly detector has been added */ public CompletableFuture<Void> addAnomalyDetectorAsync(String fileName) { CompletableFuture<JsonNode> readFileFuture = CompletableFuture.supplyAsync(() -> { try { JsonParser parser = new JsonFactory().createParser(new File(fileName)); return new ObjectMapper().readTree(parser); // Return the root node } catch (IOException e) { throw new RuntimeException("Failed to read or parse the file", e); } }); return readFileFuture.thenCompose(rootNode -> { try { String customMetricNamespace = rootNode.findValue("customMetricNamespace").asText(); String customMetricName = rootNode.findValue("customMetricName").asText(); SingleMetricAnomalyDetector singleMetricAnomalyDetector = SingleMetricAnomalyDetector.builder() .metricName(customMetricName) .namespace(customMetricNamespace) .stat("Maximum") .build(); PutAnomalyDetectorRequest anomalyDetectorRequest = PutAnomalyDetectorRequest.builder() .singleMetricAnomalyDetector(singleMetricAnomalyDetector) .build(); return getAsyncClient().putAnomalyDetector(anomalyDetectorRequest).thenAccept(response -> { logger.info("Added anomaly detector for metric {}", customMetricName); }); } catch (Exception e) { throw new RuntimeException("Failed to create anomaly detector", e); } }).whenComplete((result, exception) -> { if (exception != null) { throw new RuntimeException("Error adding anomaly detector", exception); } }); }
  • 有关API详细信息,请参阅 “Amazon SDK for Java 2.x API参考 PutAnomalyDetector” 中的。

以下代码示例演示如何使用 PutDashboard

SDK适用于 Java 2.x
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 Amazon 代码示例存储库中进行设置和运行。

/** * Creates a new dashboard with the specified name and metrics from the given file. * * @param dashboardName the name of the dashboard to be created * @param fileName the name of the file containing the dashboard body * @return a {@link CompletableFuture} representing the asynchronous operation of creating the dashboard * @throws IOException if there is an error reading the dashboard body from the file */ public CompletableFuture<PutDashboardResponse> createDashboardWithMetricsAsync(String dashboardName, String fileName) throws IOException { String dashboardBody = readFileAsString(fileName); PutDashboardRequest dashboardRequest = PutDashboardRequest.builder() .dashboardName(dashboardName) .dashboardBody(dashboardBody) .build(); return getAsyncClient().putDashboard(dashboardRequest) .handle((response, ex) -> { if (ex != null) { logger.info("Failed to create dashboard: {}", ex.getMessage()); throw new RuntimeException("Dashboard creation failed", ex); } else { // Handle the normal response case logger.info("{} was successfully created.", dashboardName); List<DashboardValidationMessage> messages = response.dashboardValidationMessages(); if (messages.isEmpty()) { logger.info("There are no messages in the new Dashboard."); } else { for (DashboardValidationMessage message : messages) { logger.info("Message: {}", message.message()); } } return response; // Return the response for further use } }); }
  • 有关API详细信息,请参阅 “Amazon SDK for Java 2.x API参考 PutDashboard” 中的。

以下代码示例演示如何使用 PutMetricAlarm

SDK适用于 Java 2.x
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 Amazon 代码示例存储库中进行设置和运行。

/** * Creates an alarm based on the configuration provided in a JSON file. * * @param fileName the name of the JSON file containing the alarm configuration * @return a CompletableFuture that represents the asynchronous operation of creating the alarm * @throws RuntimeException if an exception occurs while reading the JSON file or creating the alarm */ public CompletableFuture<String> createAlarmAsync(String fileName) { com.fasterxml.jackson.databind.JsonNode rootNode; try { JsonParser parser = new JsonFactory().createParser(new File(fileName)); rootNode = new ObjectMapper().readTree(parser); } catch (IOException e) { throw new RuntimeException("Failed to read the alarm configuration file", e); } // Extract values from the JSON node. String customMetricNamespace = rootNode.findValue("customMetricNamespace").asText(); String customMetricName = rootNode.findValue("customMetricName").asText(); String alarmName = rootNode.findValue("exampleAlarmName").asText(); String emailTopic = rootNode.findValue("emailTopic").asText(); String accountId = rootNode.findValue("accountId").asText(); String region = rootNode.findValue("region").asText(); // Create a List for alarm actions. List<String> alarmActions = new ArrayList<>(); alarmActions.add("arn:aws:sns:" + region + ":" + accountId + ":" + emailTopic); PutMetricAlarmRequest alarmRequest = PutMetricAlarmRequest.builder() .alarmActions(alarmActions) .alarmDescription("Example metric alarm") .alarmName(alarmName) .comparisonOperator(ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD) .threshold(100.00) .metricName(customMetricName) .namespace(customMetricNamespace) .evaluationPeriods(1) .period(10) .statistic("Maximum") .datapointsToAlarm(1) .treatMissingData("ignore") .build(); // Call the putMetricAlarm asynchronously and handle the result. return getAsyncClient().putMetricAlarm(alarmRequest) .handle((response, ex) -> { if (ex != null) { logger.info("Failed to create alarm: {}", ex.getMessage()); throw new RuntimeException("Failed to create alarm", ex); } else { logger.info("{} was successfully created!", alarmName); return alarmName; } }); }
  • 有关API详细信息,请参阅 “Amazon SDK for Java 2.x API参考 PutMetricAlarm” 中的。

以下代码示例演示如何使用 PutMetricData

SDK适用于 Java 2.x
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 Amazon 代码示例存储库中进行设置和运行。

/** * Adds metric data for an alarm asynchronously. * * @param fileName the name of the JSON file containing the metric data * @return a CompletableFuture that asynchronously returns the PutMetricDataResponse */ public CompletableFuture<PutMetricDataResponse> addMetricDataForAlarmAsync(String fileName) { CompletableFuture<String> readFileFuture = CompletableFuture.supplyAsync(() -> { try { JsonParser parser = new JsonFactory().createParser(new File(fileName)); com.fasterxml.jackson.databind.JsonNode rootNode = new ObjectMapper().readTree(parser); return rootNode.toString(); // Return JSON as a string for further processing } catch (IOException e) { throw new RuntimeException("Failed to read file", e); } }); return readFileFuture.thenCompose(jsonContent -> { try { com.fasterxml.jackson.databind.JsonNode rootNode = new ObjectMapper().readTree(jsonContent); String customMetricNamespace = rootNode.findValue("customMetricNamespace").asText(); String customMetricName = rootNode.findValue("customMetricName").asText(); Instant instant = Instant.now(); // Create MetricDatum objects. MetricDatum datum1 = MetricDatum.builder() .metricName(customMetricName) .unit(StandardUnit.NONE) .value(1001.00) .timestamp(instant) .build(); MetricDatum datum2 = MetricDatum.builder() .metricName(customMetricName) .unit(StandardUnit.NONE) .value(1002.00) .timestamp(instant) .build(); List<MetricDatum> metricDataList = new ArrayList<>(); metricDataList.add(datum1); metricDataList.add(datum2); // Build the PutMetricData request. PutMetricDataRequest request = PutMetricDataRequest.builder() .namespace(customMetricNamespace) .metricData(metricDataList) .build(); // Send the request asynchronously. return getAsyncClient().putMetricData(request); } catch (IOException e) { CompletableFuture<PutMetricDataResponse> failedFuture = new CompletableFuture<>(); failedFuture.completeExceptionally(new RuntimeException("Failed to parse JSON content", e)); return failedFuture; } }).whenComplete((response, exception) -> { if (exception != null) { logger.error("Failed to put metric data: " + exception.getMessage(), exception); } else { logger.info("Added metric values for metric."); } }); }
  • 有关API详细信息,请参阅 “Amazon SDK for Java 2.x API参考 PutMetricData” 中的。

场景

以下代码示例显示如何配置应用程序使用 DynamoDB 来监控性能。

SDK适用于 Java 2.x

此示例说明如何配置 Java 应用程序,以监控 DynamoDB 的性能。应用程序将指标数据发送到您可以监控性能 CloudWatch 的地方。

有关如何设置和运行的完整源代码和说明,请参阅上的完整示例GitHub

本示例中使用的服务
  • CloudWatch

  • DynamoDB