[博客遷移]探索Windows Azure 監控和自動伸縮系列2 - 獲取虛擬機的監控定義和監控數據

上一篇博文介紹瞭如何鏈接Windows Azure: http://www.cnblogs.com/teld/p/5113063.htmlhtml

本篇咱們繼續上次的示例代碼,獲取虛擬機的監控定義和監控數據。windows

有人會問,Azure Portal上已經有了監控數據,經過代碼獲取有意思嗎?咱們計劃基於性能計數器的監控數據來實現應用的自動伸縮,所以能夠獲取到監控指標定義和監控數據應該是第一步。api

在Azure的管理Portal中咱們能夠看到虛擬機的監控數據,目前,提供的主要有如下監控指標:app

CPU Percentage;Disk Read; Disk Write; Network in;NetWork Out。函數

Azure中監控的Nuget主要是這個:Microsoft Azure Management Libraries性能

核心的幾個namespace有:測試

咱們本篇用的是Metric這個命名空間,核心類MetricClient:ui

namespace AzureTest
{
    using Microsoft.WindowsAzure;
    using Microsoft.WindowsAzure.Management.Monitoring.Metrics;
    using Microsoft.WindowsAzure.Management.Monitoring.Metrics.Models;
    using Microsoft.WindowsAzure.Management.Monitoring.Utilities;

    /// <summary>
    /// 監控客戶端
    /// </summary>
    class MonitorClient
    {
        private SubscriptionCloudCredentials credentials;

        public MonitorClient(SubscriptionCloudCredentials credentials)
        {
            this.credentials = credentials;
        }

        /// <summary>
        /// 獲取全部的監控指標
        /// </summary>
        public void GetMetricDefinitions()
        {
            var metricsClient = new MetricsClient(credentials);
            // Build the resource ID string.
            var resourceId = ResourceIdBuilder.BuildVirtualMachineResourceId("cloudServiceName", "deploymentName");
            Console.WriteLine("Resource Id: {0}", resourceId);

            //Get the metric definitions.
            var metricListResponse=
                metricsClient.MetricDefinitions.List(resourceId, null, null);34 
            MetricDefinitionCollection metricDefinitions = metricListResponse.MetricDefinitionCollection;           
            // Display the metric definitions.
            int count = 0;
            foreach (MetricDefinition metricDefinition in metricDefinitions.Value)
            {
                Console.WriteLine("MetricDefinitio: " + count++);
                Console.WriteLine("Display Name: " + metricDefinition.DisplayName);
                Console.WriteLine("Metric Name: " + metricDefinition.Name);                
                Console.WriteLine("Metric Namespace: " + metricDefinition.Namespace);                
                Console.WriteLine("Is Altertable: " + metricDefinition.IsAlertable);
                Console.WriteLine("Min. Altertable Time Window: " + metricDefinition.MinimumAlertableTimeWindow);
                Console.WriteLine();
            }
        }
}
}

使用上一篇咱們的Azure 憑據驗證器,獲取一個令牌憑據TokenCloudCredentials,而後構造一個MonitorClient,獲取指定虛擬機的監控數據。this

static void Main(string[] args)
{            
      var credential = Authorizator.GetCredentials();
      var client = new MonitorClient(credential);
      client.GetMetricDefinitions();
      Console.ReadLine();
}

第一塊代碼中:spa

var resourceId = ResourceIdBuilder.BuildVirtualMachineResourceId("cloudServiceName", "deploymentName");

這個地方通ResourceIDBuilder獲取虛擬機的資源ID,對應的參數分別爲:cloudServiceName和deploymentName,第一個是虛擬機使用的雲服務名稱,第二個是虛擬機名稱便可。

Run...

出錯了:

{"ForbiddenError: The server failed to authenticate the request. Verify that the certificate is valid and is associated with this subscription."}

一番Google後未果,咋整,再分析下錯誤信息:

能夠看到,請求的Uri:

