你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

适用于 .NET 的 Azure 指标顾问客户端库 - 版本 1.1.0

Azure 认知服务指标顾问是一项云服务,它使用机器学习来监视和检测时序数据中的异常。 它包括以下功能:

  • 分析来自多个数据源的多维数据。
  • 识别并关联异常。
  • 配置和微调对数据使用的异常情况检测模型。
  • 诊断异常,并帮助进行根本原因分析。

源代码 | 包 (NuGet) | API 参考文档 | 产品文档 | 样品

入门

安装包

使用 NuGet 安装适用于 .NET 的 Azure 指标顾问客户端库:

dotnet add package Azure.AI.MetricsAdvisor

先决条件

创建“指标顾问”资源

可以使用以下方法创建指标顾问资源:

选项 1Azure 门户

选项 2Azure CLI

下面是如何使用 CLI 创建指标顾问资源的示例:

# Create a new resource group to hold the Metrics Advisor resource.
# If using an existing resource group, skip this step.
az group create --name <your-resource-name> --location <location>
# Create the Metrics Advisor resource.
az cognitiveservices account create \
    --name <your-resource-name> \
    --resource-group <your-resource-group-name> \
    --kind MetricsAdvisor \
    --sku <sku> \
    --location <location>
    --yes

有关创建资源以及如何获取位置和 SKU 信息的详细信息,请参阅 此处

验证客户端

若要与指标顾问服务交互,需要创建 或 MetricsAdvisorAdministrationClient 类的MetricsAdvisorClient实例。 需要 终结点订阅密钥API 密钥 来实例化客户端对象。

获取终结点和订阅密钥

可以从 Azure 门户中的资源信息获取终结点和订阅密钥。

或者,可以使用下面的 Azure CLI 代码片段从指标顾问资源获取订阅密钥。

az cognitiveservices account keys list --resource-group <your-resource-group-name> --name <your-resource-name>

获取 API 密钥

可以在 指标顾问 Web 门户中获取 API 密钥。 系统会提示登录进行身份验证。

登录后,填写 Azure Active Directory、订阅和指标顾问资源名称。

创建 MetricsAdvisorClient 或 MetricsAdvisorAdministrationClient

获得订阅和 API 密钥后,创建 MetricsAdvisorKeyCredential。 借助终结点和密钥凭据,可以创建 MetricsAdvisorClient

string endpoint = "<endpoint>";
string subscriptionKey = "<subscriptionKey>";
string apiKey = "<apiKey>";
var credential = new MetricsAdvisorKeyCredential(subscriptionKey, apiKey);
var client = new MetricsAdvisorClient(new Uri(endpoint), credential);

你还可以创建 MetricsAdvisorAdministrationClient 来执行管理操作:

string endpoint = "<endpoint>";
string subscriptionKey = "<subscriptionKey>";
string apiKey = "<apiKey>";
var credential = new MetricsAdvisorKeyCredential(subscriptionKey, apiKey);
var adminClient = new MetricsAdvisorAdministrationClient(new Uri(endpoint), credential);

使用 Azure Active Directory 创建 MetricsAdvisorClient 或 MetricsAdvisorAdministrationClient

MetricsAdvisorKeyCredential 本入门指南中的示例使用了身份验证,但也可以使用 Azure 标识库通过 Azure Active Directory 进行身份验证。

若要使用如下所示的 DefaultAzureCredential 提供程序或 Azure SDK 随附的其他凭据提供程序,请安装 Azure.Identity 包:

Install-Package Azure.Identity

还需要注册新的 AAD 应用程序,并通过将"Cognitive Services Metrics Advisor User"角色分配给服务主体来授予对指标顾问的访问权限。 如果需要管理员权限, "Cognitive Services Metrics Advisor Administrator" 可能需要改为分配角色。

将 AAD 应用程序的客户端 ID、租户 ID 和客户端密码的值设置为环境变量:AZURE_CLIENT_ID、AZURE_TENANT_ID、AZURE_CLIENT_SECRET。

设置环境变量后,可以创建 MetricsAdvisorClient

