【Azure Developer】通過Azure提供的Azue Java JDK 查詢虛擬機器的CPU使用率和記憶體使用率

路邊兩盞燈發表於2020-12-12

問題描述

在Azure上建立虛擬機器(VM)後,在門戶上可以檢視監控指標(Metrics),如CPU Usage,Memory,Disk I/O等。那如何通過Java 程式碼獲取到這些指標呢?

關於VM 的記憶體使用率,虛擬機器本身並沒有提供這個指標,需要開啟診斷後去Azure Storage表中獲取,欄位為\Memory\% Committed Bytes In Use是開啟了診斷日誌儲存到WADMetrics

 

解決辦法

方式一:使用REST API

Azure中門戶上看見的內容都是通過REST API來獲取值,基於此原理,可以通過在門戶中Metrics頁面中,點看CPU的指標資料後,通過F12(開發者工具),檢視具體使用的是什麼API, 並參考同樣的方式在Java 程式碼中呼叫該類介面來完成。

【Azure Developer】通過Azure提供的Azue Java JDK 查詢虛擬機器的CPU使用率和記憶體使用率

通常情況,是可以在Azure Monitor官網中(https://docs.microsoft.com/zh-cn/rest/api/monitor/)找到需要的REST API介面。如:

Metrics - List

列出資源的指標值。

GET https://management.azure.com/{resourceUri}/providers/microsoft.insights/metrics?api-version=2018-01-01
GET https://management.azure.com/{resourceUri}/providers/microsoft.insights/metrics?timespan={timespan}&interval={interval}&metricnames={metricnames}&aggregation={aggregation}&top={top}&orderby={orderby}&$filter={$filter}&resultType={resultType}&api-version=2018-01-01&metricnamespace={metricnamespace}

上文截圖中呼叫通過API獲取到的Metrics的URL引數值為:
"/subscriptions/<subscriptionid>/resourceGroups/<resource group>/providers/Microsoft.Compute/virtualMachines/<vm name>/providers/microsoft.Insights/metrics?
timespan=2020-11-24T22:03:01.141Z/2020-11-27T04:55:40.325Z
&interval=PT30M
&metricnames=Percentage CPU
&aggregation=average
&metricNamespace=microsoft.compute%2Fvirtualmachines
&autoadjusttimegrain=true
&validatedimensions=false
&api-version=2019-07-01
"

引數的詳細說明:

NameInRequiredTypeDescription
resourceUri
path True
  • string

資源的識別符號。

api-version
query True
  • string

客戶端 Api 版本。

$filter
query  
  • string

$filter用於減少返回的指標資料集。
示例:
指標包含後設資料 A、B 和 C。
- 返回所有時間序列 C,其中 A = a1 和 B = b1 或 b2
$filter_eq 'a1' 和 B eq 'b1' 或 B eq 'b2' 和 C eq '#'
- 無效變體:
$filter=eq 'a1'和 B eq 'b1' 和 C eq '*' 或 B = 'b2'
這是無效的,因為邏輯或運算子不能分隔兩個不同的後設資料名稱。
- 返回所有時間序列,其中 A = a1,B = b1 和 C = c1:
$filter=eq 'a1'和 B eq 'b1' 和 C eq 'c1'
- 返回所有時間序列,其中 A = a1
$filter_aq 'a1' 和 B eq '和 C eq''.

aggregation
query  
  • string

要檢索的聚合型別(逗號分隔)的列表。

interval
query  
  • string
duration

查詢的間隔(即時粒)。

metricnames
query  
  • string

要檢索的指標(逗號分隔)的名稱。

metricnamespace
query  
  • string

用於查詢指標定義的指標名稱空間。

orderby
query  
  • string

用於對結果進行排序的聚合和排序方向。 只能指定一個訂單。 示例:總和 asc。

resultType
query  

減少收集的資料集。 允許的語法取決於操作。 有關詳細資訊,請參閱操作說明。

timespan
query  
  • string

查詢的時間跨度。 它是具有以下格式"startDateTime_ISO/endDateTime_ISO"的字串。

top
query  
  • integer
int32

要檢索的最大記錄數。 僅在指定$filter時有效。 預設值為 10。


全文內容:https://docs.microsoft.com/zh-cn/rest/api/monitor/metrics/list

 

方式二:使用Azure VM診斷日誌 ——> Storage Table——> Java Code (Storage SDK)

開啟虛擬機器的診斷日誌,讓Azure VM把監控資料傳送到Storage Table中,通過Storage SDK直接獲取Table中的資料。

開啟診斷日誌

【Azure Developer】通過Azure提供的Azue Java JDK 查詢虛擬機器的CPU使用率和記憶體使用率

獲取Storage Table中資料的Java程式碼

檢索分割槽中的所有實體

若要對錶查詢分割槽中的實體,可以使用 TableQuery。 呼叫 TableQuery.from 可建立針對特定表的查詢,該查詢將返回指定的結果型別。 以下程式碼指定了一個篩選器,用於篩選其中的分割槽鍵是“Smith”的實體。 TableQuery.generateFilterCondition 是用於建立查詢篩選器的幫助程式方法。 對 TableQuery.from 方法返回的引用呼叫 where,以對查詢應用篩選器。 當通過呼叫 CloudTable 物件上的 execute 來執行查詢時,該查詢將返回指定了 CustomerEntity 結果型別的 Iterator。 然後,可以利用在“ForEach”迴圈中返回的 Iterator 來使用結果。 此程式碼會將查詢結果中每個實體的欄位列印到控制檯。

try
{
    // Define constants for filters.
    final String PARTITION_KEY = "PartitionKey";
    final String ROW_KEY = "RowKey";
    final String TIMESTAMP = "Timestamp";

    // Retrieve storage account from connection-string.
    CloudStorageAccount storageAccount =
        CloudStorageAccount.parse(storageConnectionString);

    // Create the table client.
    CloudTableClient tableClient = storageAccount.createCloudTableClient();

    // Create a cloud table object for the table.
    CloudTable cloudTable = tableClient.getTableReference("people");

    // Create a filter condition where the partition key is "Smith".
    String partitionFilter = TableQuery.generateFilterCondition(
        PARTITION_KEY,
        QueryComparisons.EQUAL,
        "Smith");

    // Specify a partition query, using "Smith" as the partition key filter.
    TableQuery<CustomerEntity> partitionQuery =
        TableQuery.from(CustomerEntity.class)
        .where(partitionFilter);

    // Loop through the results, displaying information about the entity.
    for (CustomerEntity entity : cloudTable.execute(partitionQuery)) {
        System.out.println(entity.getPartitionKey() +
            " " + entity.getRowKey() +
            "\t" + entity.getEmail() +
            "\t" + entity.getPhoneNumber());
    }
}
catch (Exception e)
{
    // Output the stack trace.
    e.printStackTrace();
}

 

參考資料


REST API 引用 Azure Monitor: https://docs.microsoft.com/zh-cn/rest/api/monitor/

如何通過 Java 使用 Azure 表儲存或 Azure Cosmos DB 表 API: https://docs.azure.cn/zh-cn/cosmos-db/table-storage-how-to-use-java?toc=https%3A%2F%2Fdocs.azure.cn%2Fzh-cn%2Fstorage%2Ftables%2Ftoc.json&bc=https%3A%2F%2Fdocs.azure.cn%2Fzh-cn%2Fbread%2Ftoc.json

 

附錄一:檢視Azure REST API的方法

【Azure Developer】通過Azure提供的Azue Java JDK 查詢虛擬機器的CPU使用率和記憶體使用率

 

附錄二:使用Java SDK直接獲取VM物件和VM物件中Mertics的程式碼https://github.com/Azure/azure-libraries-for-java/blob/master/azure-mgmt-monitor/src/test/java/com/microsoft/azure/management/monitor/MonitorActivityAndMetricsTests.java

/**
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License. See License.txt in the project root for
 * license information.
 */

package com.microsoft.azure.management.monitor;

import com.microsoft.azure.PagedList;
import com.microsoft.azure.management.compute.VirtualMachine;
import com.microsoft.azure.management.resources.fluentcore.utils.SdkContext;
import org.joda.time.DateTime;
import org.junit.Assert;
import org.junit.Test;

import java.util.List;

public class MonitorActivityAndMetricsTests extends MonitorManagementTest {
    @Test
    public void canListEventsAndMetrics() throws Exception {
        DateTime recordDateTime = SdkContext.dateTimeNow().minusDays(40);
        VirtualMachine vm = computeManager.virtualMachines().list().get(0);

        // Metric Definition
        List<MetricDefinition> mt = monitorManager.metricDefinitions().listByResource(vm.id());

        Assert.assertNotNull(mt);
        MetricDefinition mDef = mt.get(0);
        Assert.assertNotNull(mDef.metricAvailabilities());
        Assert.assertNotNull(mDef.namespace());
        Assert.assertNotNull(mDef.supportedAggregationTypes());

        // Metric
        MetricCollection metrics = mDef.defineQuery()
                .startingFrom(recordDateTime.minusDays(30))
                .endsBefore(recordDateTime)
                .withResultType(ResultType.DATA)
                .execute();

        Assert.assertNotNull(metrics);
        Assert.assertNotNull(metrics.namespace());
        Assert.assertNotNull(metrics.resourceRegion());
        Assert.assertEquals("Microsoft.Compute/virtualMachines", metrics.namespace());

 

相關文章