{https://management.core.windows.net/37*****-5107-*****-*******6/services/monitoring/metricdefinitions/query?&resourceId=%2Fhostedservices%2Fteldptapp%2Fdeployments%2Fteldptapp}

請求又跑到Azure Global那去了。

這個錯誤困擾了很久,還在StackOverflow上發了英文諮詢貼,不知道洋人們如何回答了。在此多謝鞠強老大的指導,想辦法將請求的Uri定位到中國區的Azure。

從新分析了代碼,找到了Monitor的構造函數中,能夠指定Uri,將中國區Azure的Uri指定一下:https://management.core.chinacloudapi.cn

MetricsClient metricsClient = new MetricsClient(credentials, new Uri("https://management.core.chinacloudapi.cn/"));

測試經過,ok。

獲取到了監控指標定義,接下來咱們獲取監控數據:

namespace AzureTest
{
    using Microsoft.WindowsAzure;
    using Microsoft.WindowsAzure.Management.Monitoring.Metrics;
    using Microsoft.WindowsAzure.Management.Monitoring.Metrics.Models;
    using Microsoft.WindowsAzure.Management.Monitoring.Utilities;
    /// <summary>
    /// 監控客戶端
    /// </summary>
    class MonitorClient
    {
        private SubscriptionCloudCredentials credentials;

        public MonitorClient(SubscriptionCloudCredentials credentials)
        {
            this.credentials = credentials;
        }

        /// <summary>
        /// 獲取全部的監控指標數據
        /// </summary>
        public void GetMetricData()
        {
            var metricsClient = new MetricsClient(credentials, new Uri("https://management.core.chinacloudapi.cn/"));
            
            // Build the resource ID string.
            var resourceId = ResourceIdBuilder.BuildVirtualMachineResourceId("cloudServiceName", "deploymentName");
            Console.WriteLine("Resource Id: {0}", resourceId);

            //Get the metric definitions.
            var metricListResponse = metricsClient.MetricDefinitions.List(resourceId, null, null);
            MetricDefinitionCollection metricDefinitions = metricListResponse.MetricDefinitionCollection;
            
            var metricNamespace = "";
            var metricNames = new List<string>();
            // Display the metric definitions.
            int count = 0;
            foreach (MetricDefinition metricDefinition in metricDefinitions.Value)
            {
                Console.WriteLine("MetricDefinitio: " + count++);
                Console.WriteLine("Display Name: " + metricDefinition.DisplayName);
                Console.WriteLine("Metric Name: " + metricDefinition.Name);
                if (!metricNames.Contains(metricDefinition.Name))
                    metricNames.Add(metricDefinition.Name);
                Console.WriteLine("Metric Namespace: " + metricDefinition.Namespace);
                metricNamespace = metricDefinition.Namespace;
                Console.WriteLine("Is Altertable: " + metricDefinition.IsAlertable);
                Console.WriteLine("Min. Altertable Time Window: " + metricDefinition.MinimumAlertableTimeWindow);
                Console.WriteLine();
            }

            // timeGrain must be 5, 60 or 720 minutes.
            TimeSpan timeGrain = TimeSpan.FromMinutes(5);
            DateTime startTime = DateTime.UtcNow.AddHours(-1);
            DateTime endTime = DateTime.UtcNow;

            MetricValueListResponse response = metricsClient.MetricValues.List(resourceId, metricNames, metricNamespace, timeGrain, startTime, endTime);

            foreach (MetricValueSet value in response.MetricValueSetCollection.Value)
            {
                String valueName = value.Name;
                Console.WriteLine("MetricValue:{0}", valueName);
                foreach (MetricValue metricValue in value.MetricValues)
                {
                    Console.WriteLine("Maximum:{0}{1}", metricValue.Maximum, value.Unit);
                    Console.WriteLine("Average:{0}{1}", metricValue.Average, value.Unit);
                    Console.WriteLine("Minimum:{0}{1}", metricValue.Minimum, value.Unit);
                }
            }
        }
    }
}

Run...

程序在metricsClient.MetricValues.List(resourceId, metricNames, metricNamespace, timeGrain, startTime, endTime);

出錯了:
Additional information: <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">{"Code":"InvalidRequest","Message":"Could not retrieve metrics."}</string>

爲啥不能獲取監控指標呢?

這個錯誤,Google一番依舊未果,諮詢了微軟的技術工程師,給了以下指導,resouceID必須執行RoleName:

var resourceId = ResourceIdBuilder.BuildVirtualMachineResourceId("cloudService", "deploymentName", "roleName");

修改以後,問題解決。

至此,咱們已經能夠獲取到監控指標和監控數據,下一步咱們要獲取自定義的性能計數器,基於自定義的性能計數器來實現自動伸縮。

 

周國慶

2016/3

相關文章
相關標籤/搜索