string endpoint = "<endpoint>";
var client = new MetricsAdvisorClient(new Uri(endpoint), new DefaultAzureCredential());

或者,还可以创建 以 MetricsAdvisorAdministrationClient 执行管理操作:

string endpoint = "<endpoint>";
var adminClient = new MetricsAdvisorAdministrationClient(new Uri(endpoint), new DefaultAzureCredential());

关键概念

MetricsAdvisorClient

MetricsAdvisorClient 是面向使用指标顾问客户端库的开发人员的主要查询接口。 它提供了同步和异步方法来访问指标顾问的特定用途,例如列出事件、检索事件的根本原因以及检索时序数据。

MetricsAdvisorAdministrationClient

MetricsAdvisorAdministrationClient 是负责管理指标顾问资源中的实体的接口。 它为创建和更新数据馈送、异常情况检测配置以及异常警报配置等任务提供同步和异步方法。

数据馈送

DataFeed定期从数据源(例如 CosmosDB 或 SQL Server)引入聚合数据的表,并使其可用于指标顾问服务。 它是数据的入口点,因此,在发生异常情况检测之前,需要设置的第一个代理。 有关详细信息,请参阅下面的 从数据源创建数据馈送 示例。

数据馈送指标

DataFeedMetric简称“指标”是一种可量化的度量值,用于监视评估特定业务流程的状态。 这可能是产品在几个月内的成本,甚至是每日温度测量值。 服务将监视此值随时间的变化情况,以搜索任何异常行为。 数据馈送可以从同一数据源引入多个指标。

数据馈送维度

DataFeedDimension或简称“维度”)是一个确定 指标特征的分类值。 例如,如果指标表示产品的成本,则产品类型 (例如鞋、帽子) 以及这些值 (测量的城市(例如纽约、东京) )可用作维度。 多个维度的组合标识特定的单变量 时序

时序

时序是按时间顺序编制索引的数据点序列。 这些数据点描述 指标 值随时间的变化。

给定指标后,指标顾问服务将为 维度 值的每个可能组合创建一个系列,这意味着可以针对同一指标监视多个时序。

例如,假设数据源返回以下数据列:

城市 类别 成本 收入
纽约 1045.00 1345.00
纽约 帽子 670.00 502.00
德里 991.00 1009.00
德里 帽子 623.00 711.00

成本和收入是希望服务监视的指标,而城市和类别是这些指标的特征维度。 此数据中有 4 种可能的维度组合:

  • City = New York, Category = Shoes
  • 城市 = 纽约,类别 = 帽子
  • 城市 = 德里,类别 = 鞋子
  • 城市 = 德里,类别 = 帽子

对于每个指标,服务将创建 4 个时序来监视数据,每个时序表示一个可能的维度组合。 每次发生数据源引入时,这些系列都将更新为新的数据点(如果新引入的数据中可用)。

数据点异常

DataPointAnomaly时序中的数据点出现意外行为时,将发生 ,或简称为“异常”。 当数据点值过高或过低时,或者当其值在收盘点之间突然更改时,可能会出现此情况。 可以使用 指定数据点必须满足的条件才能被视为异常 AnomalyDetectionConfiguration。 数据引入发生后,服务会将所有现有配置应用于新点集,以搜索异常。 有关详细信息,请参阅下面的 创建异常情况检测配置 示例。

异常事件

如果在特定时间戳的一个指标内的多个时序上检测到异常,指标顾问服务将自动将具有相同根本原因的异常分组为一个 AnomalyIncident,或者只是“事件”。 这将显著消除检查每个异常的工作量,并快速找到问题最重要的因素。

异常警报

AnomalyAlert检测到的 异常 符合指定条件时,将触发或简称为“警报”。 例如,每次检测到严重性较高的异常时,都可能会触发警报。 可以指定异常必须满足的条件才能使用 AnomalyAlertConfiguration触发警报。 对新引入的数据点执行异常情况检测后,服务会将所有现有配置应用于新的异常,并且每个配置都会针对满足指定条件的点集触发单个警报。 默认情况下未设置警报配置,因此需要创建一个警报才能开始触发警报。 有关详细信息,请参阅下面的 创建异常警报配置 示例。

