无法获取 Java 中 Elasticache 的 AWS cloudwatch 指标

问题描述 投票:0回答:1

我正在尝试使用 Java SDK 1.x 从 CloudWatch 检索一些 Elasticache 指标。我有多个用于多种服务的类,除了 Elasticache 之外,它们都可以工作。此类会传递 Elasticache 节点列表以及开始时间和结束时间。对于每个节点,我尝试从 Elasticache 检索 30 分钟内的一些指标。但是,由于某种原因,我不断获得每个指标的值 0.0。我已确认 AWS 控制台中的指标不为空。这是我的代码:

public class ElastiCacheCWMetricsRetriever {
    private final AmazonCloudWatch cloudWatchClient;

    public ElastiCacheCWMetricsRetriever(AmazonCloudWatch cloudWatchClient) {
        this.cloudWatchClient = cloudWatchClient;
    }


    public Map<String, Map<String, Object>> getElastiCacheMetrics(List<String> nodeNames, 
        String startTimeStr, String endTimeStr) {
        Map<String, Map<String, Object>> elastiCacheMetricsMap = new HashMap<>();

        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
            Date startTime = dateFormat.parse(startTimeStr);
            Date endTime = dateFormat.parse(endTimeStr);

            for (String nodeName : nodeNames) {
                Map<String, Object> nodeMetrics = new HashMap<>();

                nodeMetrics.put("SwapUsage", getAverageMetricValue("AWS/ElastiCache", 
                    "SwapUsage", "CacheNodeId", nodeName, startTime, endTime));
                Double SwapUsage = getSumMetricValue("AWS/ElastiCache", "SwapUsage", 
                    "CacheNodeId", nodeName, startTime, endTime);
                System.out.println("SwapUsage for " + nodeName + " is " + 
                    String.valueOf(SwapUsage));

                nodeMetrics.put("CurrentConnections", getSumMetricValue("AWS/ElastiCache", 
                    "CurrConnections", "CacheNodeId", nodeName, startTime, endTime));

                nodeMetrics.put("DatabaseMemoryUsagePercentage", 
                getAverageMetricValue("AWS/ElastiCache", "DatabaseMemoryUsagePercentage", 
                    "CacheNodeId", nodeName, startTime, endTime) * 100.0);

                nodeMetrics.put("EngineCPUUtilization", 
                     getAverageMetricValue("AWS/ElastiCache", "EngineCPUUtilization", 
                     "CacheNodeId", nodeName, startTime, endTime) * 100.0);

                Double EngineCPUUtil = getAverageMetricValue("AWS/ElastiCache", 
                    "EngineCPUUtilization", "CacheNodeId", nodeName, startTime, endTime) * 100.0;
                System.out.println("EngineCPUUtilization for " + nodeName + " is " + String.valueOf(EngineCPUUtil));
                elastiCacheMetricsMap.put(nodeName, nodeMetrics);
            }
        } catch (Exception e) {
            System.out.println("Error in Elasticache" + e.getMessage());
        }   
        return elastiCacheMetricsMap;
    }

     private double getAverageMetricValue(String namespace, String metricName, String 
         dimensionName, String dimensionValue, Date startTime, Date endTime) {
         int period = calculatePeriod(startTime, endTime);
         return getMetricValue(namespace, metricName, dimensionName, dimensionValue, startTime, endTime, period, "Average");
     }

    private double getSumMetricValue(String namespace, String metricName, String dimensionName, String dimensionValue, Date startTime, Date endTime) {
        int period = calculatePeriod(startTime, endTime);
        return getMetricValue(namespace, metricName, dimensionName, dimensionValue, startTime, endTime, period, "Sum");
    }

    private double getMetricValue(String namespace, String metricName, String dimensionName, String dimensionValue, Date startTime, Date endTime, int period, String statistic) {
        try {
            GetMetricStatisticsRequest request = new GetMetricStatisticsRequest()
                .withNamespace(namespace)
                .withMetricName(metricName)
                .withDimensions(new Dimension().withName(dimensionName).withValue(dimensionValue))
                .withStartTime(startTime)
                .withEndTime(endTime)
                .withPeriod(period)
                .withStatistics(statistic);

            GetMetricStatisticsResult result = cloudWatchClient.getMetricStatistics(request);
            System.out.println("Result for " + dimensionValue + " is " + result.toString());
            return result.getDatapoints().isEmpty() ? 0 : result.getDatapoints().get(0).getAverage();
        } catch (Exception e) {
            System.out.println("Error in Elasticache" + e.getMessage());
            return 0;
        }
    }


    private int calculatePeriod(Date startTime, Date endTime) {
        long diffInSeconds = (endTime.getTime() - startTime.getTime()) / 1000;
        int periods = (int) Math.ceil(diffInSeconds / 1800);

        return (periods > 0) ? 1800 : 60;
    }
}

我正在使用

System.out.println("SwapUsage for " + nodeName + " is " + String.valueOf(SwapUsage));
进行故障排除。我不知道下一步该看哪里。有什么想法/建议吗?

编辑:所以我对此进行了更多测试,并在

System.out.println("Result for " + dimensionValue + " is " + result.toString());
内添加了这一行
getMetricValue
。我得到的结果是
Result for scrsquy-001 is {Label: EngineCPUUtilization,Datapoints: []}
。为什么它是空的,我怎样才能让它工作?

java amazon-web-services amazon-elasticache aws-java-sdk
1个回答
0
投票

您检查过您的 IAM 吗? 确保用于创建 Amazon CloudWatch 客户端的 AWS IAM 用户或角色具有从 CloudWatch 读取 Elasticache 指标的必要权限。验证附加到用户或角色的 IAM 策略,以确保其具有 cloudwatch:GetMetricStatistics 的权限。

通过快速查看您的代码,我看不到任何明显的错误,但我确实注意到 getSumMetricValue 和 getAverageMetricValue 方法中的“MetricName”存在潜在问题。

您在代码中指定了“SwapUsage”和“CurrConnections”等指标名称,但 Elasticache 指标通常使用“SwapUsage:PerNode”和“CurrConnections:PerNode”等指标名称进行报告。这些是示例,实际的指标名称可能有额外的后缀来区分不同的节点。

© www.soinside.com 2019 - 2024. All rights reserved.