Example #1
0
 private void LogEndGetMetrics(string invocationId, MetricListResponse result)
 {
     if (TracingAdapter.IsEnabled)
     {
         TracingAdapter.Exit(invocationId, result);
     }
 }
Example #2
0
 private void LogEndGetMetrics(string invocationId, MetricListResponse result)
 {
     if (CloudContext.Configuration.Tracing.IsEnabled)
     {
         Tracing.Exit(invocationId, result);
     }
 }
Example #3
0
        public async Task <MetricListResponse> GetTelemetryVolume()

        {
            string token = await GetAuthenticationHeader();

            string subscriptionID = "36dfc234-9a2d-4f33-be43-db6e321dbc2bss";

            TokenCloudCredentials credentials = new TokenCloudCredentials(subscriptionID, token);

            string resourceUri = "/subscriptions/dd0db424-9a49-408d-911e-67e398aaaa3a/resourceGroups/artrejo-scaledemo2/providers/Microsoft.DocumentDB/databaseAccounts/artrejo-scaledemo2";

            //string filter = null;
            TimeSpan           period       = new TimeSpan(0, 0, 0, 30, 0);
            string             filter       = "(name.value eq 'Total Requests')";
            MetricListResponse vmMetricList = GetResourceMetrics(credentials, resourceUri, filter, TimeSpan.FromHours(1), "PT5M");

            // LINQ Query
            //            var metricValuesQuery = vmMetricList.MetricCollection.Value.FirstOrDefault().MetricValues.Select(metricValue => metricValue.Total.Value);
            //            var metricValuesQuery = vmMetricList.MetricCollection.Value.FirstOrDefault().MetricValues.Select(metricValue => metricValue.Total.Value);
            //var metricValuesQuery = vmMetricList.MetricCollection.Value.FirstOrDefault().MetricValues;
            //var metricValuesQuery = vmMetricList;


            //MetricDefinitionListResponse list = GetAvailableMetricDefinitions(credentials, resourceUri);
            // MetricListResponse list = GetResourceMetrics(credentials, resourceUri, filter, period, duration);

            //return metricValuesQuery.ToArray();
            return(vmMetricList);
        }
Example #4
0
        public async Task <JsonResult> GetGraphData()
        {
            GraphModel data   = new GraphModel();
            Random     random = new Random();
            int        value_activeincidentsovertime    = random.Next(20, 40);
            int        value_maxtimetomitigateincidents = random.Next(10, 80);

            // int value_telemetryvolume = random.Next(50, 500); //need to get value from db

            MetricListResponse value_telemetryvolume = await GetTelemetryVolume();

            int    value_noofincidents = random.Next(20, 40);
            double value_activeusers   = random.NextDouble(45.12, 51.21);
            double value_traficrequest = random.NextDouble(1.00, 1.50);

            data.telemetryvolume                   = value_telemetryvolume;
            data.noofincidents                     = value_activeincidentsovertime;
            data.maxtimetomitigateincidents        = value_maxtimetomitigateincidents;
            data.percentageoftimethesystemviolated = 5;
            data.activeincidentsovertime           = value_activeincidentsovertime;
            data.activeusers   = value_activeusers;
            data.traficrequest = value_traficrequest;
            List <GraphModel> listdata = new List <GraphModel>();

            listdata.Add(data);

            return(Json(new { items = listdata, success = true }, JsonRequestBehavior.AllowGet));
        }