通知挂钩

NotificationHook(或简称“挂钩”)是订阅警报通知的一种方式。 可以将挂钩传递给 , AnomalyAlertConfiguration 并开始获取它创建的每个警报的通知。 有关详细信息,请参阅下面的 创建用于接收异常警报的挂钩 示例。

线程安全

我们保证所有客户端实例方法都是线程安全的,并且相互独立, (准则) 。 这可确保重用客户端实例的建议始终是安全的,即使跨线程也是如此。

其他概念

客户端选项 | 访问响应 | 处理失败 | 诊断 | 嘲笑 | 客户端生存期

示例

以下部分提供了几个代码片段,说明指标顾问 .NET API 中使用的常见模式。 以下代码片段使用异步服务调用,但请注意,Azure.AI.MetricsAdvisor 包支持同步 API 和异步 API。

从数据源创建数据馈送

指标顾问支持多种类型的数据源。 在此示例中,我们将演示如何创建一个从 SQL Server 提取数据的 DataFeed

string sqlServerConnectionString = "<connectionString>";
string sqlServerQuery = "<query>";

var dataFeed = new DataFeed();

dataFeed.Name = "<dataFeedName>";
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(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.CreatedOn.Value}");

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

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

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

其他数据源身份验证替代方法

某些数据源支持多种类型的身份验证。 例如, SqlServerDataFeedSource 支持连接字符串、服务主体和托管标识。 可在此处检查数据源及其身份验证类型的完整列表。

确保数据源支持要使用的身份验证后,需要在创建或更新数据源时设置 Authentication 属性:

var dataSoure = new SqlServerDataFeedSource("<connection-string>", "<query>")
{
    Authentication = SqlServerDataFeedSource.AuthenticationType.ManagedIdentity
};

请注意,除了 Basic 身份验证的 和 ManagedIdentity 类型外,还需要在服务中具有相应的 DataSourceCredentialEntity ID。 若要创建凭据实体,需要执行以下操作:

string credentialName = "<credentialName>";

var credentialEntity = new ServicePrincipalCredentialEntity(credentialName, "<clientId>", "<clientSecret>", "<tenantId>");

Response<DataSourceCredentialEntity> response = await adminClient.CreateDataSourceCredentialAsync(credentialEntity);

DataSourceCredentialEntity createdCredentialEntity = response.Value;

Console.WriteLine($"Credential entity ID: {createdCredentialEntity.Id}");

获得 ID 后,在设置数据源时将其添加到 DataSourceCredentialId 属性:

var dataSoure = new SqlServerDataFeedSource("<connection-string>", "<query>")
{
    Authentication = SqlServerDataFeedSource.AuthenticationType.ServicePrincipal,
    DataSourceCredentialId = "<credentialId>"
};

检查数据馈送的引入状态

检查以前创建的 DataFeed的引入状态。

string dataFeedId = "<dataFeedId>";

var startsOn = DateTimeOffset.Parse("2020-01-01T00:00:00Z");
var endsOn = DateTimeOffset.Parse("2020-09-09T00:00:00Z");
var options = new GetDataFeedIngestionStatusesOptions(startsOn, endsOn)
{
    MaxPageSize = 5
};

Console.WriteLine("Ingestion statuses:");
Console.WriteLine();

int statusCount = 0;

await foreach (DataFeedIngestionStatus ingestionStatus in adminClient.GetDataFeedIngestionStatusesAsync(dataFeedId, options))
{
    Console.WriteLine($"Timestamp: {ingestionStatus.Timestamp}");
    Console.WriteLine($"Status: {ingestionStatus.Status}");
    Console.WriteLine($"Service message: {ingestionStatus.Message}");
    Console.WriteLine();

    // Print at most 5 statuses.
    if (++statusCount >= 5)
    {
        break;
    }
}

创建异常情况检测配置

