使用 Word for Java 2.x 的 CloudWatch SDK 範例 - AWS SDK 程式碼範例

文件 AWS SDK AWS 範例 SDK 儲存庫中有更多可用的 GitHub 範例。

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

使用 Word for Java 2.x 的 CloudWatch SDK 範例

下列程式碼範例示範如何使用 AWS SDK for Java 2.x with CloudWatch 來執行動作和實作常見案例。

基本概念是程式碼範例,示範如何在服務內執行基本操作。

Actions 是大型程式的程式碼摘錄,必須在內容中執行。雖然動作會示範如何呼叫個別服務函數,但您可以在相關案例中查看內容中的動作。

案例是程式碼範例,示範如何透過呼叫服務內的多個函數或與其他函數結合來完成特定任務 AWS 服務。

每個範例都包含完整原始程式碼的連結,您可以在其中找到如何在內容中設定和執行程式碼的指示。

開始使用

下列程式碼範例示範如何開始使用 CloudWatch。

Java 2.x 的 SDK
注意

還有更多 on GitHub。尋找完整範例,並了解如何在 AWS 程式碼範例儲存庫中設定和執行。

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 詳細資訊,請參閱 ListMetrics AWS SDK for Java 2.x 參考中的 API

基本概念

以下程式碼範例顯示做法:

  • List CloudWatch 命名空間和指標。

  • 取得指標和預估帳單的統計資料。

  • 建立並更新儀表板。

  • 建立資料並將其新增至指標。

  • 建立並觸發警示,然後檢視警示歷史記錄。

  • 新增異常偵測器。

  • 取得指標映像,然後清除資源。

Java 2.x 的 SDK
注意

還有更多 on GitHub。尋找完整範例,並了解如何在 AWS 程式碼範例儲存庫中設定和執行。

執行顯示 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."); } } } }

Word 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

Java 2.x 的 SDK
注意

還有更多 on GitHub。尋找完整範例,並了解如何在 AWS 程式碼範例儲存庫中設定和執行。

/** * 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 詳細資訊,請參閱 DeleteAlarms AWS SDK for Java 2.x 參考中的 API

下列程式碼範例示範如何使用 DeleteAnomalyDetector

Java 2.x 的 SDK
注意

還有更多 on GitHub。尋找完整範例,並了解如何在 AWS 程式碼範例儲存庫中設定和執行。

/** * 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."); } }); }

下列程式碼範例示範如何使用 DeleteDashboards

Java 2.x 的 SDK
注意

還有更多 on GitHub。尋找完整範例,並了解如何在 AWS 程式碼範例儲存庫中設定和執行。

/** * 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 詳細資訊,請參閱 DeleteDashboards AWS SDK for Java 2.x 參考中的 API

下列程式碼範例示範如何使用 DescribeAlarmHistory

Java 2.x 的 SDK
注意

還有更多 on GitHub。尋找完整範例,並了解如何在 AWS 程式碼範例儲存庫中設定和執行。

/** * 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); } }); }

下列程式碼範例示範如何使用 DescribeAlarms

Java 2.x 的 SDK
注意

還有更多 on GitHub。尋找完整範例,並了解如何在 AWS 程式碼範例儲存庫中設定和執行。

/** * 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 詳細資訊,請參閱 DescribeAlarms AWS SDK for Java 2.x 參考中的 API

下列程式碼範例示範如何使用 DescribeAlarmsForMetric

Java 2.x 的 SDK
注意

還有更多 on GitHub。尋找完整範例,並了解如何在 AWS 程式碼範例儲存庫中設定和執行。

/** * 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

Java 2.x 的 SDK
注意

還有更多 on GitHub。尋找完整範例,並了解如何在 AWS 程式碼範例儲存庫中設定和執行。

/** * 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

Java 2.x 的 SDK
注意

還有更多 on GitHub。尋找完整範例,並了解如何在 AWS 程式碼範例儲存庫中設定和執行。

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); } } }

下列程式碼範例示範如何使用 EnableAlarmActions

Java 2.x 的 SDK
注意

還有更多 on GitHub。尋找完整範例,並了解如何在 AWS 程式碼範例儲存庫中設定和執行。

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 詳細資訊,請參閱 EnableAlarmActions AWS SDK for Java 2.x 參考中的 API

下列程式碼範例示範如何使用 GetMetricData

Java 2.x 的 SDK
注意

還有更多 on GitHub。尋找完整範例,並了解如何在 AWS 程式碼範例儲存庫中設定和執行。

/** * 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 詳細資訊,請參閱 GetMetricData AWS SDK for Java 2.x 參考中的 API

下列程式碼範例示範如何使用 GetMetricStatistics

Java 2.x 的 SDK
注意

還有更多 on GitHub。尋找完整範例,並了解如何在 AWS 程式碼範例儲存庫中設定和執行。

/** * 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); }); }

下列程式碼範例示範如何使用 GetMetricWidgetImage

Java 2.x 的 SDK
注意

還有更多 on GitHub。尋找完整範例,並了解如何在 AWS 程式碼範例儲存庫中設定和執行。

/** * 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); } }); }

下列程式碼範例示範如何使用 ListDashboards

Java 2.x 的 SDK
注意

還有更多 on GitHub。尋找完整範例,並了解如何在 AWS 程式碼範例儲存庫中設定和執行。

/** * 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 詳細資訊,請參閱 ListDashboards AWS SDK for Java 2.x 參考中的 API

下列程式碼範例示範如何使用 ListMetrics

Java 2.x 的 SDK
注意

還有更多 on GitHub。尋找完整範例,並了解如何在 AWS 程式碼範例儲存庫中設定和執行。

/** * 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 詳細資訊,請參閱 ListMetrics AWS SDK for Java 2.x 參考中的 API

下列程式碼範例示範如何使用 PutAnomalyDetector

Java 2.x 的 SDK
注意

還有更多 on GitHub。尋找完整範例,並了解如何在 AWS 程式碼範例儲存庫中設定和執行。

/** * 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 詳細資訊,請參閱 PutAnomalyDetector AWS SDK for Java 2.x 參考中的 API

下列程式碼範例示範如何使用 PutDashboard

Java 2.x 的 SDK
注意

還有更多 on GitHub。尋找完整範例,並了解如何在 AWS 程式碼範例儲存庫中設定和執行。

/** * 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 詳細資訊,請參閱 PutDashboard AWS SDK for Java 2.x 參考中的 API

下列程式碼範例示範如何使用 PutMetricAlarm

Java 2.x 的 SDK
注意

還有更多 on GitHub。尋找完整範例,並了解如何在 AWS 程式碼範例儲存庫中設定和執行。

/** * 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 詳細資訊,請參閱 PutMetricAlarm AWS SDK for Java 2.x 參考中的 API

下列程式碼範例示範如何使用 PutMetricData

Java 2.x 的 SDK
注意

還有更多 on GitHub。尋找完整範例,並了解如何在 AWS 程式碼範例儲存庫中設定和執行。

/** * 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 詳細資訊,請參閱 PutMetricData AWS SDK for Java 2.x 參考中的 API

案例

下列程式碼範例示範如何設定應用程式使用 DynamoDB 來監控效能。

Java 2.x 的 SDK

此範例示範如何設定 Java 應用程式來監控 DynamoDB 的效能。應用程式會將指標資料傳送至 CloudWatch ,您可以在其中監控效能。

如需完整的原始程式碼和如何設定和執行的指示,請參閱 GitHub 上的完整範例。

此範例中使用的服務
  • CloudWatch

  • DynamoDB