private async Task MeasureArmRateLimitingAsync(HttpResponseMessage response)
        {
            // Source: https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-request-limits
            if (response.Headers.Contains("x-ms-ratelimit-remaining-subscription-reads"))
            {
                var remainingApiCalls     = response.Headers.GetValues("x-ms-ratelimit-remaining-subscription-reads").FirstOrDefault();
                var subscriptionReadLimit = Convert.ToInt16(remainingApiCalls);
                await _metricSinkWriter.ReportMetricAsync(RuntimeMetricNames.RateLimitingForArm, "Indication how many calls are still available before Azure Resource Manager is going to throttle us.", subscriptionReadLimit, _metricLabels);

                _metricsCollector.SetGaugeMeasurement(RuntimeMetricNames.RateLimitingForArm, "Indication how many calls are still available before Azure Resource Manager is going to throttle us.", subscriptionReadLimit, _metricLabels);
            }
        }
        public async Task ReportMetricAsync_WriteToNoSinks_Succeeds()
        {
            // Arrange
            var metricName        = BogusGenerator.Name.FirstName();
            var metricDescription = BogusGenerator.Lorem.Sentence();
            var metricValue       = BogusGenerator.Random.Double();
            var scrapeResult      = ScrapeResultGenerator.Generate(metricValue);
            var metricSinkWriter  = new MetricSinkWriter(new List <IMetricSink>(), NullLogger <MetricSinkWriter> .Instance);

            // Act & Assert
            await metricSinkWriter.ReportMetricAsync(metricName, metricDescription, scrapeResult);
        }
        public async Task ReportMetricAsync_WriteToOneSinkWithoutMetricDescription_Succeeds(string metricDescription)
        {
            // Arrange
            var metricName       = BogusGenerator.Name.FirstName();
            var metricValue      = BogusGenerator.Random.Double();
            var scrapeResult     = ScrapeResultGenerator.Generate(metricValue);
            var metricSink       = new Mock <IMetricSink>();
            var metricSinkWriter = new MetricSinkWriter(new List <IMetricSink> {
                metricSink.Object
            }, NullLogger <MetricSinkWriter> .Instance);

            // Act & Assert
            await metricSinkWriter.ReportMetricAsync(metricName, metricDescription, scrapeResult);
        }
        protected override async Task AvailableRateLimitingCallsAsync(HttpResponseMessage response)
        {
            // Source: https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-request-limits
            if (response.Headers.Contains(ThrottlingHeaderName))
            {
                var remainingApiCalls     = response.Headers.GetValues(ThrottlingHeaderName).FirstOrDefault();
                var subscriptionReadLimit = Convert.ToInt16(remainingApiCalls);

                // Report metric
                await _metricSinkWriter.ReportMetricAsync(RuntimeMetricNames.RateLimitingForArm, AvailableCallsMetricDescription, subscriptionReadLimit, _metricLabels);

                _azureScrapingPrometheusMetricsCollector.WriteGaugeMeasurement(RuntimeMetricNames.RateLimitingForArm, AvailableCallsMetricDescription, subscriptionReadLimit, _metricLabels);
            }
        }
示例#5
0
        public async Task ScrapeAsync(ScrapeDefinition <IAzureResourceDefinition> scrapeDefinition)
        {
            if (scrapeDefinition == null)
            {
                throw new ArgumentNullException(nameof(scrapeDefinition));
            }

            var aggregationInterval = scrapeDefinition.AzureMetricConfiguration?.Aggregation?.Interval;

            if (aggregationInterval == null)
            {
                throw new ArgumentNullException(nameof(scrapeDefinition));
            }

            try
            {
                var castedMetricDefinition = scrapeDefinition.Resource as TResourceDefinition;
                if (castedMetricDefinition == null)
                {
                    throw new ArgumentException($"Could not cast metric definition of type {scrapeDefinition.Resource.ResourceType} to {typeof(TResourceDefinition)}. Payload: {JsonConvert.SerializeObject(scrapeDefinition)}");
                }

                var aggregationType     = scrapeDefinition.AzureMetricConfiguration.Aggregation.Type;
                var scrapedMetricResult = await ScrapeResourceAsync(
                    scrapeDefinition.SubscriptionId,
                    scrapeDefinition,
                    castedMetricDefinition,
                    aggregationType,
                    aggregationInterval.Value);

                LogMeasuredMetrics(scrapeDefinition, scrapedMetricResult, aggregationInterval);

                await _metricSinkWriter.ReportMetricAsync(scrapeDefinition.PrometheusMetricDefinition.Name, scrapeDefinition.PrometheusMetricDefinition.Description, scrapedMetricResult);

                ReportScrapingOutcome(scrapeDefinition, isSuccessful: true);
            }
            catch (ErrorResponseException errorResponseException)
            {
                HandleErrorResponseException(errorResponseException, scrapeDefinition.PrometheusMetricDefinition.Name);

                ReportScrapingOutcome(scrapeDefinition, isSuccessful: false);
            }
            catch (Exception exception)
            {
                Logger.LogCritical(exception, "Failed to scrape resource for metric '{MetricName}'", scrapeDefinition.PrometheusMetricDefinition.Name);

                ReportScrapingOutcome(scrapeDefinition, isSuccessful: false);
            }
        }
        public async Task ReportMetricAsync_WriteToOneSinkWithoutScrapeResult_ThrowsException()
        {
            // Arrange
            var          metricName        = BogusGenerator.Name.FirstName();
            var          metricDescription = BogusGenerator.Lorem.Sentence();
            ScrapeResult scrapeResult      = null;
            var          metricSink        = new Mock <IMetricSink>();
            var          metricSinkWriter  = new MetricSinkWriter(new List <IMetricSink> {
                metricSink.Object
            }, NullLogger <MetricSinkWriter> .Instance);

            // Act & Assert
            // ReSharper disable once ExpressionIsAlwaysNull
            await Assert.ThrowsAsync <ArgumentNullException>(() => metricSinkWriter.ReportMetricAsync(metricName, metricDescription, scrapeResult));
        }