创建 以 AnomalyDetectionConfiguration 告知服务应将哪些数据点视为异常。

string metricId = "<metricId>";
string configurationName = "<configurationName>";

var detectionConfiguration = new AnomalyDetectionConfiguration()
{
    MetricId = metricId,
    Name = configurationName,
    WholeSeriesDetectionConditions = new MetricWholeSeriesDetectionCondition()
};

var detectCondition = detectionConfiguration.WholeSeriesDetectionConditions;

var hardSuppress = new SuppressCondition(1, 100);
detectCondition.HardThresholdCondition = new HardThresholdCondition(AnomalyDetectorDirection.Down, hardSuppress)
{
    LowerBound = 5.0
};

var smartSuppress = new SuppressCondition(4, 50);
detectCondition.SmartDetectionCondition = new SmartDetectionCondition(10.0, AnomalyDetectorDirection.Up, smartSuppress);

detectCondition.ConditionOperator = DetectionConditionOperator.Or;

Response<AnomalyDetectionConfiguration> response = await adminClient.CreateDetectionConfigurationAsync(detectionConfiguration);

AnomalyDetectionConfiguration createdDetectionConfiguration = response.Value;

Console.WriteLine($"Anomaly detection configuration ID: {createdDetectionConfiguration.Id}");

创建用于接收异常警报的挂钩

指标顾问支持 EmailNotificationHookWebNotificationHook 类作为订阅 警报 通知的方式。 在此示例中,我们将演示如何创建 EmailNotificationHook。 请注意,需要将挂钩传递到异常警报配置,才能开始接收通知。 有关详细信息,请参阅下面的 创建异常警报配置 示例。

string hookName = "<hookName>";

var emailHook = new EmailNotificationHook(hookName);

emailHook.EmailsToAlert.Add("email1@sample.com");
emailHook.EmailsToAlert.Add("email2@sample.com");

Response<NotificationHook> response = await adminClient.CreateHookAsync(emailHook);

NotificationHook createdHook = response.Value;

Console.WriteLine($"Hook ID: {createdHook.Id}");

创建异常警报配置

创建一个 AnomalyAlertConfiguration,告诉服务哪些异常会触发警报。

string hookId = "<hookId>";
string anomalyDetectionConfigurationId = "<anomalyDetectionConfigurationId>";
string configurationName = "<configurationName>";

AnomalyAlertConfiguration alertConfiguration = new AnomalyAlertConfiguration()
{
    Name = configurationName
};

alertConfiguration.IdsOfHooksToAlert.Add(hookId);

var scope = MetricAnomalyAlertScope.CreateScopeForWholeSeries();
var metricAlertConfiguration = new MetricAlertConfiguration(anomalyDetectionConfigurationId, scope);

alertConfiguration.MetricAlertConfigurations.Add(metricAlertConfiguration);

Response<AnomalyAlertConfiguration> response = await adminClient.CreateAlertConfigurationAsync(alertConfiguration);

AnomalyAlertConfiguration createdAlertConfiguration = response.Value;

Console.WriteLine($"Alert configuration ID: {createdAlertConfiguration.Id}");

查询检测到的异常和触发的警报

查看由给定异常警报 配置创建的警报

string anomalyAlertConfigurationId = "<anomalyAlertConfigurationId>";

var startsOn = DateTimeOffset.Parse("2020-01-01T00:00:00Z");
var endsOn = DateTimeOffset.UtcNow;
var options = new GetAlertsOptions(startsOn, endsOn, AlertQueryTimeMode.AnomalyDetectedOn)
{
    MaxPageSize = 5
};

int alertCount = 0;

await foreach (AnomalyAlert alert in client.GetAlertsAsync(anomalyAlertConfigurationId, options))
{
    Console.WriteLine($"Alert created at: {alert.CreatedOn}");
    Console.WriteLine($"Alert at timestamp: {alert.Timestamp}");
    Console.WriteLine($"Id: {alert.Id}");
    Console.WriteLine();

    // Print at most 5 alerts.
    if (++alertCount >= 5)
    {
        break;
    }
}

