Beispiel #1
0
        public async Task <MetricListResponse> GetMetricsAsync(string resourceUri, string filterString, CancellationToken cancellationToken)
        {
            // Ensure exactly one '/' at the start
            resourceUri = '/' + resourceUri.TrimStart('/');

            // Generate filter strings
            string metricFilter     = RemoveNamesFromFilterString(filterString);
            string definitionFilter = ShoeboxHelper.GenerateMetricDefinitionFilterString(MetricFilterExpressionParser.Parse(filterString).Names);

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

            // Get Metrics by definitions
            return(await this.GetMetricsAsync(resourceUri, metricFilter, definitions, cancellationToken).ConfigureAwait(false));
        }
Beispiel #2
0
        public async Task <MetricListResponse> GetMetricsAsync(string resourceUri, string filterString, CancellationToken cancellationToken)
        {
            if (resourceUri == null)
            {
                throw new ArgumentNullException("resourceUri");
            }

            // Generate filter strings
            MetricFilter filter = MetricFilterExpressionParser.Parse(filterString);
            string       filterStringNamesOnly = 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,
                     filterStringNamesOnly,
                     cancellationToken).ConfigureAwait(false)).MetricDefinitionCollection.Value;

            // Get Metrics with definitions
            return(await this.GetMetricsAsync(resourceUri, filterString, definitions, cancellationToken));
        }
        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);
        }
Beispiel #4
0
        public async Task <MetricDefinitionListResponse> GetMetricDefinitionsAsync(string resourceUri, string filterString, CancellationToken cancellationToken)
        {
            MetricDefinitionListResponse result;

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

            this.LogStartGetMetricDefinitions(invocationId, resourceUri, filterString);

            // Ensure exactly one '/' at the start
            resourceUri = '/' + resourceUri.TrimStart('/');
            IEnumerable <MetricDefinition> definitions;

            // If no filter string, must request all metric definiitons since we don't know if we have them all
            if (string.IsNullOrWhiteSpace(filterString))
            {
                // request all definitions
                definitions = (await this.GetMetricDefinitionsInternalAsync(resourceUri, string.Empty, CancellationToken.None).ConfigureAwait(false))
                              .MetricDefinitionCollection.Value;

                // cache definitions
                this.Client.Cache[resourceUri] = definitions;

                // wrap and return definitions
                result = new MetricDefinitionListResponse()
                {
                    StatusCode = HttpStatusCode.OK,
                    MetricDefinitionCollection = new MetricDefinitionCollection()
                    {
                        Value = definitions.ToList()
                    }
                };

                this.LogEndGetMetricDefinitions(invocationId, result);

                return(result);
            }

            // Parse the filter and retrieve cached definitions
            IEnumerable <string> names = MetricDefinitionFilterParser.Parse(filterString);

            definitions = this.Client.Cache[resourceUri];

            // Find the names in the filter that don't appear on any of the cached definitions
            IEnumerable <string> missing = definitions == null
                ? names
                : names.Where((n => !definitions.Any(d => string.Equals(d.Name.Value, n, StringComparison.OrdinalIgnoreCase))));

            // Request any missing definitions and update cache (if any)
            if (missing.Any())
            {
                string missingFilter = ShoeboxHelper.GenerateMetricDefinitionFilterString(missing);

                // Request missing definitions
                var missingDefinitions = (await this.GetMetricDefinitionsInternalAsync(resourceUri, missingFilter, cancellationToken).ConfigureAwait(false))
                                         .MetricDefinitionCollection.Value;

                // merge definitions
                definitions = (definitions ?? new MetricDefinition[0]).Union(missingDefinitions);

                // Store the new set of definitions
                this.Client.Cache[resourceUri] = definitions;
            }

            // Filter out the metrics that were cached but not requested and wrap
            result = new MetricDefinitionListResponse()
            {
                StatusCode = HttpStatusCode.OK,
                MetricDefinitionCollection = new MetricDefinitionCollection()
                {
                    Value = definitions.Where(d => names.Contains(d.Name.Value)).ToList()
                }
            };

            this.LogEndGetMetricDefinitions(invocationId, result);

            return(result);
        }