【Azure Developer】Java代码实现获取Azure 资源的指标数据却报错 "invalid time interval input"

问题描述

在使用 Java 代码调用虚拟机(VM)API获取指标数据时,出现时间格式解析错误。

错误信息:

'{
"code": "BadRequest",
"message": "Detected invalid time interval input: 2024-03-13T13:33:05.123 15:00/2024-03-13T13:48:05.233 15:00, supported Iso 8601 time interval format: (Datetime/Datetime, Datetime/Duration, Duration/Datetime, Duration)"
}'

JAVA 代码:

static void query() 
 {
     MetricsQueryClient metricsQueryClient = new MetricsQueryClientBuilder()
        .endpoint("https://management.chinacloudapi.cn")
        .credential(new DefaultAzureCredentialBuilder().build())
        .buildClient();

    String resourceId = "<resource id>";
    Response<MetricsQueryResult> metricsResponse = metricsQueryClient
        .queryResourceWithResponse(resourceId, 
                                    Arrays.asList("CpuTime", "Requests"), new MetricsQueryOptions()
                                        .setGranularity(Duration.ofHours(1))
                                        .setTimeInterval(new QueryTimeInterval(OffsetDateTime.now().minusDays(1), OffsetDateTime.now()))
                                        .setAggregations(Arrays.asList(AggregationType.AVERAGE, AggregationType.COUNT)),
                                    Context.NONE);

    MetricsQueryResult metricsQueryResult = metricsResponse.getValue(); for (MetricResult metric : metricsQueryResult.getMetrics()) 
    {
        System.out.println("Metric name " + metric.getMetricName()); for (TimeSeriesElement timeSeriesElement : metric.getTimeSeries()) 
        {
            System.out.println("Dimensions " + timeSeriesElement.getMetadata()); for (MetricValue metricValue : timeSeriesElement.getValues()) 
            {
                System.out.println(metricValue.getTimeStamp() + " " + metricValue.getTotal());
            }
        }
    }
}

这个会是什么原因导致的呢?

问题解答

添加日志,对比代码生成的时间格式字符串后,发现问题根源于本地执行环境的时区设置相关!

因为 Java SDK中timespan参数仅支持UTC的ZoneOffset。如果本地环境设置为非UTC的时区,例如:export TZ="/usr/share/zoneinfo/Hongkong" 就可以复现此问题。

鉴于此种情况,如果不修改本地电脑环境的情况下,可以在代码中进行指定时间为UTC时区。

添加代码:ZoneOffset zoneOffsetUTC = ZoneOffset.ofHours(0);, 然后在设置 setTimeInterval 中指定时区 OffsetDateTime.now().withOffsetSameInstant(zoneOffsetUTC)。这样就可以解决时间格式因时区不同而产生的问题!

修改后的代码为:

 static void query() 
 {
     MetricsQueryClient metricsQueryClient = new MetricsQueryClientBuilder()
        .endpoint("https://management.chinacloudapi.cn")
        .credential(new DefaultAzureCredentialBuilder().build())
        .buildClient();

    String resourceId = "<resource id>";

 ZoneOffset zoneOffsetUTC = ZoneOffset.ofHours(0);

    Response<MetricsQueryResult> metricsResponse = metricsQueryClient
        .queryResourceWithResponse(resourceId, 
                                    Arrays.asList("CpuTime", "Requests"), new MetricsQueryOptions()
                                        .setGranularity(Duration.ofHours(1))
                                        .setTimeInterval(new QueryTimeInterval(OffsetDateTime.now().minusDays(1).withOffsetSameInstant(zoneOffsetUTC), OffsetDateTime.now().withOffsetSameInstant(zoneOffsetUTC)))
                                        .setAggregations(Arrays.asList(AggregationType.AVERAGE, AggregationType.COUNT)),
                                    Context.NONE);

    MetricsQueryResult metricsQueryResult = metricsResponse.getValue(); for (MetricResult metric : metricsQueryResult.getMetrics()) 
    {
        System.out.println("Metric name " + metric.getMetricName()); for (TimeSeriesElement timeSeriesElement : metric.getTimeSeries()) 
        {
            System.out.println("Dimensions " + timeSeriesElement.getMetadata()); for (MetricValue metricValue : timeSeriesElement.getValues()) 
            {
                System.out.println(metricValue.getTimeStamp() + " " + metricValue.getTotal());
            }
        }
    }
}

参考资料

Azure Resource Metrics - List :https://learn.microsoft.com/en-us/rest/api/monitor/metrics/list?view=rest-monitor-2023-10-01&tabs=HTTP

timespan :The timespan of the query. It is a string with the following format 'startDateTime_ISO/endDateTime_ISO'.

当在复杂的环境中面临问题,格物之道需:浊而静之徐清,安以动之徐生。 云中,恰是如此!

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1.概述 Java 8为Date和Time引入了新的API,以解决旧java.util.Date和java.uti...
    BUG生产者阅读 1,534评论 0 0
  • 我们先来看一些基本概念,然后再介绍 Java 的日期和时间 API。关于日期和时间,有一些基本概念,包括时区、时刻...
    acc8226阅读 3,427评论 1 1
  • 为什么我们需要一个新的日期和时间库? Java长期存在的一个问题是对日期和时间的支持非常不理想。例如,现有的类(例...
    bern85阅读 2,669评论 0 0
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,408评论 19 139
  • 在实际开发项目中,我们经常会与各种时间类型打交道,在Java8之前我们是用Calendar,Date, Time和...
    乱七八糟谈技术阅读 5,699评论 0 1