Exemplo n.º 1
0
        public static async Task <List <Measurement> > GetMetricAsync(
            this IMonitorManagementClient monitorManagementClient,
            string resourceUri,
            MetricName metricName,
            DateTime startTimeUtc, DateTime endTimeUtc,
            TimeSpan samplingInterval,
            AggregationType aggregation,
            CancellationToken cancellationToken = default)
        {
            Contract.Requires(aggregation != AggregationType.None);

            // Unfortunately, the Azure Metrics API is pretty bad and lacking documentation, so we do our best here to
            // get things working. However, API may fail anyways if an invalid set of sampling frequency vs time length
            // is input.
            var startTime = startTimeUtc.ToString("o").Replace("+", "%2b");
            var endTime   = endTimeUtc.ToString("o").Replace("+", "%2b");

            return(await RetryPolicy.ExecuteAsync(async() =>
            {
                var result = await monitorManagementClient.Metrics.ListAsync(
                    resourceUri: resourceUri,
                    metricnames: metricName,
                    timespan: $"{startTime}/{endTime}",
                    interval: samplingInterval,
                    aggregation: aggregation.ToString(),
                    cancellationToken: cancellationToken);

                var metric = result.Value[0];
                var extract = ExtractMetric[aggregation];
                var timeSeries = metric.Timeseries[0];

                return timeSeries.Data.Select(metricValue => new Measurement(metricValue.TimeStamp, extract(metricValue))).ToList();
            }, cancellationToken));
        }