知道警报的 ID 后,列出触发此警报的异常

string alertConfigurationId = "<alertConfigurationId>";
string alertId = "<alertId>";

var options = new GetAnomaliesForAlertOptions() { MaxPageSize = 3 };

int anomalyCount = 0;

await foreach (DataPointAnomaly anomaly in client.GetAnomaliesForAlertAsync(alertConfigurationId, alertId, options))
{
    Console.WriteLine($"Anomaly detection configuration ID: {anomaly.DetectionConfigurationId}");
    Console.WriteLine($"Data feed ID: {anomaly.DataFeedId}");
    Console.WriteLine($"Metric ID: {anomaly.MetricId}");
    Console.WriteLine($"Anomaly value: {anomaly.Value}");

    if (anomaly.ExpectedValue.HasValue)
    {
        Console.WriteLine($"Anomaly expected value: {anomaly.ExpectedValue}");
    }

    Console.WriteLine($"Anomaly at timestamp: {anomaly.Timestamp}");
    Console.WriteLine($"Anomaly detected at: {anomaly.CreatedOn}");
    Console.WriteLine($"Status: {anomaly.Status}");
    Console.WriteLine($"Severity: {anomaly.Severity}");
    Console.WriteLine("Series key:");

    foreach (KeyValuePair<string, string> dimension in anomaly.SeriesKey)
    {
        Console.WriteLine($"  Dimension '{dimension.Key}': {dimension.Value}");
    }

    Console.WriteLine();

    // Print at most 3 anomalies.
    if (++anomalyCount >= 3)
    {
        break;
    }
}

疑难解答

常规

使用 .NET SDK 与认知服务指标顾问客户端库交互时,服务返回的错误将导致 REST RequestFailedExceptionAPI 请求返回的 HTTP 状态代码相同。

例如,如果尝试从具有不存在 ID 的服务获取数据馈送,则会返回一个 404 错误,指示“找不到”。

string dataFeedId = "00000000-0000-0000-0000-000000000000";

try
{
    Response<DataFeed> response = await adminClient.GetDataFeedAsync(dataFeedId);
}
catch (RequestFailedException ex)
{
    Console.WriteLine(ex.ToString());
}

请注意,会记录其他信息,例如服务返回的错误消息。

Azure.RequestFailedException: Service request failed.
Status: 404 (Not Found)

Content:
{"code":"ERROR_INVALID_PARAMETER","message":"datafeedId is invalid."}

Headers:
X-Request-ID: REDACTED
x-envoy-upstream-service-time: REDACTED
apim-request-id: REDACTED
Strict-Transport-Security: REDACTED
X-Content-Type-Options: REDACTED
Date: Thu, 08 Oct 2020 09:04:31 GMT
Content-Length: 69
Content-Type: application/json; charset=utf-8

设置控制台日志记录

查看日志的最简单方法是启用控制台日志记录。

若要创建将消息输出到控制台的 Azure SDK 日志侦听器, AzureEventSourceListener.CreateConsoleLogger 请使用 方法。

// Set up a listener to monitor logged events.
using AzureEventSourceListener listener = AzureEventSourceListener.CreateConsoleLogger();

若要详细了解其他日志记录机制,请参阅 诊断示例

后续步骤

此 GitHub 存储库中提供了演示如何使用认知服务指标顾问库的示例。 为每个main功能区域提供示例:

贡献

本项目欢迎贡献和建议。 大多数贡献要求你同意贡献者许可协议 (CLA),并声明你有权(并且确实有权)授予我们使用你的贡献的权利。 有关详细信息,请访问 cla.microsoft.com

提交拉取请求时,CLA 机器人将自动确定你是否需要提供 CLA,并相应地修饰 PR(例如标签、注释)。 直接按机器人提供的说明操作。 只需使用 CLA 对所有存储库执行一次这样的操作。

此项目采用了 Microsoft 开放源代码行为准则。 有关详细信息,请参阅行为准则常见问题解答,或如果有任何其他问题或意见,请与 联系。