示例#7
0
        public async Task ReportMetricAsync_WriteToOneSinkWithoutMetricName_ThrowsException(string metricName)
        {
            // Arrange
            var metricDescription = _bogus.Lorem.Sentence();
            var metricValue       = _bogus.Random.Double();
            var scrapeResult      = ScrapeResultGenerator.Generate(metricValue);
            var metricSink        = new Mock <IMetricSink>();
            var metricSinkWriter  = new MetricSinkWriter(new List <IMetricSink> {
                metricSink.Object
            }, NullLogger <MetricSinkWriter> .Instance);

            // Act & Assert
            // ReSharper disable once ExpressionIsAlwaysNull
            await Assert.ThrowsAsync <ArgumentException>(() => metricSinkWriter.ReportMetricAsync(metricName, metricDescription, scrapeResult));
        }
        public async Task ReportMetricAsync_WriteToOneSink_Succeeds()
        {
            // Arrange
            var metricName        = BogusGenerator.Name.FirstName();
            var metricDescription = BogusGenerator.Lorem.Sentence();
            var metricValue       = BogusGenerator.Random.Double();
            var scrapeResult      = ScrapeResultGenerator.Generate(metricValue);
            var metricSink        = new Mock <IMetricSink>();
            var metricSinkWriter  = new MetricSinkWriter(new List <IMetricSink> {
                metricSink.Object
            }, NullLogger <MetricSinkWriter> .Instance);

            // Act
            await metricSinkWriter.ReportMetricAsync(metricName, metricDescription, scrapeResult);

            // Assert
            metricSink.Verify(mock => mock.ReportMetricAsync(metricName, metricDescription, scrapeResult), Times.Once());
        }
示例#9
0
        public async Task ReportMetricAsync_WriteToStatsDSink_Succeeds()
        {
            // Arrange
            var metricName          = _bogus.Name.FirstName();
            var metricDescription   = _bogus.Lorem.Sentence();
            var metricValue         = _bogus.Random.Double();
            var scrapeResult        = ScrapeResultGenerator.Generate(metricValue);
            var statsDPublisherMock = new Mock <IStatsDPublisher>();
            var statsdMetricSink    = new StatsdMetricSink(statsDPublisherMock.Object, NullLogger <StatsdMetricSink> .Instance);
            var metricSinkWriter    = new MetricSinkWriter(new List <IMetricSink> {
                statsdMetricSink
            }, NullLogger <MetricSinkWriter> .Instance);

            // Act
            await metricSinkWriter.ReportMetricAsync(metricName, metricDescription, scrapeResult);

            // Assert
            statsDPublisherMock.Verify(mock => mock.Gauge(metricValue, metricName), Times.Once());
        }
示例#10
0
        public async Task ReportMetricAsync_WriteToMultipleSinks_Succeeds()
        {
            // Arrange
            var metricName        = _bogus.Name.FirstName();
            var metricDescription = _bogus.Lorem.Sentence();
            var metricValue       = _bogus.Random.Double();
            var scrapeResult      = GenerateScrapeResult(metricValue);
            var firstSink         = new Mock <IMetricSink>();
            var secondSink        = new Mock <IMetricSink>();
            var metricSinkWriter  = new MetricSinkWriter(new List <IMetricSink> {
                firstSink.Object, secondSink.Object
            }, NullLogger <MetricSinkWriter> .Instance);

            // Act
            await metricSinkWriter.ReportMetricAsync(metricName, metricDescription, scrapeResult);

            // Assert
            firstSink.Verify(mock => mock.ReportMetricAsync(metricName, metricDescription, It.IsAny <MeasuredMetric>()), Times.Once());
            secondSink.Verify(mock => mock.ReportMetricAsync(metricName, metricDescription, It.IsAny <MeasuredMetric>()), Times.Once());
        }