Exemplo n.º 2
0
        public RedisAutoscalingAgent(Configuration configuration, IMonitorManagementClient monitorManagementClient)
        {
            Contract.Requires(configuration.UsedMemoryAggregationInterval < configuration.UsedMemoryLookback);
            Contract.Requires(configuration.UsedMemoryLookback <= TimeSpan.FromDays(30));
            Contract.Requires(configuration.MinimumExtraMemoryAvailable > 0);

            _configuration           = configuration;
            _monitorManagementClient = monitorManagementClient;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="MetricClient"/> class
        /// </summary>
        /// <param name="tracer">The tracer</param>
        /// <param name="subscriptionId">The subscription Id</param>
        /// <param name="monitorManagementClient">Monitor management client to use to fetch metric data</param>
        public MetricClient(IExtendedTracer tracer, string subscriptionId, IMonitorManagementClient monitorManagementClient)
        {
            this.tracer = Diagnostics.EnsureArgumentNotNull(() => tracer);

            this.monitorManagementClient = monitorManagementClient;
            this.monitorManagementClient.SubscriptionId = subscriptionId;
            this.tracer      = tracer;
            this.retryPolicy = PolicyExtensions.CreateDefaultPolicy(this.tracer, DependencyName);
        }
Exemplo n.º 4
0
        public DiagnosticSettingsResource CreateDiagnosticSettings(
            string categoryName, string settingsName,
            string eventHubName, string eventHubAuthorizationRuleId, string workspaceId,
            string resourceGroupName, string serverName, string databaseName = "master")
        {
            string resoureUri = GetResourceUri(resourceGroupName, serverName, databaseName);
            IMonitorManagementClient   client   = GetMonitorManagementClient();
            DiagnosticSettingsResource settings = new DiagnosticSettingsResource
            {
                Logs         = new List <LogSettings>(),
                Metrics      = new List <MetricSettings>(),
                EventHubName = eventHubName,
                EventHubAuthorizationRuleId = eventHubAuthorizationRuleId,
                WorkspaceId = workspaceId
            };

            try
            {
                IList <DiagnosticSettingsCategoryResource> supportedCategories =
                    client.DiagnosticSettingsCategory.ListAsync(resoureUri).Result.Value;
                if (supportedCategories != null)
                {
                    foreach (DiagnosticSettingsCategoryResource category in supportedCategories)
                    {
                        if (category.CategoryType == CategoryType.Metrics)
                        {
                            settings.Metrics.Add(new MetricSettings(false, null, category.Name));
                        }
                        else
                        {
                            settings.Logs.Add(
                                new LogSettings(
                                    string.Equals(category.Name, categoryName),
                                    category.Name));
                        }
                    }
                }
            }
            catch (AggregateException ex)
            {
                if (!(ex.InnerException is ErrorResponseException ex1) ||
                    ex1.Response.StatusCode != System.Net.HttpStatusCode.NotFound)
                {
                    throw ex.InnerException ?? ex;
                }
            }

            if (!settings.Logs.Any(l => string.Equals(l.Category, categoryName)))
            {
                settings.Logs.Add(new LogSettings(true, categoryName));
            }

            return(client.DiagnosticSettings.CreateOrUpdateAsync(
                       resoureUri, settings, settingsName).Result);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MdmClient"/> class
        /// </summary>
        /// <param name="tracer">The tracer</param>
        /// <param name="credentialsFactory">The credentials factory</param>
        /// <param name="resourceIdentifier">The resource for which we want to fetch data from MDM</param>
        /// /// <param name="monitorManagementClient">Monitor management client to use to fetch data from MDM</param>
        public MdmClient(ITracer tracer, ICredentialsFactory credentialsFactory, ResourceIdentifier resourceIdentifier, IMonitorManagementClient monitorManagementClient)
        {
            this.tracer = Diagnostics.EnsureArgumentNotNull(() => tracer);
            Diagnostics.EnsureArgumentNotNull(() => credentialsFactory);
            this.resourceIdentifier = resourceIdentifier;

            this.credentials             = credentialsFactory.Create("https://management.azure.com/");
            this.monitorManagementClient = monitorManagementClient;
            this.monitorManagementClient.SubscriptionId = resourceIdentifier.SubscriptionId;
            this.tracer      = tracer;
            this.retryPolicy = PolicyExtensions.CreateDefaultPolicy(this.tracer, DependencyName);
        }
        /// <summary>
        /// Dispose the resources
        /// </summary>
        /// <param name="disposing">Indicates whether the managed resources should be disposed or not</param>
        protected override void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (this.monitorManagementClient != null)
                {
                    this.monitorManagementClient.Dispose();
                    this.monitorManagementClient = null;
                }

                this.disposed = true;
            }
            base.Dispose(disposing);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="MetricClient"/> class
        /// </summary>
        /// <param name="tracer">The tracer</param>
        /// <param name="monitorManagementClient">Monitor management client to use to fetch metric data</param>
        public MetricClient(ITracer tracer, IMonitorManagementClient monitorManagementClient)
        {
            if (tracer == null)
            {
                throw new ArgumentNullException(nameof(tracer));
            }

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

            this.tracer = tracer;
            this.monitorManagementClient = monitorManagementClient;
            this.retryPolicy             = PolicyExtensions.CreateDefaultPolicy(this.tracer, DependencyName);
        }
Exemplo n.º 8
0
        private void SetupManagementClients(RestTestFramework.MockContext context)
        {
            if (HttpMockServer.Mode == HttpRecorderMode.Record)
            {
                // This allows the use of a particular subscription if the user is associated to several
                // "TEST_CSM_ORGID_AUTHENTICATION=SubscriptionId=<subscription-id>"
                string subId = Environment.GetEnvironmentVariable("TEST_CSM_ORGID_AUTHENTICATION");
                RestTestFramework.TestEnvironment environment = new RestTestFramework.TestEnvironment(connectionString: subId);
                this.MonitorManagementClient = this.GetInsightsManagementClient(context: context, env: environment);
            }
            else if (HttpMockServer.Mode == HttpRecorderMode.Playback)
            {
                this.MonitorManagementClient = this.GetInsightsManagementClient(context: context, env: null);
            }

            _helper.SetupManagementClients(
                this.MonitorManagementClient);
        }
Exemplo n.º 9
0
 public EnvironmentResources(IAzure azure, IMonitorManagementClient monitorManagementClient, IReadOnlyDictionary <string, IRedisCache> redisCaches)
 {
     Azure = azure;
     MonitorManagementClient = monitorManagementClient;
     RedisCaches             = redisCaches;
 }
Exemplo n.º 10
0
        public static async Task<Dictionary<MetricName, List<MetricValue>>> GetMetricsWithDimensionAsync(
            this IMonitorManagementClient monitorManagementClient,
            string resourceUri,
            IReadOnlyList<MetricName> metrics,
            string dimension,
            DateTime startTimeUtc, DateTime endTimeUtc,
            TimeSpan samplingInterval,
            IReadOnlyList<AggregationType> aggregations,
            CancellationToken cancellationToken = default)
        {
            Contract.Requires(startTimeUtc < endTimeUtc);

            // HERE BE DRAGONS. The Azure Monitor Metrics API is basically nondeterministic. It may fail at random, for
            // unknown periods of time, and for unknown reasons. This function is an attempt to make a sane wrapper
            // over it.

            // We remove the seconds in an attempt to play nicely with the Azure Metrics API. Format is not strictly
            // ISO, as they claim is supported, but what we have found to work by trial and error and looking at
            // examples.
            var startTime = startTimeUtc.ToString("yyyy-MM-ddTHH:mm:00Z");
            var endTime = endTimeUtc.ToString("yyyy-MM-ddTHH:mm:00Z");
            var interval = $"{startTime}/{endTime}";

            return await RetryPolicy.ExecuteAsync(async () =>
            {
                var metricNames = string.Join(",", metrics.Select(name => name.Name.ToLower()));
                var odataQuery = new ODataQuery<MetadataValue>(odataExpression: $"{dimension} eq '*'");
                var aggregation = string.Join(
                    ",",
                    aggregations.Select(
                        agg =>
                        {
                            Contract.Assert(agg != AggregationType.None); return agg.ToString().ToLower();
                        }));
                var result = await monitorManagementClient.Metrics.ListAsync(
                    resourceUri: resourceUri,
                    metricnames: metricNames,
                    odataQuery: odataQuery,
                    timespan: interval,
                    interval: samplingInterval,
                    aggregation: aggregation,
                    cancellationToken: cancellationToken);
                result.Validate();

                if (result.Value.Count == 0)
                {
                    // Sometimes, for unknown reasons, this can be empty. This is an error, but can go away when
                    // retried. That's exactly what we do here (look at the retry policy's detection strategy).
                    throw new AzureMetricsClientValidationException("Invalid `result.Value` returned");
                }

                var output = new Dictionary<MetricName, List<MetricValue>>();
                foreach (var metric in result.Value)
                {
                    if (metric.Timeseries.Count == 0)
                    {
                        // Sometimes, there may be no timeseries. Reasons seem to be varied, but here's the predominant
                        // example that would brick us in production:
                        //  - We'd attempt to fetch operationsPerSecond going back several weeks for all possible 10
                        //    shards.
                        //  - The current number of shards is less than 10, say 1
                        //  - Shard 0 would have a result. Shards 1-9 wouldn't.
                        // WARNING: this continue means that we won't report the result for this metric. Usages must
                        // account for arbitrary metric disappearance.
                        continue;
                    }

                    var metricNameFromApi = metric.Name.Value;
                    if (string.IsNullOrEmpty(metricNameFromApi))
                    {
                        throw new AzureMetricsClientValidationException("Received empty metric name");
                    }

                    foreach (var timeseries in metric.Timeseries)
                    {
                        var metricGroupFromApi = timeseries.Metadatavalues.ToDictionary(v => v.Name.Value, v => v.Value);

                        var timeSeriesFromApi = timeseries.Data;
                        if (timeSeriesFromApi == null || timeSeriesFromApi.Count < 1)
                        {
                            throw new AzureMetricsClientValidationException($"Received invalid time series for metric `{metricNameFromApi}`. Size=[{timeSeriesFromApi?.Count ?? -1}]");
                        }

                        var metricName = new MetricName(metricNameFromApi, metricGroupFromApi);
                        output[metricName] = timeSeriesFromApi
                            .OrderBy(m => m.TimeStamp)
                            .ToList();
                    }
                }

                return output;
            }, cancellationToken);
        }
Exemplo n.º 11
0
 public AzureMetricsClient(IMonitorManagementClient monitorManagementClient)
 {
     _monitorManagementClient = monitorManagementClient;
 }