Example #5
0
        /// <summary>
        /// Execute the cmdlet
        /// </summary>
        protected override void ExecuteCmdletInternal()
        {
            string queryFilter = this.ProcessParameters();
            bool   fullDetails = this.DetailedOutput.IsPresent;

            // Call the proper API methods to return a list of raw records.
            // If fullDetails is present full details of the records displayed, otherwise only a summary of the values is displayed
            MetricListResponse response = this.InsightsClient.MetricOperations.GetMetricsAsync(resourceUri: this.ResourceId, filterString: queryFilter, cancellationToken: CancellationToken.None).Result;
            var records = response.MetricCollection.Value.Select(e => fullDetails ? (Metric) new PSMetric(e) : new PSMetricNoDetails(e)).ToArray();

            WriteObject(sendToPipeline: records);
        }
        private static void PrintMetricValues(MetricListResponse metricList)
        {
            foreach (Metric m in metricList.MetricCollection.Value)
            {
                Console.WriteLine("Metric: {0}", m.Name.Value);
                foreach (MetricValue metricValue in m.MetricValues)
                {
                    Console.WriteLine("{0} - {1}", metricValue.Timestamp, metricValue.Average);
                }

                Console.WriteLine();
            }
        }
        static void Main(string[] args)
        {
            _subscriptionId          = ConfigurationManager.AppSettings["AzureSubscriptionId"];
            _tenantId                = ConfigurationManager.AppSettings["AzureADTenantId"];
            _applicationId           = ConfigurationManager.AppSettings["AzureADApplicationId"];
            _applicationPwd          = ConfigurationManager.AppSettings["AzureADApplicationPassword"];
            _webAppResourceGroupName = ConfigurationManager.AppSettings["AzureWebAppResourceGroupName"];
            _siteName                = ConfigurationManager.AppSettings["AzureWebAppName"];
            _vmResourceGroupName     = ConfigurationManager.AppSettings["AzureClassicVmResourceGroupName"];
            _vmName = ConfigurationManager.AppSettings["AzureClassicVmName"];


            string webAppResourceUri    = string.Format(WebAppResourceUriFormat, _subscriptionId, _webAppResourceGroupName, _siteName);
            string classicVmResourceUri = string.Format(VirtualMachineResourceUriFormat, _subscriptionId, _vmResourceGroupName, _vmName);

            var token = GetAccessToken();
            var creds = new TokenCloudCredentials(_subscriptionId, token);

            /* Web App */
            Console.WriteLine("--------- List available Web App metric definitions ---------");

            MetricDefinitionListResponse webMetricDefinitions = GetAvailableMetricDefinitions(creds, webAppResourceUri);

            PrintMetricDefinitions(webMetricDefinitions);

            Console.WriteLine("--------- List Web App metrics ---------");

            MetricListResponse webMetricList = GetResourceMetrics(creds, webAppResourceUri, string.Empty, TimeSpan.FromHours(1), "PT1M");

            PrintMetricValues(webMetricList);


            /* Classic Virtual Machine */
            Console.WriteLine("--------- List Classic Compute metrics ---------");

            MetricDefinitionListResponse vmMetricDefinitions = GetAvailableMetricDefinitions(creds, classicVmResourceUri);

            PrintMetricDefinitions(vmMetricDefinitions);

            string             filter       = "(name.value eq 'Percentage CPU' or name.value eq 'Network In')";
            MetricListResponse vmMetricList = GetResourceMetrics(creds, classicVmResourceUri, filter, TimeSpan.FromHours(1), "PT5M");

            PrintMetricValues(vmMetricList);



            Console.WriteLine("Press any key to exit!");
            Console.ReadLine();
        }
        /// <summary>
        /// Execute the cmdlet
        /// </summary>
        protected override void ProcessRecordInternal()
        {
            WriteWarning("This cmdlet is being modified to enable better experience and may contain breaking changes in a future release.");

            string queryFilter = this.ProcessParameters();
            bool   fullDetails = this.DetailedOutput.IsPresent;

            // Call the proper API methods to return a list of raw records.
            // If fullDetails is present full details of the records displayed, otherwise only a summary of the values is displayed
            MetricListResponse response = this.InsightsClient.MetricOperations.GetMetricsAsync(resourceUri: this.ResourceId, filterString: queryFilter, cancellationToken: CancellationToken.None).Result;

            var records = response.MetricCollection.Value.Select(e => fullDetails ? (Metric) new PSMetric(e) : new PSMetricNoDetails(e)).ToArray();

            WriteObject(sendToPipeline: records);
        }
        public void GetMetricsTest()
        {
            MetricCollection expectedMetricCollection = GetMetricCollection(ResourceUri);

            var response = new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new StringContent(expectedMetricCollection.ToJson())
            };

            RecordedDelegatingHandler handler = new RecordedDelegatingHandler(response);
            var insightsClient = GetInsightsClient(handler);

            string             filterString  = "timeGrain eq duration'PT1M' and startTime eq 2014-01-01T06:00:00Z and endTime eq 2014-01-10T06:00:00Z";
            MetricListResponse actualMetrics = (insightsClient.MetricOperations as MetricOperations)
                                               .GetMetricsAsync(
                ResourceUri,
                filterString,
                CancellationToken.None).Result;

            AreEqual(expectedMetricCollection, actualMetrics.MetricCollection);
        }
