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

简介: 在使用 Java 调用虚拟机 API 获取指标数据时,因本地时区设置非 UTC,导致时间格式解析错误。解决方法是在代码中手动指定时区为 UTC,使用 `ZoneOffset.ofHours(0)` 并结合 `withOffsetSameInstant` 方法进行时区转换,从而避免因时区差异引发的时间格式问题。

问题描述

在使用 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'.

 

 


 


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

相关文章
|
4月前
|
Java 开发工具
【Azure Storage Account】Java Code访问Storage Account File Share的上传和下载代码示例
本文介绍如何使用Java通过azure-storage-file-share SDK实现Azure文件共享的上传下载。包含依赖引入、客户端创建及完整示例代码,助你快速集成Azure File Share功能。
408 5
|
4月前
|
Java 数据处理 API
为什么你的Java代码应该多用Stream?从循环到声明式的思维转变
为什么你的Java代码应该多用Stream?从循环到声明式的思维转变
297 115
|
4月前
|
安全 Java 编译器
为什么你的Java代码需要泛型?类型安全的艺术
为什么你的Java代码需要泛型?类型安全的艺术
214 98
|
4月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
246 2
|
4月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
260 1
|
5月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
Java 数据库 Spring
215 0
|
5月前
|
算法 Java
Java多线程编程:实现线程间数据共享机制
以上就是Java中几种主要处理多线程序列化资源以及协调各自独立运行但需相互配合以完成任务threads 的技术手段与策略。正确应用上述技术将大大增强你程序稳定性与效率同时也降低bug出现率因此深刻理解每项技术背后理论至关重要.
396 16
|
6月前
|
缓存 并行计算 安全
关于Java多线程详解
本文深入讲解Java多线程编程,涵盖基础概念、线程创建与管理、同步机制、并发工具类、线程池、线程安全集合、实战案例及常见问题解决方案,助你掌握高性能并发编程技巧,应对多线程开发中的挑战。
|
6月前
|
数据采集 存储 前端开发
Java爬虫性能优化:多线程抓取JSP动态数据实践
Java爬虫性能优化:多线程抓取JSP动态数据实践