[博客迁移]探索Windows Azure 监控和自动伸缩系列2 - 获取虚拟机的监控定义和监控数据

上一篇博文介绍了如何连接Windows Azure: http://www.cnblogs.com/teld/p/5113063.html

本篇我们继续上次的示例代码,获取虚拟机的监控定义和监控数据。

有人会问,Azure Portal上已经有了监控数据,通过代码获取有意思吗?我们计划基于性能计数器的监控数据来实现应用的自动伸缩,因此可以获取到监控指标定义和监控数据应该是第一步。

在Azure的管理Portal中我们可以看到虚拟机的监控数据,目前,提供的主要有以下监控指标:

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

Azure中监控的Nuget主要是这个:Microsoft Azure Management Libraries

核心的几个namespace有:

我们本篇用的是Metric这个命名空间,核心类MetricClient:

namespace AzureTest
{
    using Microsoft.WindowsAzure;
     Microsoft.WindowsAzure.Management.Monitoring.Metrics;
     Microsoft.WindowsAzure.Management.Monitoring.Metrics.Models;
     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,获取指定虚拟机的监控数据。

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

第一块代码中:

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,1)">new Uri(https://management.core.chinacloudapi.cn/"));

测试通过,ok。

获取到了监控指标定义,接下来我们获取监控数据:

 Microsoft.WindowsAzure.Management.Monitoring.Utilities;
     获取所有的监控指标数据
         GetMetricData()
        {
            ));
            
            var metricListResponse = metricsClient.MetricDefinitions.List(resourceId,1)">null);
            MetricDefinitionCollection metricDefinitions = metricListResponse.MetricDefinitionCollection;
            
            var metricNamespace = ""var metricNames = new List<string>();
             metricDefinition.Name);
                if (!metricNames.Contains(metricDefinition.Name))
                    metricNames.Add(metricDefinition.Name);
                Console.WriteLine( metricDefinition.Namespace);
                metricNamespace = metricDefinition.Namespace;
                Console.WriteLine( 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  response.MetricValueSetCollection.Value)
            {
                String valueName = value.Name;
                Console.WriteLine(MetricValue:{0}foreach (MetricValue metricValue  value.MetricValues)
                {
                    Console.WriteLine(Maximum:{0}{1}Average:{0}{1}Minimum:{0}{1}

为啥不能获取监控指标呢?

这个错误,Google一番依旧未果,咨询了微软的技术工程师,给了如下指导,resouceID必须执行RoleName:

cloudServiceroleName");

修改之后,问题解决。

至此,我们已经可以获取到监控指标和监控数据,下一步我们要获取自定义的性能计数器,基于自定义的性能计数器来实现自动伸缩。

 

周国庆

2016/3

相关文章

Microsoft云包括了Azure、PowerPlatform、Microsoft365、Git...
《WindowsAzurePlatform系列文章目录》 我们在使用AzureAPI...
微软免费使用一年的Azure虚拟机,默认提供了一个64G的磁盘,...
上篇请访问这里做一个能对标阿里云的前端APM工具(上)样本多...
一年一度的MicrosoftBuild终于来了,带来了非常非常多的新技...