Пример #1
0
        public void UpdateAlertConfigurationRespectsTheCancellationToken()
        {
            MetricsAdvisorAdministrationClient adminClient = GetMetricsAdvisorAdministrationClient();

            var config = new AnomalyAlertConfiguration(FakeGuid, default, default, default, new List <string>(), new List <string>(), new List <MetricAlertConfiguration>());
        public void RefreshDataIngestionValidatesArguments()
        {
            MetricsAdvisorAdministrationClient adminClient = GetMetricsAdvisorAdministrationClient();

            Assert.That(() => adminClient.RefreshDataFeedIngestionAsync(null, default, default), Throws.InstanceOf <ArgumentNullException>());
        public void CreateDataFeedValidatesArguments()
        {
            MetricsAdvisorAdministrationClient adminClient = GetMetricsAdvisorAdministrationClient();

            var name        = "dataFeedName";
            var dataSource  = new AzureTableDataFeedSource("connectionString", "table", "query");
            var granularity = new DataFeedGranularity(DataFeedGranularityType.Daily);
            var schema      = new DataFeedSchema()
            {
                MetricColumns = { new("metricName") }
            };
            var ingestionSettings = new DataFeedIngestionSettings()
            {
                IngestionStartTime = DateTimeOffset.UtcNow
            };

            var dataFeed = new DataFeed()
            {
                Name              = null,
                DataSource        = dataSource,
                Granularity       = granularity,
                Schema            = schema,
                IngestionSettings = ingestionSettings
            };

            Assert.That(() => adminClient.CreateDataFeedAsync(null), Throws.InstanceOf <ArgumentNullException>());
            Assert.That(() => adminClient.CreateDataFeed(null), Throws.InstanceOf <ArgumentNullException>());

            Assert.That(() => adminClient.CreateDataFeedAsync(dataFeed), Throws.InstanceOf <ArgumentNullException>());
            Assert.That(() => adminClient.CreateDataFeed(dataFeed), Throws.InstanceOf <ArgumentNullException>());

            dataFeed.Name = "";
            Assert.That(() => adminClient.CreateDataFeedAsync(dataFeed), Throws.InstanceOf <ArgumentException>());
            Assert.That(() => adminClient.CreateDataFeed(dataFeed), Throws.InstanceOf <ArgumentException>());

            dataFeed.Name       = name;
            dataFeed.DataSource = null;
            Assert.That(() => adminClient.CreateDataFeedAsync(dataFeed), Throws.InstanceOf <ArgumentNullException>());
            Assert.That(() => adminClient.CreateDataFeed(dataFeed), Throws.InstanceOf <ArgumentNullException>());

            dataFeed.DataSource  = dataSource;
            dataFeed.Granularity = null;
            Assert.That(() => adminClient.CreateDataFeedAsync(dataFeed), Throws.InstanceOf <ArgumentNullException>());
            Assert.That(() => adminClient.CreateDataFeed(dataFeed), Throws.InstanceOf <ArgumentNullException>());

            dataFeed.Granularity = granularity;
            dataFeed.Schema      = null;
            Assert.That(() => adminClient.CreateDataFeedAsync(dataFeed), Throws.InstanceOf <ArgumentNullException>());
            Assert.That(() => adminClient.CreateDataFeed(dataFeed), Throws.InstanceOf <ArgumentNullException>());

            dataFeed.Schema            = schema;
            dataFeed.IngestionSettings = null;
            Assert.That(() => adminClient.CreateDataFeedAsync(dataFeed), Throws.InstanceOf <ArgumentNullException>());
            Assert.That(() => adminClient.CreateDataFeed(dataFeed), Throws.InstanceOf <ArgumentNullException>());

            dataFeed.IngestionSettings = new DataFeedIngestionSettings()
            {
                IngestionStartTime = null
            };
            Assert.That(() => adminClient.CreateDataFeedAsync(dataFeed), Throws.InstanceOf <ArgumentNullException>());
            Assert.That(() => adminClient.CreateDataFeed(dataFeed), Throws.InstanceOf <ArgumentNullException>());
        }
Пример #4
0
        public void UpdateDatasourceCredentialRespectsTheCancellationToken()
        {
            MetricsAdvisorAdministrationClient adminClient = GetMetricsAdvisorAdministrationClient();

            var credential = new ServicePrincipalDatasourceCredential(default, FakeGuid, default, default, new ServicePrincipalParam("clientId", "clientSecret"));
Пример #5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DisposableDataFeed"/> class.
 /// </summary>
 /// <param name="adminClient">The client to use for deleting the data feed upon disposal.</param>
 /// <param name="dataFeed">The data feed this instance is associated with.</param>
 private DisposableDataFeed(MetricsAdvisorAdministrationClient adminClient, DataFeed dataFeed)
 {
     _adminClient = adminClient;
     DataFeed     = dataFeed;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="DisposableNotificationHook"/> class.
 /// </summary>
 /// <param name="adminClient">The client to use for deleting the hook upon disposal.</param>
 /// <param name="id">The identifier of the hook this instance is associated with.</param>
 private DisposableNotificationHook(MetricsAdvisorAdministrationClient adminClient, string id)
 {
     _adminClient = adminClient;
     Id           = id;
 }
Пример #7
0
        public async Task CreateAndGetAlertConfigurationWithMultipleMetricConfigurations()
        {
            MetricsAdvisorAdministrationClient adminClient = GetMetricsAdvisorAdministrationClient();

            await using DisposableDataFeed disposableDataFeed = await CreateTempDataFeedAsync(adminClient);

            string metricId = disposableDataFeed.DataFeed.MetricIds[TempDataFeedMetricName];

            await using DisposableDetectionConfiguration disposableDetectionConfig = await CreateTempDetectionConfigurationAsync(adminClient, metricId);

            // Configure the Metric Alert Configurations to be used.

            var detectionConfigId  = disposableDetectionConfig.Configuration.Id;
            var scope              = MetricAnomalyAlertScope.CreateScopeForWholeSeries();
            var metricAlertConfig0 = new MetricAlertConfiguration(detectionConfigId, scope)
            {
                AlertConditions = new MetricAnomalyAlertConditions()
                {
                    MetricBoundaryCondition = new MetricBoundaryCondition(BoundaryDirection.Up)
                    {
                        UpperBound = 20.0
                    }
                },
                UseDetectionResultToFilterAnomalies = true
            };
            var metricAlertConfig1 = new MetricAlertConfiguration(detectionConfigId, scope)
            {
                AlertConditions = new MetricAnomalyAlertConditions()
                {
                    MetricBoundaryCondition = new MetricBoundaryCondition(BoundaryDirection.Down)
                    {
                        LowerBound = 10.0
                    }
                }
            };

            // Create the Anomaly Alert Configuration.

            string configName = Recording.GenerateAlphaNumericId("config");

            var configToCreate = new AnomalyAlertConfiguration()
            {
                Name = configName,
                MetricAlertConfigurations = { metricAlertConfig0, metricAlertConfig1 },
                CrossMetricsOperator      = MetricAlertConfigurationsOperator.Xor
            };

            await using var disposableConfig = await DisposableAlertConfiguration.CreateAlertConfigurationAsync(adminClient, configToCreate);

            // Get the created configuration and validate top-level members.

            AnomalyAlertConfiguration createdConfig = disposableConfig.Configuration;

            Assert.That(createdConfig.Id, Is.Not.Null.And.Not.Empty);
            Assert.That(createdConfig.Name, Is.EqualTo(configName));
            Assert.That(createdConfig.Description, Is.Empty);
            Assert.That(createdConfig.CrossMetricsOperator, Is.EqualTo(MetricAlertConfigurationsOperator.Xor));
            Assert.That(createdConfig.IdsOfHooksToAlert, Is.Not.Null.And.Empty);
            Assert.That(createdConfig.DimensionsToSplitAlert, Is.Not.Null.And.Empty);
            Assert.That(createdConfig.MetricAlertConfigurations, Is.Not.Null);
            Assert.That(createdConfig.MetricAlertConfigurations.Count, Is.EqualTo(2));

            // Validate the first Metric Alert Configuration.

            MetricAlertConfiguration createdMetricAlertConfig0 = createdConfig.MetricAlertConfigurations[0];

            Assert.That(createdMetricAlertConfig0.DetectionConfigurationId, Is.EqualTo(detectionConfigId));

            Assert.That(createdMetricAlertConfig0.AlertScope, Is.Not.Null);
            Assert.That(createdMetricAlertConfig0.AlertScope.ScopeType, Is.EqualTo(MetricAnomalyAlertScopeType.WholeSeries));
            Assert.That(createdMetricAlertConfig0.AlertScope.SeriesGroupInScope, Is.Null);
            Assert.That(createdMetricAlertConfig0.AlertScope.TopNGroupInScope, Is.Null);

            Assert.That(createdMetricAlertConfig0.AlertConditions, Is.Not.Null);
            Assert.That(createdMetricAlertConfig0.AlertConditions.MetricBoundaryCondition, Is.Not.Null);
            Assert.That(createdMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.Direction, Is.EqualTo(BoundaryDirection.Up));
            Assert.That(createdMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.UpperBound, Is.EqualTo(20.0));
            Assert.That(createdMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.LowerBound, Is.Null);
            Assert.That(createdMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.CompanionMetricId, Is.Null);
            Assert.That(createdMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.ShouldAlertIfDataPointMissing, Is.False);
            Assert.That(createdMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.MeasureType, Is.EqualTo(BoundaryMeasureType.Value));
            Assert.That(createdMetricAlertConfig0.AlertConditions.SeverityCondition, Is.Null);

            Assert.That(createdMetricAlertConfig0.AlertSnoozeCondition, Is.Null);
            Assert.That(createdMetricAlertConfig0.UseDetectionResultToFilterAnomalies, Is.True);

            // Validate the second Metric Alert Configuration.

            MetricAlertConfiguration createdMetricAlertConfig1 = createdConfig.MetricAlertConfigurations[1];

            Assert.That(createdMetricAlertConfig1.DetectionConfigurationId, Is.EqualTo(detectionConfigId));

            Assert.That(createdMetricAlertConfig1.AlertScope, Is.Not.Null);
            Assert.That(createdMetricAlertConfig1.AlertScope.ScopeType, Is.EqualTo(MetricAnomalyAlertScopeType.WholeSeries));
            Assert.That(createdMetricAlertConfig1.AlertScope.SeriesGroupInScope, Is.Null);
            Assert.That(createdMetricAlertConfig1.AlertScope.TopNGroupInScope, Is.Null);

            Assert.That(createdMetricAlertConfig1.AlertConditions, Is.Not.Null);
            Assert.That(createdMetricAlertConfig1.AlertConditions.MetricBoundaryCondition, Is.Not.Null);
            Assert.That(createdMetricAlertConfig1.AlertConditions.MetricBoundaryCondition.Direction, Is.EqualTo(BoundaryDirection.Down));
            Assert.That(createdMetricAlertConfig1.AlertConditions.MetricBoundaryCondition.UpperBound, Is.Null);
            Assert.That(createdMetricAlertConfig1.AlertConditions.MetricBoundaryCondition.LowerBound, Is.EqualTo(10.0));
            Assert.That(createdMetricAlertConfig1.AlertConditions.MetricBoundaryCondition.CompanionMetricId, Is.Null);
            Assert.That(createdMetricAlertConfig1.AlertConditions.MetricBoundaryCondition.ShouldAlertIfDataPointMissing, Is.False);
            Assert.That(createdMetricAlertConfig1.AlertConditions.MetricBoundaryCondition.MeasureType, Is.EqualTo(BoundaryMeasureType.Value));
            Assert.That(createdMetricAlertConfig1.AlertConditions.SeverityCondition, Is.Null);

            Assert.That(createdMetricAlertConfig1.AlertSnoozeCondition, Is.Null);
            Assert.That(createdMetricAlertConfig1.UseDetectionResultToFilterAnomalies, Is.False);
        }
        public async Task CreateAndGetDetectionConfigurationWithSeriesConditions()
        {
            // Set required parameters of the configuration to be created.

            MetricsAdvisorAdministrationClient adminClient = GetMetricsAdvisorAdministrationClient();

            await using DisposableDataFeed disposableDataFeed = await CreateDisposableDataFeedAsync(adminClient);

            string configName = Recording.GenerateAlphaNumericId("config");
            string metricId   = disposableDataFeed.DataFeed.MetricIds[MetricName];

            var wholeConditions = new MetricWholeSeriesDetectionCondition()
            {
                HardThresholdCondition = new(AnomalyDetectorDirection.Both, new(1, 2.0))
                {
                    UpperBound = 20.0,
                    LowerBound = 10.0
                }
            };

            var configToCreate = new AnomalyDetectionConfiguration()
            {
                MetricId = metricId,
                Name     = configName,
                WholeSeriesDetectionConditions = wholeConditions
            };

            // Set the series conditions and create the configuration.

            var seriesConditions0 = new MetricSingleSeriesDetectionCondition()
            {
                SmartDetectionCondition = new(30.0, AnomalyDetectorDirection.Both, new(3, 4.0))
            };

            seriesConditions0.SeriesKey.AddDimensionColumn(DimensionNameA, "Delhi");
            seriesConditions0.SeriesKey.AddDimensionColumn(DimensionNameB, "Handmade");

            var seriesConditions1 = new MetricSingleSeriesDetectionCondition()
            {
                ChangeThresholdCondition = new(40.0, 12, false, AnomalyDetectorDirection.Up, new(5, 6.0))
            };

            seriesConditions1.SeriesKey.AddDimensionColumn(DimensionNameA, "Koltaka");
            seriesConditions1.SeriesKey.AddDimensionColumn(DimensionNameB, "Grocery & Gourmet Food");

            configToCreate.SeriesDetectionConditions.Add(seriesConditions0);
            configToCreate.SeriesDetectionConditions.Add(seriesConditions1);

            await using var disposableConfig = await DisposableDetectionConfiguration.CreateDetectionConfigurationAsync(adminClient, configToCreate);

            // Get the created configuration and validate top-level members.

            AnomalyDetectionConfiguration createdConfig = disposableConfig.Configuration;

            Assert.That(createdConfig.Id, Is.Not.Null.And.Not.Empty);
            Assert.That(createdConfig.MetricId, Is.EqualTo(metricId));
            Assert.That(createdConfig.Name, Is.EqualTo(configName));
            Assert.That(createdConfig.Description, Is.Empty);
            Assert.That(createdConfig.SeriesGroupDetectionConditions, Is.Not.Null.And.Empty);

            // Validate whole series detection conditions.

            MetricWholeSeriesDetectionCondition createdWholeConditions = createdConfig.WholeSeriesDetectionConditions;

            Assert.That(createdWholeConditions, Is.Not.Null);
            Assert.That(createdWholeConditions.CrossConditionsOperator, Is.Null);
            Assert.That(createdWholeConditions.ChangeThresholdCondition, Is.Null);
            Assert.That(createdWholeConditions.SmartDetectionCondition, Is.Null);

            ValidateHardThresholdCondition(createdWholeConditions.HardThresholdCondition, AnomalyDetectorDirection.Both, 20.0, 10.0, 1, 2.0);

            // Start series conditions validation.

            Assert.That(createdConfig.SeriesDetectionConditions, Is.Not.Null);
            Assert.That(createdConfig.SeriesDetectionConditions.Count, Is.EqualTo(2));

            // Validate first series conditions.

            var createdSeriesConditions0 = createdConfig.SeriesDetectionConditions[0];

            Assert.That(createdSeriesConditions0, Is.Not.Null);

            ValidateDimensionKey(createdSeriesConditions0.SeriesKey, "Delhi", "Handmade");

            Assert.That(createdSeriesConditions0.CrossConditionsOperator, Is.Null);
            Assert.That(createdSeriesConditions0.HardThresholdCondition, Is.Null);
            Assert.That(createdSeriesConditions0.ChangeThresholdCondition, Is.Null);

            ValidateSmartDetectionCondition(createdSeriesConditions0.SmartDetectionCondition, 30.0, AnomalyDetectorDirection.Both, 3, 4.0);

            // Validate last series conditions.

            var createdSeriesConditions1 = createdConfig.SeriesDetectionConditions[1];

            Assert.That(createdSeriesConditions1, Is.Not.Null);

            ValidateDimensionKey(createdSeriesConditions1.SeriesKey, "Koltaka", "Grocery & Gourmet Food");

            Assert.That(createdSeriesConditions1.CrossConditionsOperator, Is.Null);
            Assert.That(createdSeriesConditions1.HardThresholdCondition, Is.Null);
            Assert.That(createdSeriesConditions1.SmartDetectionCondition, Is.Null);

            ValidateChangeThresholdCondition(createdSeriesConditions1.ChangeThresholdCondition, 40.0, 12, false, AnomalyDetectorDirection.Up, 5, 6.0);
        }
Пример #9
0
        /// <summary>
        /// Creates a detection configuration using the specified <see cref="MetricsAdvisorAdministrationClient"/>.
        /// A <see cref="DisposableDetectionConfiguration"/> instance is returned, from which the created configuration
        /// can be obtained. Upon disposal, the associated configuration will be deleted.
        /// </summary>
        /// <param name="adminClient">The client to use for creating and for deleting the configuration.</param>
        /// <param name="configuration">Specifies how the created <see cref="AnomalyDetectionConfiguration"/> should be configured.</param>
        /// <returns>A <see cref="DisposableDetectionConfiguration"/> instance from which the created configuration can be obtained.</returns>
        public static async Task <DisposableDetectionConfiguration> CreateDetectionConfigurationAsync(MetricsAdvisorAdministrationClient adminClient, AnomalyDetectionConfiguration configuration)
        {
            AnomalyDetectionConfiguration createdConfig = await adminClient.CreateDetectionConfigurationAsync(configuration);

            return(new DisposableDetectionConfiguration(adminClient, createdConfig));
        }
Пример #10
0
        public async Task CreateAndGetAlertConfigurationWithOptionalSingleMetricConfigurationMembers()
        {
            MetricsAdvisorAdministrationClient adminClient = GetMetricsAdvisorAdministrationClient();

            await using DisposableDataFeed disposableDataFeed = await CreateTempDataFeedAsync(adminClient);

            string metricId = disposableDataFeed.DataFeed.MetricIds[TempDataFeedMetricName];

            await using DisposableDetectionConfiguration disposableDetectionConfig = await CreateTempDetectionConfigurationAsync(adminClient, metricId);

            string hookName0 = Recording.GenerateAlphaNumericId("hook");
            string hookName1 = Recording.GenerateAlphaNumericId("hook");

            var hookToCreate0 = new EmailNotificationHook(hookName0);
            var hookToCreate1 = new EmailNotificationHook(hookName1);

            hookToCreate0.EmailsToAlert.Add("*****@*****.**");
            hookToCreate1.EmailsToAlert.Add("*****@*****.**");

            await using var disposableHook0 = await DisposableNotificationHook.CreateHookAsync(adminClient, hookToCreate0);

            await using var disposableHook1 = await DisposableNotificationHook.CreateHookAsync(adminClient, hookToCreate1);

            var detectionConfigId = disposableDetectionConfig.Configuration.Id;
            var scope             = MetricAnomalyAlertScope.CreateScopeForWholeSeries();
            var metricAlertConfig = new MetricAlertConfiguration(detectionConfigId, scope)
            {
                AlertSnoozeCondition = new MetricAnomalyAlertSnoozeCondition(12, SnoozeScope.Series, true),
                AlertConditions      = new MetricAnomalyAlertConditions()
                {
                    MetricBoundaryCondition = new MetricBoundaryCondition(BoundaryDirection.Both)
                    {
                        UpperBound                    = 20.0,
                        LowerBound                    = 10.0,
                        CompanionMetricId             = metricId,
                        ShouldAlertIfDataPointMissing = true,
                        MeasureType                   = BoundaryMeasureType.Mean
                    },
                    SeverityCondition = new SeverityCondition(AnomalySeverity.Low, AnomalySeverity.Medium)
                }
            };

            string configName  = Recording.GenerateAlphaNumericId("config");
            var    description = "This hook was created to test the .NET client.";

            var configToCreate = new AnomalyAlertConfiguration()
            {
                Name = configName,
                IdsOfHooksToAlert         = { disposableHook0.Hook.Id, disposableHook1.Hook.Id },
                MetricAlertConfigurations = { metricAlertConfig },
                Description = description
            };

            await using var disposableConfig = await DisposableAlertConfiguration.CreateAlertConfigurationAsync(adminClient, configToCreate);

            AnomalyAlertConfiguration createdConfig = disposableConfig.Configuration;

            Assert.That(createdConfig.Id, Is.Not.Null.And.Not.Empty);
            Assert.That(createdConfig.Name, Is.EqualTo(configName));
            Assert.That(createdConfig.Description, Is.EqualTo(description));
            Assert.That(createdConfig.CrossMetricsOperator, Is.Null);
            Assert.That(createdConfig.IdsOfHooksToAlert.Count, Is.EqualTo(2));
            Assert.That(createdConfig.IdsOfHooksToAlert.Contains(disposableHook0.Hook.Id));
            Assert.That(createdConfig.IdsOfHooksToAlert.Contains(disposableHook1.Hook.Id));
            Assert.That(createdConfig.DimensionsToSplitAlert, Is.Not.Null.And.Empty);
            Assert.That(createdConfig.MetricAlertConfigurations, Is.Not.Null);

            MetricAlertConfiguration createdMetricAlertConfig = createdConfig.MetricAlertConfigurations.Single();

            Assert.That(createdMetricAlertConfig.DetectionConfigurationId, Is.EqualTo(detectionConfigId));

            Assert.That(createdMetricAlertConfig.AlertScope, Is.Not.Null);
            Assert.That(createdMetricAlertConfig.AlertScope.ScopeType, Is.EqualTo(MetricAnomalyAlertScopeType.WholeSeries));
            Assert.That(createdMetricAlertConfig.AlertScope.SeriesGroupInScope, Is.Null);
            Assert.That(createdMetricAlertConfig.AlertScope.TopNGroupInScope, Is.Null);

            Assert.That(createdMetricAlertConfig.AlertConditions, Is.Not.Null);
            Assert.That(createdMetricAlertConfig.AlertConditions.MetricBoundaryCondition, Is.Not.Null);
            Assert.That(createdMetricAlertConfig.AlertConditions.MetricBoundaryCondition.Direction, Is.EqualTo(BoundaryDirection.Both));
            Assert.That(createdMetricAlertConfig.AlertConditions.MetricBoundaryCondition.UpperBound, Is.EqualTo(20.0));
            Assert.That(createdMetricAlertConfig.AlertConditions.MetricBoundaryCondition.LowerBound, Is.EqualTo(10.0));
            Assert.That(createdMetricAlertConfig.AlertConditions.MetricBoundaryCondition.CompanionMetricId, Is.EqualTo(metricId));
            Assert.That(createdMetricAlertConfig.AlertConditions.MetricBoundaryCondition.ShouldAlertIfDataPointMissing, Is.True);
            Assert.That(createdMetricAlertConfig.AlertConditions.MetricBoundaryCondition.MeasureType, Is.EqualTo(BoundaryMeasureType.Mean));
            Assert.That(createdMetricAlertConfig.AlertConditions.SeverityCondition, Is.Not.Null);
            Assert.That(createdMetricAlertConfig.AlertConditions.SeverityCondition.MinimumAlertSeverity, Is.EqualTo(AnomalySeverity.Low));
            Assert.That(createdMetricAlertConfig.AlertConditions.SeverityCondition.MaximumAlertSeverity, Is.EqualTo(AnomalySeverity.Medium));

            Assert.That(createdMetricAlertConfig.AlertSnoozeCondition, Is.Not.Null);
            Assert.That(createdMetricAlertConfig.AlertSnoozeCondition.AutoSnooze, Is.EqualTo(12));
            Assert.That(createdMetricAlertConfig.AlertSnoozeCondition.SnoozeScope, Is.EqualTo(SnoozeScope.Series));
            Assert.That(createdMetricAlertConfig.AlertSnoozeCondition.IsOnlyForSuccessive, Is.True);

            Assert.That(createdMetricAlertConfig.UseDetectionResultToFilterAnomalies, Is.False);
        }
Пример #11
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DisposableDetectionConfiguration"/> class.
 /// </summary>
 /// <param name="adminClient">The client to use for deleting the configuration upon disposal.</param>
 /// <param name="configuration">The detection configuration this instance is associated with.</param>
 private DisposableDetectionConfiguration(MetricsAdvisorAdministrationClient adminClient, AnomalyDetectionConfiguration configuration)
 {
     _adminClient  = adminClient;
     Configuration = configuration;
 }
Пример #12
0
        public void UpdateDetectionConfigurationRespectsTheCancellationToken()
        {
            MetricsAdvisorAdministrationClient adminClient = GetMetricsAdvisorAdministrationClient();

            var config = new AnomalyDetectionConfiguration(FakeGuid, default, default, default, default, new List <MetricSeriesGroupDetectionCondition>(), new List <MetricSingleSeriesDetectionCondition>());
        public async Task CreateAndGetDetectionConfigurationWithSeriesGroupConditions()
        {
            // Set required parameters of the configuration to be created.

            MetricsAdvisorAdministrationClient adminClient = GetMetricsAdvisorAdministrationClient();

            string configName = Recording.GenerateAlphaNumericId("config");

            var wholeConditions = new MetricWholeSeriesDetectionCondition()
            {
                HardThresholdCondition = new (AnomalyDetectorDirection.Down, new (1, 2.0))
                {
                    LowerBound = 10.0
                }
            };

            var configToCreate = new AnomalyDetectionConfiguration(MetricId, configName, wholeConditions);

            // Set the series group conditions and create the configuration.

            var groupKey1 = new DimensionKey();
            var groupKey2 = new DimensionKey();

            groupKey1.AddDimensionColumn("city", "Delhi");
            groupKey2.AddDimensionColumn("city", "Koltaka");

            var groupConditions0 = new MetricSeriesGroupDetectionCondition(groupKey1)
            {
                SmartDetectionCondition = new (30.0, AnomalyDetectorDirection.Both, new (3, 4.0))
            };

            var groupConditions1 = new MetricSeriesGroupDetectionCondition(groupKey2)
            {
                ChangeThresholdCondition = new (40.0, 12, false, AnomalyDetectorDirection.Up, new (5, 6.0))
            };

            configToCreate.SeriesGroupDetectionConditions.Add(groupConditions0);
            configToCreate.SeriesGroupDetectionConditions.Add(groupConditions1);

            await using var disposableConfig = await DisposableDetectionConfiguration.CreateDetectionConfigurationAsync(adminClient, configToCreate);

            // Get the created configuration and validate top-level members.

            AnomalyDetectionConfiguration createdConfig = await adminClient.GetDetectionConfigurationAsync(disposableConfig.Id);

            Assert.That(createdConfig.Id, Is.EqualTo(disposableConfig.Id));
            Assert.That(createdConfig.MetricId, Is.EqualTo(MetricId));
            Assert.That(createdConfig.Name, Is.EqualTo(configName));
            Assert.That(createdConfig.Description, Is.Empty);
            Assert.That(createdConfig.SeriesDetectionConditions, Is.Not.Null.And.Empty);

            // Validate whole series detection conditions.

            MetricWholeSeriesDetectionCondition createdWholeConditions = createdConfig.WholeSeriesDetectionConditions;

            Assert.That(createdWholeConditions, Is.Not.Null);
            Assert.That(createdWholeConditions.CrossConditionsOperator, Is.Null);
            Assert.That(createdWholeConditions.ChangeThresholdCondition, Is.Null);
            Assert.That(createdWholeConditions.SmartDetectionCondition, Is.Null);

            ValidateHardThresholdCondition(createdWholeConditions.HardThresholdCondition, AnomalyDetectorDirection.Down, null, 10.0, 1, 2.0);

            // Start series group conditions validation.

            Assert.That(createdConfig.SeriesGroupDetectionConditions, Is.Not.Null);
            Assert.That(createdConfig.SeriesGroupDetectionConditions.Count, Is.EqualTo(2));

            // Validate first series group conditions.

            var createdGroupConditions0 = createdConfig.SeriesGroupDetectionConditions[0];

            Assert.That(createdGroupConditions0, Is.Not.Null);

            ValidateGroupKey(createdGroupConditions0.SeriesGroupKey);

            Dictionary <string, string> dimensionColumns = createdGroupConditions0.SeriesGroupKey.AsDictionary();

            Assert.That(dimensionColumns.Count, Is.EqualTo(1));
            Assert.That(dimensionColumns["city"], Is.EqualTo("Delhi"));

            Assert.That(createdGroupConditions0.CrossConditionsOperator, Is.Null);
            Assert.That(createdGroupConditions0.HardThresholdCondition, Is.Null);
            Assert.That(createdGroupConditions0.ChangeThresholdCondition, Is.Null);

            ValidateSmartDetectionCondition(createdGroupConditions0.SmartDetectionCondition, 30.0, AnomalyDetectorDirection.Both, 3, 4.0);

            // Validate last series group conditions.

            var createdGroupConditions1 = createdConfig.SeriesGroupDetectionConditions[1];

            Assert.That(createdGroupConditions1, Is.Not.Null);

            ValidateGroupKey(createdGroupConditions1.SeriesGroupKey);

            dimensionColumns = createdGroupConditions1.SeriesGroupKey.AsDictionary();

            Assert.That(dimensionColumns.Count, Is.EqualTo(1));
            Assert.That(dimensionColumns["city"], Is.EqualTo("Koltaka"));

            Assert.That(createdGroupConditions1.CrossConditionsOperator, Is.Null);
            Assert.That(createdGroupConditions1.HardThresholdCondition, Is.Null);
            Assert.That(createdGroupConditions1.SmartDetectionCondition, Is.Null);

            ValidateChangeThresholdCondition(createdGroupConditions1.ChangeThresholdCondition, 40.0, 12, false, AnomalyDetectorDirection.Up, 5, 6.0);
        }
        public async Task CreateDataFeedFromDataSource()
        {
            string endpoint        = MetricsAdvisorUri;
            string subscriptionKey = MetricsAdvisorSubscriptionKey;
            string apiKey          = MetricsAdvisorApiKey;
            var    credential      = new MetricsAdvisorKeyCredential(subscriptionKey, apiKey);

            var adminClient = new MetricsAdvisorAdministrationClient(new Uri(endpoint), credential);

            string sqlServerConnectionString = SqlServerConnectionString;
            string sqlServerQuery            = SqlServerQuery;

            #region Snippet:CreateDataFeedFromDataSource
            //@@ string sqlServerConnectionString = "<connectionString>";
            //@@ string sqlServerQuery = "<query>";

            var dataFeedName        = "Sample data feed";
            var dataFeedSource      = new MySqlDataFeedSource(sqlServerConnectionString, sqlServerQuery);
            var dataFeedGranularity = new DataFeedGranularity(DataFeedGranularityType.Daily);

            var dataFeedMetrics = new List <DataFeedMetric>()
            {
                new DataFeedMetric("cost"),
                new DataFeedMetric("revenue")
            };
            var dataFeedDimensions = new List <MetricDimension>()
            {
                new MetricDimension("category"),
                new MetricDimension("city")
            };
            var dataFeedSchema = new DataFeedSchema(dataFeedMetrics)
            {
                DimensionColumns = dataFeedDimensions
            };

            var ingestionStartTime        = DateTimeOffset.Parse("2020-01-01T00:00:00Z");
            var dataFeedIngestionSettings = new DataFeedIngestionSettings(ingestionStartTime);

            Response <DataFeed> response = await adminClient.CreateDataFeedAsync(dataFeedName, dataFeedSource,
                                                                                 dataFeedGranularity, dataFeedSchema, dataFeedIngestionSettings);

            DataFeed dataFeed = response.Value;

            Console.WriteLine($"Data feed ID: {dataFeed.Id}");

            // Only the ID of the data feed is known at this point. You can perform another service
            // call to get more information, such as status, created time, the list of administrators,
            // or the metric IDs.

            response = await adminClient.GetDataFeedAsync(dataFeed.Id);

            dataFeed = response.Value;

            Console.WriteLine($"Data feed status: {dataFeed.Status.Value}");
            Console.WriteLine($"Data feed created time: {dataFeed.CreatedTime.Value}");

            Console.WriteLine($"Data feed administrators:");
            foreach (string admin in dataFeed.Options.Administrators)
            {
                Console.WriteLine($" - {admin}");
            }

            Console.WriteLine($"Metric IDs:");
            foreach (DataFeedMetric metric in dataFeed.Schema.MetricColumns)
            {
                Console.WriteLine($" - {metric.MetricName}: {metric.MetricId}");
            }

            #endregion

            // Delete the created data feed to clean up the Metrics Advisor resource. Do not perform this
            // step if you intend to keep using the data feed.

            await adminClient.DeleteDataFeedAsync(dataFeed.Id);
        }
Пример #15
0
        public async Task UpdateAlertConfigurationWithMinimumSetup(bool useTokenCrendential)
        {
            MetricsAdvisorAdministrationClient adminClient = GetMetricsAdvisorAdministrationClient(useTokenCrendential);

            await using DisposableDataFeed disposableDataFeed = await CreateTempDataFeedAsync(adminClient);

            string metricId = disposableDataFeed.DataFeed.MetricIds[TempDataFeedMetricName];

            await using DisposableDetectionConfiguration disposableDetectionConfig = await CreateTempDetectionConfigurationAsync(adminClient, metricId);

            // Configure the Metric Alert Configurations to be used.

            string hookName     = Recording.GenerateAlphaNumericId("hook");
            var    hookToCreate = new EmailNotificationHook(hookName)
            {
                EmailsToAlert = { "*****@*****.**" }
            };

            await using var disposableHook = await DisposableNotificationHook.CreateHookAsync(adminClient, hookToCreate);

            var detectionConfigId  = disposableDetectionConfig.Configuration.Id;
            var scope              = MetricAnomalyAlertScope.CreateScopeForWholeSeries();
            var metricAlertConfig0 = new MetricAlertConfiguration(detectionConfigId, scope)
            {
                AlertSnoozeCondition = new MetricAnomalyAlertSnoozeCondition(12, SnoozeScope.Series, true),
                AlertConditions      = new MetricAnomalyAlertConditions()
                {
                    MetricBoundaryCondition = new MetricBoundaryCondition(BoundaryDirection.Both)
                    {
                        UpperBound                    = 20.0,
                        LowerBound                    = 10.0,
                        CompanionMetricId             = metricId,
                        ShouldAlertIfDataPointMissing = true
                    },
                    SeverityCondition = new SeverityCondition(AnomalySeverity.Low, AnomalySeverity.Medium)
                }
            };
            var metricAlertConfig1 = new MetricAlertConfiguration(detectionConfigId, scope)
            {
                UseDetectionResultToFilterAnomalies = true
            };

            // Create the Anomaly Alert Configuration.

            string configName = Recording.GenerateAlphaNumericId("config");
            var    hookIds    = new List <string>()
            {
                disposableHook.Hook.Id
            };

            var configToCreate = new AnomalyAlertConfiguration()
            {
                Name = configName,
                IdsOfHooksToAlert         = { disposableHook.Hook.Id },
                MetricAlertConfigurations = { metricAlertConfig0, metricAlertConfig1 },
                CrossMetricsOperator      = MetricAlertConfigurationsOperator.Xor
            };

            await using var disposableConfig = await DisposableAlertConfiguration.CreateAlertConfigurationAsync(adminClient, configToCreate);

            // Update the created configuration.

            AnomalyAlertConfiguration configToUpdate = disposableConfig.Configuration;

            configToUpdate.CrossMetricsOperator = MetricAlertConfigurationsOperator.Or;

            AnomalyAlertConfiguration updatedConfig = await adminClient.UpdateAlertConfigurationAsync(configToUpdate);

            // Validate top-level members.

            Assert.That(updatedConfig.Id, Is.EqualTo(configToUpdate.Id));
            Assert.That(updatedConfig.Name, Is.EqualTo(configName));
            Assert.That(updatedConfig.Description, Is.Empty);
            Assert.That(updatedConfig.CrossMetricsOperator, Is.EqualTo(MetricAlertConfigurationsOperator.Or));
            Assert.That(updatedConfig.IdsOfHooksToAlert, Is.EqualTo(hookIds));
            Assert.That(updatedConfig.DimensionsToSplitAlert, Is.Not.Null.And.Empty);
            Assert.That(updatedConfig.MetricAlertConfigurations, Is.Not.Null);
            Assert.That(updatedConfig.MetricAlertConfigurations.Count, Is.EqualTo(2));

            // Validate the first Metric Alert Configuration.

            MetricAlertConfiguration updatedMetricAlertConfig0 = updatedConfig.MetricAlertConfigurations[0];

            Assert.That(updatedMetricAlertConfig0.DetectionConfigurationId, Is.EqualTo(detectionConfigId));

            Assert.That(updatedMetricAlertConfig0.AlertScope, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig0.AlertScope.ScopeType, Is.EqualTo(MetricAnomalyAlertScopeType.WholeSeries));
            Assert.That(updatedMetricAlertConfig0.AlertScope.SeriesGroupInScope, Is.Null);
            Assert.That(updatedMetricAlertConfig0.AlertScope.TopNGroupInScope, Is.Null);

            Assert.That(updatedMetricAlertConfig0.AlertConditions, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig0.AlertConditions.MetricBoundaryCondition, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.Direction, Is.EqualTo(BoundaryDirection.Both));
            Assert.That(updatedMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.UpperBound, Is.EqualTo(20.0));
            Assert.That(updatedMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.LowerBound, Is.EqualTo(10.0));
            Assert.That(updatedMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.CompanionMetricId, Is.EqualTo(metricId));
            Assert.That(updatedMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.ShouldAlertIfDataPointMissing, Is.True);
            Assert.That(updatedMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.MeasureType, Is.EqualTo(BoundaryMeasureType.Value));
            Assert.That(updatedMetricAlertConfig0.AlertConditions.SeverityCondition, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig0.AlertConditions.SeverityCondition.MinimumAlertSeverity, Is.EqualTo(AnomalySeverity.Low));
            Assert.That(updatedMetricAlertConfig0.AlertConditions.SeverityCondition.MaximumAlertSeverity, Is.EqualTo(AnomalySeverity.Medium));

            Assert.That(updatedMetricAlertConfig0.AlertSnoozeCondition, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig0.AlertSnoozeCondition.AutoSnooze, Is.EqualTo(12));
            Assert.That(updatedMetricAlertConfig0.AlertSnoozeCondition.SnoozeScope, Is.EqualTo(SnoozeScope.Series));
            Assert.That(updatedMetricAlertConfig0.AlertSnoozeCondition.IsOnlyForSuccessive, Is.True);

            Assert.That(updatedMetricAlertConfig0.UseDetectionResultToFilterAnomalies, Is.False);

            // Validate the second Metric Alert Configuration.

            MetricAlertConfiguration updatedMetricAlertConfig1 = updatedConfig.MetricAlertConfigurations[1];

            Assert.That(updatedMetricAlertConfig1.DetectionConfigurationId, Is.EqualTo(detectionConfigId));

            Assert.That(updatedMetricAlertConfig1.AlertScope, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig1.AlertScope.ScopeType, Is.EqualTo(MetricAnomalyAlertScopeType.WholeSeries));
            Assert.That(updatedMetricAlertConfig1.AlertScope.SeriesGroupInScope, Is.Null);
            Assert.That(updatedMetricAlertConfig1.AlertScope.TopNGroupInScope, Is.Null);

            Assert.That(updatedMetricAlertConfig1.AlertConditions, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig1.AlertConditions.MetricBoundaryCondition, Is.Null);
            Assert.That(updatedMetricAlertConfig1.AlertConditions.SeverityCondition, Is.Null);
            Assert.That(updatedMetricAlertConfig1.AlertSnoozeCondition, Is.Null);
            Assert.That(updatedMetricAlertConfig1.UseDetectionResultToFilterAnomalies, Is.True);
        }
        public async Task CreateAndDeleteDataFeedAsync()
        {
            string endpoint        = MetricsAdvisorUri;
            string subscriptionKey = MetricsAdvisorSubscriptionKey;
            string apiKey          = MetricsAdvisorApiKey;
            var    credential      = new MetricsAdvisorKeyCredential(subscriptionKey, apiKey);

            var adminClient = new MetricsAdvisorAdministrationClient(new Uri(endpoint), credential);

            #region Snippet:CreateDataFeedAsync
#if SNIPPET
            string sqlServerConnectionString = "<connectionString>";
            string sqlServerQuery            = "<query>";
#else
            string sqlServerConnectionString = SqlServerConnectionString;
            string sqlServerQuery            = SqlServerQuery;
#endif

            var dataFeed = new DataFeed();

#if SNIPPET
            dataFeed.Name = "<dataFeedName>";
#else
            dataFeed.Name = GetUniqueName();
#endif
            dataFeed.DataSource  = new SqlServerDataFeedSource(sqlServerConnectionString, sqlServerQuery);
            dataFeed.Granularity = new DataFeedGranularity(DataFeedGranularityType.Daily);

            dataFeed.Schema = new DataFeedSchema();
            dataFeed.Schema.MetricColumns.Add(new DataFeedMetric("cost"));
            dataFeed.Schema.MetricColumns.Add(new DataFeedMetric("revenue"));
            dataFeed.Schema.DimensionColumns.Add(new DataFeedDimension("category"));
            dataFeed.Schema.DimensionColumns.Add(new DataFeedDimension("city"));

            dataFeed.IngestionSettings = new DataFeedIngestionSettings()
            {
                IngestionStartTime = DateTimeOffset.Parse("2020-01-01T00:00:00Z")
            };

            Response <DataFeed> response = await adminClient.CreateDataFeedAsync(dataFeed);

            DataFeed createdDataFeed = response.Value;

            Console.WriteLine($"Data feed ID: {createdDataFeed.Id}");
            Console.WriteLine($"Data feed status: {createdDataFeed.Status.Value}");
            Console.WriteLine($"Data feed created time: {createdDataFeed.CreatedTime.Value}");

            Console.WriteLine($"Data feed administrators:");
            foreach (string admin in createdDataFeed.AdministratorsEmails)
            {
                Console.WriteLine($" - {admin}");
            }

            Console.WriteLine($"Metric IDs:");
            foreach (DataFeedMetric metric in createdDataFeed.Schema.MetricColumns)
            {
                Console.WriteLine($" - {metric.Name}: {metric.Id}");
            }

            Console.WriteLine($"Dimension columns:");
            foreach (DataFeedDimension dimension in createdDataFeed.Schema.DimensionColumns)
            {
                Console.WriteLine($" - {dimension.Name}");
            }
            #endregion

            // Delete the created data feed to clean up the Metrics Advisor resource. Do not perform this
            // step if you intend to keep using the data feed.

            await adminClient.DeleteDataFeedAsync(createdDataFeed.Id);
        }
Пример #17
0
        public async Task UpdateAlertConfigurationWithEveryMember()
        {
            MetricsAdvisorAdministrationClient adminClient = GetMetricsAdvisorAdministrationClient();

            await using DisposableDataFeed disposableDataFeed = await CreateTempDataFeedAsync(adminClient);

            string metricId = disposableDataFeed.DataFeed.MetricIds[TempDataFeedMetricName];

            await using DisposableDetectionConfiguration disposableDetectionConfig = await CreateTempDetectionConfigurationAsync(adminClient, metricId);

            // Configure the Metric Alert Configurations to be used.

            string hookName     = Recording.GenerateAlphaNumericId("hook");
            var    hookToCreate = new EmailNotificationHook(hookName)
            {
                EmailsToAlert = { "*****@*****.**" }
            };

            await using var disposableHook = await DisposableNotificationHook.CreateHookAsync(adminClient, hookToCreate);

            var detectionConfigId  = disposableDetectionConfig.Configuration.Id;
            var scope              = MetricAnomalyAlertScope.CreateScopeForWholeSeries();
            var metricAlertConfig0 = new MetricAlertConfiguration(detectionConfigId, scope)
            {
                AlertSnoozeCondition = new MetricAnomalyAlertSnoozeCondition(12, SnoozeScope.Series, true),
                AlertConditions      = new MetricAnomalyAlertConditions()
                {
                    MetricBoundaryCondition = new MetricBoundaryCondition(BoundaryDirection.Both)
                    {
                        UpperBound                    = 20.0,
                        LowerBound                    = 10.0,
                        CompanionMetricId             = metricId,
                        ShouldAlertIfDataPointMissing = true
                    },
                    SeverityCondition = new SeverityCondition(AnomalySeverity.Low, AnomalySeverity.Medium)
                }
            };
            var metricAlertConfig1 = new MetricAlertConfiguration(detectionConfigId, scope)
            {
                UseDetectionResultToFilterAnomalies = true
            };

            // Create the Anomaly Alert Configuration.

            string configName  = Recording.GenerateAlphaNumericId("config");
            var    description = "This hook was created to test the .NET client.";
            var    hookIds     = new List <string>()
            {
                disposableHook.Hook.Id
            };
            var metricAlertConfigs = new List <MetricAlertConfiguration>()
            {
                metricAlertConfig0, metricAlertConfig1
            };

            var configToCreate = new AnomalyAlertConfiguration()
            {
                Name = configName,
                IdsOfHooksToAlert         = { disposableHook.Hook.Id },
                MetricAlertConfigurations = { metricAlertConfig0, metricAlertConfig1 },
                CrossMetricsOperator      = MetricAlertConfigurationsOperator.Xor
            };

            await using var disposableConfig = await DisposableAlertConfiguration.CreateAlertConfigurationAsync(adminClient, configToCreate);

            // Update the created configuration.

            AnomalyAlertConfiguration configToUpdate = disposableConfig.Configuration;

            configToUpdate.Description = description;
            configToUpdate.IdsOfHooksToAlert.Clear();
            configToUpdate.DimensionsToSplitAlert.Add(TempDataFeedDimensionNameA);
            configToUpdate.CrossMetricsOperator = MetricAlertConfigurationsOperator.And;
            configToUpdate.MetricAlertConfigurations.RemoveAt(1);

            var newScope             = MetricAnomalyAlertScope.CreateScopeForTopNGroup(50, 40, 30);
            var newMetricAlertConfig = new MetricAlertConfiguration(detectionConfigId, newScope)
            {
                AlertSnoozeCondition = new MetricAnomalyAlertSnoozeCondition(4, SnoozeScope.Metric, true),
                UseDetectionResultToFilterAnomalies = true
            };

            configToUpdate.MetricAlertConfigurations.Add(newMetricAlertConfig);

            MetricAlertConfiguration metricAlertConfigToUpdate = configToUpdate.MetricAlertConfigurations[0];

            metricAlertConfigToUpdate.AlertConditions.MetricBoundaryCondition.UpperBound                    = 15.0;
            metricAlertConfigToUpdate.AlertConditions.MetricBoundaryCondition.LowerBound                    = 5.0;
            metricAlertConfigToUpdate.AlertConditions.MetricBoundaryCondition.CompanionMetricId             = null;
            metricAlertConfigToUpdate.AlertConditions.MetricBoundaryCondition.ShouldAlertIfDataPointMissing = false;
            metricAlertConfigToUpdate.AlertConditions.MetricBoundaryCondition.MeasureType                   = BoundaryMeasureType.Mean;

            metricAlertConfigToUpdate.AlertConditions.SeverityCondition = new SeverityCondition(AnomalySeverity.Medium, AnomalySeverity.High);

            metricAlertConfigToUpdate.AlertSnoozeCondition = null;

            AnomalyAlertConfiguration updatedConfig = await adminClient.UpdateAlertConfigurationAsync(configToUpdate);

            // Validate top-level members.

            Assert.That(updatedConfig.Id, Is.EqualTo(configToUpdate.Id));
            Assert.That(updatedConfig.Name, Is.EqualTo(configName));
            Assert.That(updatedConfig.Description, Is.EqualTo(description));
            Assert.That(updatedConfig.CrossMetricsOperator, Is.EqualTo(MetricAlertConfigurationsOperator.And));
            Assert.That(updatedConfig.IdsOfHooksToAlert, Is.Not.Null.And.Empty);
            Assert.That(updatedConfig.DimensionsToSplitAlert.Single(), Is.EqualTo(TempDataFeedDimensionNameA));
            Assert.That(updatedConfig.MetricAlertConfigurations, Is.Not.Null);

            // Validate the first Metric Alert Configuration.

            MetricAlertConfiguration updatedMetricAlertConfig0 = updatedConfig.MetricAlertConfigurations[0];

            Assert.That(updatedMetricAlertConfig0.DetectionConfigurationId, Is.EqualTo(detectionConfigId));

            Assert.That(updatedMetricAlertConfig0.AlertScope, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig0.AlertScope.ScopeType, Is.EqualTo(MetricAnomalyAlertScopeType.WholeSeries));
            Assert.That(updatedMetricAlertConfig0.AlertScope.SeriesGroupInScope, Is.Null);
            Assert.That(updatedMetricAlertConfig0.AlertScope.TopNGroupInScope, Is.Null);

            Assert.That(updatedMetricAlertConfig0.AlertConditions, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig0.AlertConditions.MetricBoundaryCondition, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.Direction, Is.EqualTo(BoundaryDirection.Both));
            Assert.That(updatedMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.UpperBound, Is.EqualTo(15.0));
            Assert.That(updatedMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.LowerBound, Is.EqualTo(5.0));
            Assert.That(updatedMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.CompanionMetricId, Is.Null);
            Assert.That(updatedMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.ShouldAlertIfDataPointMissing, Is.False);
            Assert.That(updatedMetricAlertConfig0.AlertConditions.MetricBoundaryCondition.MeasureType, Is.EqualTo(BoundaryMeasureType.Mean));
            Assert.That(updatedMetricAlertConfig0.AlertConditions.SeverityCondition, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig0.AlertConditions.SeverityCondition.MinimumAlertSeverity, Is.EqualTo(AnomalySeverity.Medium));
            Assert.That(updatedMetricAlertConfig0.AlertConditions.SeverityCondition.MaximumAlertSeverity, Is.EqualTo(AnomalySeverity.High));

            Assert.That(updatedMetricAlertConfig0.AlertSnoozeCondition, Is.Null);
            Assert.That(updatedMetricAlertConfig0.UseDetectionResultToFilterAnomalies, Is.False);

            // Validate the second Metric Alert Configuration.

            MetricAlertConfiguration updatedMetricAlertConfig1 = updatedConfig.MetricAlertConfigurations[1];

            Assert.That(updatedMetricAlertConfig1.DetectionConfigurationId, Is.EqualTo(detectionConfigId));

            Assert.That(updatedMetricAlertConfig1.AlertScope, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig1.AlertScope.ScopeType, Is.EqualTo(MetricAnomalyAlertScopeType.TopN));
            Assert.That(updatedMetricAlertConfig1.AlertScope.SeriesGroupInScope, Is.Null);
            Assert.That(updatedMetricAlertConfig1.AlertScope.TopNGroupInScope, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig1.AlertScope.TopNGroupInScope.Top, Is.EqualTo(50));
            Assert.That(updatedMetricAlertConfig1.AlertScope.TopNGroupInScope.Period, Is.EqualTo(40));
            Assert.That(updatedMetricAlertConfig1.AlertScope.TopNGroupInScope.MinimumTopCount, Is.EqualTo(30));

            Assert.That(updatedMetricAlertConfig1.AlertConditions, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig1.AlertConditions.MetricBoundaryCondition, Is.Null);
            Assert.That(updatedMetricAlertConfig1.AlertConditions.SeverityCondition, Is.Null);

            Assert.That(updatedMetricAlertConfig1.AlertSnoozeCondition, Is.Not.Null);
            Assert.That(updatedMetricAlertConfig1.AlertSnoozeCondition.AutoSnooze, Is.EqualTo(4));
            Assert.That(updatedMetricAlertConfig1.AlertSnoozeCondition.SnoozeScope, Is.EqualTo(SnoozeScope.Metric));
            Assert.That(updatedMetricAlertConfig1.AlertSnoozeCondition.IsOnlyForSuccessive, Is.True);

            Assert.That(updatedMetricAlertConfig1.UseDetectionResultToFilterAnomalies, Is.True);
        }
Пример #18
0
        internal async Task <MetricAnomalyDetectionConfiguration> CreateMetricAnomalyDetectionConfiguration(MetricsAdvisorAdministrationClient adminClient)
        {
            DataFeed feed = await GetFirstDataFeed(adminClient).ConfigureAwait(false);

            var config = new MetricAnomalyDetectionConfiguration(
                feed.MetricIds.First(),
                Recording.GenerateAlphaNumericId("Name"),
                new MetricAnomalyDetectionConditions(
                    DetectionConditionsOperator.And,
                    new SmartDetectionCondition(42, AnomalyDetectorDirection.Both, new SuppressCondition(1, 67)),
                    new HardThresholdCondition(23, 45, AnomalyDetectorDirection.Both, new SuppressCondition(1, 50)),
                    new ChangeThresholdCondition(12, 5, true, AnomalyDetectorDirection.Both, new SuppressCondition(1, 1))));

            return(await adminClient.CreateMetricAnomalyDetectionConfigurationAsync(config).ConfigureAwait(false));
        }
Пример #19
0
        private async Task <DisposableDetectionConfiguration> CreateTempDetectionConfigurationAsync(MetricsAdvisorAdministrationClient adminClient, string metricId)
        {
            var config = new AnomalyDetectionConfiguration()
            {
                Name     = Recording.GenerateAlphaNumericId("dataFeed"),
                MetricId = metricId,
                WholeSeriesDetectionConditions = new MetricWholeSeriesDetectionCondition()
                {
                    HardThresholdCondition = new HardThresholdCondition(AnomalyDetectorDirection.Up, new SuppressCondition(1, 1.0))
                    {
                        UpperBound = 1.0
                    }
                }
            };

            return(await DisposableDetectionConfiguration.CreateDetectionConfigurationAsync(adminClient, config));
        }
Пример #20
0
        /// <summary>
        /// Creates a data feed using the specified <see cref="MetricsAdvisorAdministrationClient"/>.
        /// A <see cref="DisposableDataFeed"/> instance is returned, from which the created data feed
        /// can be obtained. Upon disposal, the associated data feed will be deleted.
        /// </summary>
        /// <param name="adminClient">The client to use for creating and for deleting the data feed.</param>
        /// <param name="dataFeed">Specifies how the created <see cref="Models.DataFeed"/> should be configured.</param>
        /// <returns>A <see cref="DisposableDataFeed"/> instance from which the created data feed can be obtained.</returns>
        public static async Task <DisposableDataFeed> CreateDataFeedAsync(MetricsAdvisorAdministrationClient adminClient, DataFeed dataFeed)
        {
            DataFeed createdDataFeed = await adminClient.CreateDataFeedAsync(dataFeed);

            return(new DisposableDataFeed(adminClient, createdDataFeed));
        }
        public void UpdateHookRespectsTheCancellationToken()
        {
            MetricsAdvisorAdministrationClient adminClient = GetMetricsAdvisorAdministrationClient();

            var hook = new EmailNotificationHook(default, FakeGuid, default, default, default, new List <string>(), new EmailHookParameter(new List <string>()));