Example #10
0
        private static void ShowMetrics(MetricListResponse result)
        {
            string metricforTime = "";

            foreach (var metric in result.MetricCollection.Value)
            {
                Console.Write(metric.Name.Value + ":   \t");
                foreach (var value in metric.MetricValues)
                {
                    Console.Write(value.Maximum + "/" + value.Average + "\t");
                }
                Console.WriteLine("");
                if (metric.MetricValues.Count == 0)
                {
                    Console.WriteLine("-= No data in resultset =-");
                    return;
                }
                metricforTime = metric.MetricValues.Last().Timestamp.ToString("HH:mm:ss");
            }
            Console.WriteLine("Request: {1} -> Last metric time: {0} UTC", metricforTime, DateTime.UtcNow.ToString("HH:mm:ss"));
        }
        public GetAzureRmMetricTests()
        {
            insightsMetricOperationsMock = new Mock <IMetricOperations>();
            insightsClientMock           = new Mock <InsightsClient>();
            commandRuntimeMock           = new Mock <ICommandRuntime>();
            cmdlet = new GetAzureRmMetricCommand()
            {
                CommandRuntime = commandRuntimeMock.Object,
                InsightsClient = insightsClientMock.Object
            };

            response = Utilities.InitializeMetricResponse();

            insightsMetricOperationsMock.Setup(f => f.GetMetricsAsync(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult <MetricListResponse>(response))
            .Callback((string f, string s, CancellationToken t) =>
            {
                resourceId = f;
                filter     = s;
            });

            insightsClientMock.SetupGet(f => f.MetricOperations).Returns(this.insightsMetricOperationsMock.Object);
        }
        public GetAzureRmMetricTests(Xunit.Abstractions.ITestOutputHelper output)
        {
            ServiceManagemenet.Common.Models.XunitTracingInterceptor.AddToContext(new ServiceManagemenet.Common.Models.XunitTracingInterceptor(output));
            insightsMetricOperationsMock = new Mock <IMetricOperations>();
            insightsClientMock           = new Mock <InsightsClient>();
            commandRuntimeMock           = new Mock <ICommandRuntime>();
            cmdlet = new GetAzureRmMetricCommand()
            {
                CommandRuntime = commandRuntimeMock.Object,
                //InsightsClient = insightsClientMock.Object
            };

            response = Utilities.InitializeMetricResponse();

            insightsMetricOperationsMock.Setup(f => f.GetMetricsAsync(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult <MetricListResponse>(response))
            .Callback((string f, string s, CancellationToken t) =>
            {
                resourceId = f;
                filter     = s;
            });

            insightsClientMock.SetupGet(f => f.MetricOperations).Returns(this.insightsMetricOperationsMock.Object);
        }
        public async Task <MetricListResponse> GetMetricsAsync(string resourceUri, string filterString, CancellationToken cancellationToken)
        {
            // Ensure exactly one '/' at the start
            resourceUri = '/' + resourceUri.TrimStart('/');

            // Generate filter strings
            MetricFilter filter                 = MetricFilterExpressionParser.Parse(filterString);
            string       metricFilterString     = GenerateNamelessMetricFilterString(filter);
            string       definitionFilterString = filter.DimensionFilters == null ? null
                : ShoeboxHelper.GenerateMetricDefinitionFilterString(filter.DimensionFilters.Select(df => df.Name));

            // Get definitions for requested metrics
            IList <MetricDefinition> definitions =
                (await this.Client.MetricDefinitionOperations.GetMetricDefinitionsAsync(
                     resourceUri,
                     definitionFilterString,
                     cancellationToken).ConfigureAwait(false)).MetricDefinitionCollection.Value;

            // Separate passthrough metrics with dimensions specified
            IEnumerable <MetricDefinition> passthruDefinitions = definitions.Where(d => !IsShoebox(d, filter.TimeGrain));
            IEnumerable <MetricDefinition> shoeboxDefinitions  = definitions.Where(d => IsShoebox(d, filter.TimeGrain));

            // Get Passthru definitions
            List <Metric> passthruMetrics = new List <Metric>();
            string        invocationId    = TracingAdapter.NextInvocationId.ToString(CultureInfo.InvariantCulture);

            this.LogStartGetMetrics(invocationId, resourceUri, filterString, passthruDefinitions);
            if (passthruDefinitions.Any())
            {
                // Create new filter for passthru metrics
                List <MetricDimension> passthruDimensionFilters = filter.DimensionFilters == null ? new List <MetricDimension>() :
                                                                  filter.DimensionFilters.Where(df => passthruDefinitions.Any(d => string.Equals(d.Name.Value, df.Name, StringComparison.OrdinalIgnoreCase))).ToList();

                foreach (MetricDefinition def in passthruDefinitions
                         .Where(d => !passthruDimensionFilters.Any(pdf => string.Equals(pdf.Name, d.Name.Value, StringComparison.OrdinalIgnoreCase))))
                {
                    passthruDimensionFilters.Add(new MetricDimension()
                    {
                        Name = def.Name.Value
                    });
                }

                MetricFilter passthruFilter = new MetricFilter()
                {
                    TimeGrain        = filter.TimeGrain,
                    StartTime        = filter.StartTime,
                    EndTime          = filter.EndTime,
                    DimensionFilters = passthruDimensionFilters
                };

                // Create passthru filter string
                string passthruFilterString = ShoeboxHelper.GenerateMetricFilterString(passthruFilter);

                // Get Metrics from passthrough (hydra) client
                MetricListResponse passthruResponse = await this.GetMetricsInternalAsync(resourceUri, passthruFilterString, cancellationToken).ConfigureAwait(false);

                passthruMetrics = passthruResponse.MetricCollection.Value.ToList();

                this.LogMetricCountFromResponses(invocationId, passthruMetrics.Count());

                // Fill in values (resourceUri, displayName, unit) from definitions
                CompleteShoeboxMetrics(passthruMetrics, passthruDefinitions, resourceUri);

                // Add empty objects for metrics that had no values come back, ensuring a metric is returned for each definition
                IEnumerable <Metric> emptyMetrics = passthruDefinitions
                                                    .Where(d => !passthruMetrics.Any(m => string.Equals(m.Name.Value, d.Name.Value, StringComparison.OrdinalIgnoreCase)))
                                                    .Select(d => new Metric()
                {
                    Name         = d.Name,
                    Unit         = d.Unit,
                    ResourceId   = resourceUri,
                    StartTime    = filter.StartTime,
                    EndTime      = filter.EndTime,
                    TimeGrain    = filter.TimeGrain,
                    MetricValues = new List <MetricValue>(),
                    Properties   = new Dictionary <string, string>()
                });

                passthruMetrics.AddRange(emptyMetrics);
            }

            // Get Metrics by definitions
            MetricListResponse shoeboxResponse = await this.GetMetricsAsync(resourceUri, metricFilterString, shoeboxDefinitions, cancellationToken).ConfigureAwait(false);

            // Create response (merge and wrap metrics)
            MetricListResponse result = new MetricListResponse()
            {
                RequestId        = Guid.NewGuid().ToString("D"),
                StatusCode       = HttpStatusCode.OK,
                MetricCollection = new MetricCollection()
                {
                    Value = passthruMetrics.Union(shoeboxResponse.MetricCollection.Value).ToList()
                }
            };

            this.LogEndGetMetrics(invocationId, result);

            return(result);
        }
        // Alternate method for getting metrics by passing in the definitions
        // TODO [davmc]: Revisit - this method cannot support dimensions
        public async Task <MetricListResponse> GetMetricsAsync(
            string resourceUri, string filterString, IEnumerable <MetricDefinition> definitions, CancellationToken cancellationToken)
        {
            MetricListResponse result;

            if (definitions == null)
            {
                throw new ArgumentNullException("definitions");
            }

            string invocationId = TracingAdapter.NextInvocationId.ToString(CultureInfo.InvariantCulture);

            this.LogStartGetMetrics(invocationId, resourceUri, filterString, definitions);

            // If no definitions provided, return empty collection
            if (!definitions.Any())
            {
                result = new MetricListResponse()
                {
                    RequestId  = Guid.NewGuid().ToString("D"),
                    StatusCode = HttpStatusCode.OK
                };

                this.LogEndGetMetrics(invocationId, result);

                return(result);
            }

            // Parse MetricFilter
            MetricFilter filter = MetricFilterExpressionParser.Parse(filterString);

            // Names not allowed in filter since the names are in the definitions
            if (filter.DimensionFilters != null && filter.DimensionFilters.Any())
            {
                throw new ArgumentException("Cannot specify names (or dimensions) when MetricDefinitions are included", "filterString");
            }

            // Ensure every definition has at least one availability matching the filter timegrain
            if (!definitions.All(d => d.MetricAvailabilities.Any(a => a.TimeGrain == filter.TimeGrain)))
            {
                throw new ArgumentException("Definition contains no availability for the timeGrain requested", "definitions");
            }

            // Group definitions by location so we can make one request to each location
            Dictionary <MetricAvailability, MetricFilter> groups =
                definitions.GroupBy(d => d.MetricAvailabilities.First(a => a.TimeGrain == filter.TimeGrain),
                                    new AvailabilityComparer()).ToDictionary(g => g.Key, g => new MetricFilter()
            {
                TimeGrain        = filter.TimeGrain,
                StartTime        = filter.StartTime,
                EndTime          = filter.EndTime,
                DimensionFilters = g.Select(d => new MetricDimension()
                {
                    Name = d.Name.Value
                })
            });

            // Get Metrics from each location (group)
            IEnumerable <Task <MetricListResponse> > locationTasks = groups.Select(g => g.Key.Location == null
                    ? this.GetMetricsInternalAsync(resourceUri, ShoeboxHelper.GenerateMetricFilterString(g.Value), cancellationToken)
                    : ShoeboxClient.GetMetricsInternalAsync(g.Value, g.Key.Location, invocationId));

            // Aggregate metrics from all groups
            MetricListResponse[] results = (await Task.Factory.ContinueWhenAll(locationTasks.ToArray(), tasks => tasks.Select(t => t.Result))).ToArray();
            IEnumerable <Metric> metrics = results.Aggregate <MetricListResponse, IEnumerable <Metric> >(
                new List <Metric>(), (list, response) => list.Union(response.MetricCollection.Value));

            this.LogMetricCountFromResponses(invocationId, metrics.Count());

            // Fill in values (resourceUri, displayName, unit) from definitions
            CompleteShoeboxMetrics(metrics, definitions, resourceUri);

            // Add empty objects for metrics that had no values come back, ensuring a metric is returned for each definition
            IEnumerable <Metric> emptyMetrics = definitions
                                                .Where(d => !metrics.Any(m => string.Equals(m.Name.Value, d.Name.Value, StringComparison.OrdinalIgnoreCase)))
                                                .Select(d => new Metric()
            {
                Name         = d.Name,
                Unit         = d.Unit,
                ResourceId   = resourceUri,
                StartTime    = filter.StartTime,
                EndTime      = filter.EndTime,
                TimeGrain    = filter.TimeGrain,
                MetricValues = new List <MetricValue>(),
                Properties   = new Dictionary <string, string>()
            });

            // Create response (merge and wrap metrics)
            result = new MetricListResponse()
            {
                RequestId        = Guid.NewGuid().ToString("D"),
                StatusCode       = HttpStatusCode.OK,
                MetricCollection = new MetricCollection()
                {
                    Value = metrics.Union(emptyMetrics).ToList()
                }
            };

            this.LogEndGetMetrics(invocationId, result);

            return(result);
        }
Example #15
0
        // Alternate method for getting metrics by passing in the definitions
        public async Task <MetricListResponse> GetMetricsAsync(
            string resourceUri, string filterString, IEnumerable <MetricDefinition> definitions, CancellationToken cancellationToken)
        {
            if (definitions == null)
            {
                throw new ArgumentNullException("definitions");
            }

            if (resourceUri == null)
            {
                throw new ArgumentNullException("resourceUri");
            }

            // Remove any '/' characters from the start since these are handled by the hydra (thin) client
            // Don't encode Uri segments here since this will mess up the SAS retrievers (they use the resourceUri directly)
            resourceUri = resourceUri.TrimStart('/');

            MetricListResponse result;
            string             invocationId = TracingAdapter.NextInvocationId.ToString(CultureInfo.InvariantCulture);

            // If no definitions provided, return empty collection
            if (!definitions.Any())
            {
                this.LogStartGetMetrics(invocationId, resourceUri, filterString, definitions);
                result = new MetricListResponse()
                {
                    RequestId        = Guid.NewGuid().ToString("D"),
                    StatusCode       = HttpStatusCode.OK,
                    MetricCollection = new MetricCollection()
                    {
                        Value = new Metric[0]
                    }
                };

                this.LogEndGetMetrics(invocationId, result);

                return(result);
            }

            // Parse MetricFilter
            MetricFilter filter = MetricFilterExpressionParser.Parse(filterString);

            // Names in filter must match the names in the definitions
            if (filter.DimensionFilters != null && filter.DimensionFilters.Any())
            {
                IEnumerable <string> filterNames     = filter.DimensionFilters.Select(df => df.Name);
                IEnumerable <string> definitionNames = definitions.Select(d => d.Name.Value);
                IEnumerable <string> filterOnly      = filterNames.Where(fn => !definitionNames.Contains(fn, StringComparer.InvariantCultureIgnoreCase));
                IEnumerable <string> definitionOnly  = definitionNames.Where(df => !filterNames.Contains(df, StringComparer.InvariantCultureIgnoreCase));

                if (filterOnly.Any() || definitionOnly.Any())
                {
                    throw new ArgumentException("Set of names specified in filter string must match set of names in provided definitions", "filterString");
                }

                // "Filter out" metrics with unsupported dimensions
                definitions = definitions.Where(d => SupportsRequestedDimensions(d, filter));
            }
            else
            {
                filter = new MetricFilter()
                {
                    TimeGrain        = filter.TimeGrain,
                    StartTime        = filter.StartTime,
                    EndTime          = filter.EndTime,
                    DimensionFilters = definitions.Select(d => new MetricDimension()
                    {
                        Name = d.Name.Value
                    })
                };
            }

            // Parse out provider name and determine if provider is storage
            string providerName      = this.GetProviderFromResourceId(resourceUri);
            bool   isStorageProvider =
                string.Equals(providerName, "Microsoft.Storage", StringComparison.OrdinalIgnoreCase) ||
                string.Equals(providerName, "Microsoft.ClassicStorage", StringComparison.OrdinalIgnoreCase);

            // Create supported MetricRetrievers
            IMetricRetriever proxyRetriever             = new ProxyMetricRetriever(this);
            IMetricRetriever shoeboxRetriever           = new ShoeboxMetricRetriever();
            IMetricRetriever storageRetriever           = new StorageMetricRetriever();
            IMetricRetriever blobShoeboxMetricRetriever = new BlobShoeboxMetricRetriever();
            IMetricRetriever emptyRetriever             = EmptyMetricRetriever.Instance;

            // Create the selector function here so it has access to the retrievers, filter, and providerName
            Func <MetricDefinition, IMetricRetriever> retrieverSelector = (d) =>
            {
                if (!d.MetricAvailabilities.Any())
                {
                    return(emptyRetriever);
                }

                if (isStorageProvider)
                {
                    return(storageRetriever);
                }

                if (IsBlobSasMetric(d, filter.TimeGrain))
                {
                    return(blobShoeboxMetricRetriever);
                }

                if (IsTableSasMetric(d, filter.TimeGrain))
                {
                    return(shoeboxRetriever);
                }

                return(proxyRetriever);
            };

            // Group definitions by retriever so we can make one request to each retriever
            IEnumerable <IGrouping <IMetricRetriever, MetricDefinition> > groups = definitions.GroupBy(retrieverSelector);

            // Get Metrics from each retriever (group)
            IEnumerable <Task <MetricListResponse> > locationTasks = groups.Select(g =>
                                                                                   g.Key.GetMetricsAsync(resourceUri, GetFilterStringForDefinitions(filter, g), g, invocationId));

            // Aggregate metrics from all groups
            this.LogStartGetMetrics(invocationId, resourceUri, filterString, definitions);
            MetricListResponse[] results = (await Task.Factory.ContinueWhenAll(locationTasks.ToArray(), tasks => tasks.Select(t => t.Result))).ToArray();
            IEnumerable <Metric> metrics = results.Aggregate <MetricListResponse, IEnumerable <Metric> >(
                new List <Metric>(), (list, response) => list.Union(response.MetricCollection.Value));

            this.LogMetricCountFromResponses(invocationId, metrics.Count());

            // Fill in values (resourceUri, displayName, unit) from definitions
            CompleteShoeboxMetrics(metrics, definitions, resourceUri);

            // Add empty objects for metrics that had no values come back, ensuring a metric is returned for each definition
            IEnumerable <Metric> emptyMetrics = (await emptyRetriever.GetMetricsAsync(
                                                     resourceUri,
                                                     filterString,
                                                     definitions.Where(d => !metrics.Any(m => string.Equals(m.Name.Value, d.Name.Value, StringComparison.OrdinalIgnoreCase))),
                                                     invocationId)).MetricCollection.Value;

            // Create response (merge and wrap metrics)
            result = new MetricListResponse()
            {
                RequestId        = Guid.NewGuid().ToString("D"),
                StatusCode       = HttpStatusCode.OK,
                MetricCollection = new MetricCollection()
                {
                    Value = metrics.Union(emptyMetrics).ToList()
                }
            };

            this.LogEndGetMetrics(invocationId, result);

            return(result);
        }
        /// <summary>
        /// The List Metric operation lists the metric value sets for the
        /// resource metrics.
        /// </summary>
        /// <param name='resourceUri'>
        /// Required. The uri of the target resource to get metrics for.
        /// </param>
        /// <param name='filterString'>
        /// Required. An OData $filter expression that supports querying by the
        /// name of the metric definition.
        /// </param>
        /// <param name='cancellationToken'>
        /// Cancellation token.
        /// </param>
        /// <returns>
        /// The List Metric values operation response.
        /// </returns>
        public async Task <MetricListResponse> GetMetricsInternalAsync(string resourceUri, string filterString, CancellationToken cancellationToken)
        {
            // Validate
            if (resourceUri == null)
            {
                throw new ArgumentNullException("resourceUri");
            }

            // Tracing
            bool   shouldTrace  = CloudContext.Configuration.Tracing.IsEnabled;
            string invocationId = null;

            if (shouldTrace)
            {
                invocationId = Tracing.NextInvocationId.ToString();
                Dictionary <string, object> tracingParameters = new Dictionary <string, object>();
                tracingParameters.Add("resourceUri", resourceUri);
                tracingParameters.Add("filterString", filterString);
                Tracing.Enter(invocationId, this, "GetMetricsAsync", tracingParameters);
            }

            // Construct URL
            string url = "/" + resourceUri.Trim() + "/metrics?";

            url = url + "api-version=2014-04-01";
            if (filterString != null)
            {
                url = url + "&$filter=" + Uri.EscapeDataString(filterString != null ? filterString.Trim() : "");
            }
            string baseUrl = this.Client.BaseUri.AbsoluteUri;

            // Trim '/' character from the end of baseUrl and beginning of url.
            if (baseUrl[baseUrl.Length - 1] == '/')
            {
                baseUrl = baseUrl.Substring(0, baseUrl.Length - 1);
            }
            if (url[0] == '/')
            {
                url = url.Substring(1);
            }
            url = baseUrl + "/" + url;
            url = url.Replace(" ", "%20");

            // Create HTTP transport objects
            HttpRequestMessage httpRequest = null;

            try
            {
                httpRequest            = new HttpRequestMessage();
                httpRequest.Method     = HttpMethod.Get;
                httpRequest.RequestUri = new Uri(url);

                // Set Headers
                httpRequest.Headers.Add("Accept", "application/json");
                httpRequest.Headers.Add("x-ms-version", "2014-04-01");

                // Set Credentials
                cancellationToken.ThrowIfCancellationRequested();
                await this.Client.Credentials.ProcessHttpRequestAsync(httpRequest, cancellationToken).ConfigureAwait(false);

                // Send Request
                HttpResponseMessage httpResponse = null;
                try
                {
                    if (shouldTrace)
                    {
                        Tracing.SendRequest(invocationId, httpRequest);
                    }
                    cancellationToken.ThrowIfCancellationRequested();
                    httpResponse = await this.Client.HttpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false);

                    if (shouldTrace)
                    {
                        Tracing.ReceiveResponse(invocationId, httpResponse);
                    }
                    HttpStatusCode statusCode = httpResponse.StatusCode;
                    if (statusCode != HttpStatusCode.OK)
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                        CloudException ex = CloudException.Create(httpRequest, null, httpResponse, await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false));
                        if (shouldTrace)
                        {
                            Tracing.Error(invocationId, ex);
                        }
                        throw ex;
                    }

                    // Create Result
                    MetricListResponse result = null;
                    // Deserialize Response
                    cancellationToken.ThrowIfCancellationRequested();
                    string responseContent = await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);

                    result = new MetricListResponse();
                    JToken responseDoc = null;
                    if (string.IsNullOrEmpty(responseContent) == false)
                    {
                        responseDoc = JToken.Parse(responseContent);
                    }

                    if (responseDoc != null && responseDoc.Type != JTokenType.Null)
                    {
                        MetricCollection metricCollectionInstance = new MetricCollection();
                        result.MetricCollection = metricCollectionInstance;

                        JToken valueArray = responseDoc["value"];
                        if (valueArray != null && valueArray.Type != JTokenType.Null)
                        {
                            foreach (JToken valueValue in ((JArray)valueArray))
                            {
                                Metric metricInstance = new Metric();
                                metricCollectionInstance.Value.Add(metricInstance);

                                JToken nameValue = valueValue["name"];
                                if (nameValue != null && nameValue.Type != JTokenType.Null)
                                {
                                    LocalizableString nameInstance = new LocalizableString();
                                    metricInstance.Name = nameInstance;

                                    JToken valueValue2 = nameValue["value"];
                                    if (valueValue2 != null && valueValue2.Type != JTokenType.Null)
                                    {
                                        string valueInstance = ((string)valueValue2);
                                        nameInstance.Value = valueInstance;
                                    }

                                    JToken localizedValueValue = nameValue["localizedValue"];
                                    if (localizedValueValue != null && localizedValueValue.Type != JTokenType.Null)
                                    {
                                        string localizedValueInstance = ((string)localizedValueValue);
                                        nameInstance.LocalizedValue = localizedValueInstance;
                                    }
                                }

                                JToken unitValue = valueValue["unit"];
                                if (unitValue != null && unitValue.Type != JTokenType.Null)
                                {
                                    Unit unitInstance = ((Unit)Enum.Parse(typeof(Unit), ((string)unitValue), true));
                                    metricInstance.Unit = unitInstance;
                                }

                                JToken timeGrainValue = valueValue["timeGrain"];
                                if (timeGrainValue != null && timeGrainValue.Type != JTokenType.Null)
                                {
                                    TimeSpan timeGrainInstance = TypeConversion.From8601TimeSpan(((string)timeGrainValue));
                                    metricInstance.TimeGrain = timeGrainInstance;
                                }

                                JToken startTimeValue = valueValue["startTime"];
                                if (startTimeValue != null && startTimeValue.Type != JTokenType.Null)
                                {
                                    DateTime startTimeInstance = ((DateTime)startTimeValue);
                                    metricInstance.StartTime = startTimeInstance;
                                }

                                JToken endTimeValue = valueValue["endTime"];
                                if (endTimeValue != null && endTimeValue.Type != JTokenType.Null)
                                {
                                    DateTime endTimeInstance = ((DateTime)endTimeValue);
                                    metricInstance.EndTime = endTimeInstance;
                                }

                                JToken metricValuesArray = valueValue["metricValues"];
                                if (metricValuesArray != null && metricValuesArray.Type != JTokenType.Null)
                                {
                                    foreach (JToken metricValuesValue in ((JArray)metricValuesArray))
                                    {
                                        MetricValue metricValueInstance = new MetricValue();
                                        metricInstance.MetricValues.Add(metricValueInstance);

                                        JToken timestampValue = metricValuesValue["timestamp"];
                                        if (timestampValue != null && timestampValue.Type != JTokenType.Null)
                                        {
                                            DateTime timestampInstance = ((DateTime)timestampValue);
                                            metricValueInstance.Timestamp = timestampInstance;
                                        }

                                        JToken averageValue = metricValuesValue["average"];
                                        if (averageValue != null && averageValue.Type != JTokenType.Null)
                                        {
                                            double averageInstance = ((double)averageValue);
                                            metricValueInstance.Average = averageInstance;
                                        }

                                        JToken minimumValue = metricValuesValue["minimum"];
                                        if (minimumValue != null && minimumValue.Type != JTokenType.Null)
                                        {
                                            double minimumInstance = ((double)minimumValue);
                                            metricValueInstance.Minimum = minimumInstance;
                                        }

                                        JToken maximumValue = metricValuesValue["maximum"];
                                        if (maximumValue != null && maximumValue.Type != JTokenType.Null)
                                        {
                                            double maximumInstance = ((double)maximumValue);
                                            metricValueInstance.Maximum = maximumInstance;
                                        }

                                        JToken totalValue = metricValuesValue["total"];
                                        if (totalValue != null && totalValue.Type != JTokenType.Null)
                                        {
                                            double totalInstance = ((double)totalValue);
                                            metricValueInstance.Total = totalInstance;
                                        }

                                        JToken countValue = metricValuesValue["count"];
                                        if (countValue != null && countValue.Type != JTokenType.Null)
                                        {
                                            long countInstance = ((long)countValue);
                                            metricValueInstance.Count = countInstance;
                                        }

                                        JToken lastValue = metricValuesValue["last"];
                                        if (lastValue != null && lastValue.Type != JTokenType.Null)
                                        {
                                            double lastInstance = ((double)lastValue);
                                            metricValueInstance.Last = lastInstance;
                                        }

                                        JToken propertiesSequenceElement = ((JToken)metricValuesValue["properties"]);
                                        if (propertiesSequenceElement != null && propertiesSequenceElement.Type != JTokenType.Null)
                                        {
                                            foreach (JProperty property in propertiesSequenceElement)
                                            {
                                                string propertiesKey   = ((string)property.Name);
                                                string propertiesValue = ((string)property.Value);
                                                metricValueInstance.Properties.Add(propertiesKey, propertiesValue);
                                            }
                                        }
                                    }
                                }

                                JToken resourceIdValue = valueValue["resourceId"];
                                if (resourceIdValue != null && resourceIdValue.Type != JTokenType.Null)
                                {
                                    string resourceIdInstance = ((string)resourceIdValue);
                                    metricInstance.ResourceId = resourceIdInstance;
                                }

                                JToken propertiesSequenceElement2 = ((JToken)valueValue["properties"]);
                                if (propertiesSequenceElement2 != null && propertiesSequenceElement2.Type != JTokenType.Null)
                                {
                                    foreach (JProperty property2 in propertiesSequenceElement2)
                                    {
                                        string propertiesKey2   = ((string)property2.Name);
                                        string propertiesValue2 = ((string)property2.Value);
                                        metricInstance.Properties.Add(propertiesKey2, propertiesValue2);
                                    }
                                }
                            }
                        }
                    }

                    result.StatusCode = statusCode;
                    if (httpResponse.Headers.Contains("x-ms-request-id"))
                    {
                        result.RequestId = httpResponse.Headers.GetValues("x-ms-request-id").FirstOrDefault();
                    }

                    if (shouldTrace)
                    {
                        Tracing.Exit(invocationId, result);
                    }
                    return(result);
                }
                finally
                {
                    if (httpResponse != null)
                    {
                        httpResponse.Dispose();
                    }
                }
            }
            finally
            {
                if (httpRequest != null)
                {
                    httpRequest.Dispose();
                }
            }
        }
        public async Task <MetricListResponse> GetMetricsAsync(string resourceId, string filterString, IEnumerable <MetricDefinition> definitions, string invocationId)
        {
            MetricFilter filter = MetricFilterExpressionParser.Parse(filterString);

            var metricsPerBlob = new Dictionary <string, Task <Dictionary <string, List <MetricValueBlob> > > >(StringComparer.OrdinalIgnoreCase);

            // We download all the relevant blobs first and then use the data later, to avoid download the same blob more than once.
            foreach (MetricDefinition metricDefinition in definitions)
            {
                if (!IsMetricDefinitionIncluded(filter, metricDefinition))
                {
                    continue;
                }

                foreach (MetricAvailability availability in metricDefinition.MetricAvailabilities)
                {
                    if (availability.BlobLocation == null)
                    {
                        continue;
                    }

                    foreach (BlobInfo blobInfo in availability.BlobLocation.BlobInfo)
                    {
                        string blobId = GetBlobEndpoint(blobInfo);
                        if (!metricsPerBlob.ContainsKey(blobId))
                        {
                            metricsPerBlob.Add(blobId, FetchMetricValuesFromBlob(blobInfo, filter));
                        }
                    }
                }
            }

            foreach (var task in metricsPerBlob.Values)
            {
                await task;
            }

            var result = new MetricListResponse
            {
                MetricCollection = new MetricCollection
                {
                    Value = new List <Metric>()
                }
            };

            // Populate the metrics result using the data from the blobs.
            foreach (MetricDefinition metricDefinition in definitions)
            {
                if (!IsMetricDefinitionIncluded(filter, metricDefinition))
                {
                    continue;
                }

                foreach (MetricAvailability availability in metricDefinition.MetricAvailabilities)
                {
                    if (availability.BlobLocation == null)
                    {
                        continue;
                    }

                    var metricValues = new List <MetricValueBlob>();
                    foreach (BlobInfo blobInfo in availability.BlobLocation.BlobInfo)
                    {
                        string blobId = GetBlobEndpoint(blobInfo);

                        List <MetricValueBlob> metricsInBlob;
                        if (metricsPerBlob[blobId].Result.TryGetValue(metricDefinition.Name.Value, out metricsInBlob))
                        {
                            metricValues.AddRange(metricsInBlob);
                        }
                    }

                    var metric = new Metric
                    {
                        Name = new LocalizableString
                        {
                            Value          = metricDefinition.Name.Value,
                            LocalizedValue = metricDefinition.Name.LocalizedValue,
                        },
                        StartTime    = filter.StartTime,
                        EndTime      = filter.EndTime,
                        MetricValues = GetAggregatedByTimestamp(metricValues),
                        TimeGrain    = availability.TimeGrain,
                    };

                    result.MetricCollection.Value.Add(metric);
                }
            }

            return(result);
        }