快速入门:使用客户端库或 REST API 自定义解决方案
重要
从 2023 年 9 月 20 日开始,将无法创建新的 Azure 指标顾问资源。 指标顾问服务将于 2026 年 10 月 1 日停用。
开始使用指标顾问 REST API 或客户端库。 请按照以下步骤安装程序包并试用基本任务的示例代码。
使用指标顾问执行以下操作:
- 从数据源添加数据馈送
- 检查引入状态
- 配置检测和警报
- 查询异常情况检测结果
- 诊断异常
重要
Azure 建议使用最安全的可用身份验证流。 本文所述的某些身份验证流需要极高度地信任应用程序,并且附带了其他更安全的流中不存在的风险。 请仅在无法使用其他更安全的流(例如托管标识)时才使用此流。
先决条件
提示
- 可以在 GitHub 上找到 .NET 指标顾问示例。
- 指标顾问资源可能需要 10 到 30 分钟才能部署一个服务实例供你使用。 部署成功后,选择“转到资源”。 部署完成后,可以通过 Web 门户和 REST API 这两种方式开始使用指标顾问实例。
- 可以在 Azure 门户的资源“概述”部分中找到 REST API 的 URL。 它将如下所示:
https://<instance-name>.cognitiveservices.azure.cn/
设置
安装客户端库
创建新项目后,右键单击“解决方案资源管理器”中的项目解决方案,然后选择“管理 NuGet 包”,以安装客户端库。 在打开的包管理器中,选择“浏览”,选中“包括预发行版”并搜索 Azure.AI.MetricsAdvisor
。 选择版本 1.0.0
,然后选择“安装”。
在控制台窗口(例如 cmd、PowerShell 或 Bash)中,使用 dotnet new
命令创建名为 metrics-advisor-quickstart
的新控制台应用。 此命令将创建包含单个源文件的简单“Hello World”C# 项目:program.cs。
dotnet new console -n metrics-advisor-quickstart
将目录更改为新创建的应用文件夹。 可使用以下代码生成应用程序:
dotnet build
生成输出不应包含警告或错误。
...
Build succeeded.
0 Warning(s)
0 Error(s)
...
如果你使用的 IDE 而不是 Visual Studio,则可通过以下命令安装适用于 .NET 的指标顾问客户端库:
dotnet add package Azure.AI.MetricsAdvisor --version 1.1.0
环境变量
若要成功对异常检测器服务发出调用,需要使用以下值:
变量名称 | 值 |
---|---|
METRICS_ADVISOR_ENDPOINT |
从 Azure 门户检查资源时,可在“密钥和终结点”部分中找到此值。 终结点示例:https://YOUR_RESOURCE_NAME.cognitiveservices.azure.cn/ |
METRICS_ADVISOR_KEY |
从 Azure 门户检查资源时,可在“密钥和终结点”部分中找到键值。 可以使用 KEY1 或 KEY2 。 |
METRICS_ADVISOR_API_KEY |
从指标顾问门户检查资源时,可以在“设置”>“API 密钥”下找到密钥值。 可以使用 KEY1 或 KEY2 。 |
SQL_CONNECTION_STRING |
本快速入门要求你拥有自己的 SQL 数据库 + 连接字符串。 示例连接字符串类似于以下示例:Data Source=<Server>;Initial Catalog=<db-name>;User ID=<user-name>;Password=<password> 有关构造 SQL 连接字符串的详细信息,请参阅 SQL 文档。 |
SQL_QUERY |
特定于数据集的唯一查询。 |
创建环境变量
为密钥和终结点创建和分配持久环境变量。
重要
如果使用 API 密钥,请将其安全地存储在某个其他位置,例如 Azure Key Vault 中。 请不要直接在代码中包含 API 密钥,并且切勿公开发布该密钥。
有关 Azure AI 服务安全性的详细信息,请参阅对 Azure AI 服务的请求进行身份验证。
setx METRICS_ADVISOR_ENDPOINT "REPLACE_WITH_YOUR_ENDPOINT_HERE"
setx METRICS_ADVISOR_KEY "REPLACE_WITH_YOUR_KEY_VALUE_HERE"
setx METRICS_ADVISOR_API_KEY "REPLACE_WITH_YOUR_KEY_VALUE_HERE"
setx SQL_CONNECTION_STRING "REPLACE_WITH_YOUR_UNIQUE_SQL_CONNECTION_STRING"
setx SQL_QUERY "REPLACE_WITH_YOUR_UNIQUE_SQL_QUERY_BASED_ON_THE_UNDERLYING_STRUCTURE_OF_YOUR_DATA"
创建应用程序
编辑 program.cs 文件并替换为以下内容:
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using System;
using System.Threading.Tasks;
using Azure.AI.MetricsAdvisor.Administration;
using Azure.AI.MetricsAdvisor.Models;
using Azure.AI.MetricsAdvisor.Tests;
using Azure.Core.TestFramework;
using NUnit.Framework;
using static System.Environment;
namespace Azure.AI.MetricsAdvisor.Samples
{
[LiveOnly]
public partial class MetricsAdvisorSamples : MetricsAdvisorTestEnvironment
{
[Test]
public async Task CreateAndDeleteDataFeedAsync()
{
string endpoint = GetEnvironmentVariable("METRICS_ADVISOR_ENDPOINT");
string subscriptionKey = GetEnvironmentVariable("METRICS_ADVISOR_KEY");
string apiKey = GetEnvironmentVariable("METRICS_ADVISOR_API_KEY");
var credential = new MetricsAdvisorKeyCredential(subscriptionKey, apiKey);
var adminClient = new MetricsAdvisorAdministrationClient(new Uri(endpoint), credential);
#region Snippet:CreateDataFeedAsync
#if SNIPPET
string sqlServerConnectionString = GetEnvironmentVariable("SQL_CONNECTION_STRING");
string sqlServerQuery = GetEnvironmentVariable("SQL_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("region"));
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}");
}
#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);
}
[Test]
public async Task GetDataFeedAsync()
{
string endpoint = GetEnvironmentVariable("METRICS_ADVISOR_ENDPOINT");
string subscriptionKey = GetEnvironmentVariable("METRICS_ADVISOR_KEY");
string apiKey = GetEnvironmentVariable("METRICS_ADVISOR_API_KEY");
var credential = new MetricsAdvisorKeyCredential(subscriptionKey, apiKey);
var adminClient = new MetricsAdvisorAdministrationClient(new Uri(endpoint), credential);
string dataFeedId = DataFeedId;
Response<DataFeed> response = await adminClient.GetDataFeedAsync(dataFeedId);
DataFeed dataFeed = response.Value;
Console.WriteLine($"Data feed status: {dataFeed.Status.Value}");
Console.WriteLine($"Data feed created time: {dataFeed.CreatedOn.Value}");
Console.WriteLine($"Data feed administrators:");
foreach (string admin in dataFeed.Administrators)
{
Console.WriteLine($" - {admin}");
}
Console.WriteLine($"Metric IDs:");
foreach (DataFeedMetric metric in dataFeed.Schema.MetricColumns)
{
Console.WriteLine($" - {metric.Name}: {metric.Id}");
}
Console.WriteLine($"Dimensions:");
foreach (DataFeedDimension dimension in dataFeed.Schema.DimensionColumns)
{
Console.WriteLine($" - {dimension.Name}");
}
}
[Test]
public async Task UpdateDataFeedAsync()
{
string endpoint = GetEnvironmentVariable("METRICS_ADVISOR_ENDPOINT");
string subscriptionKey = GetEnvironmentVariable("METRICS_ADVISOR_KEY");
string apiKey = GetEnvironmentVariable("METRICS_ADVISOR_API_KEY");
var credential = new MetricsAdvisorKeyCredential(subscriptionKey, apiKey);
var adminClient = new MetricsAdvisorAdministrationClient(new Uri(endpoint), credential);
string dataFeedId = DataFeedId;
Response<DataFeed> response = await adminClient.GetDataFeedAsync(dataFeedId);
DataFeed dataFeed = response.Value;
string originalDescription = dataFeed.Description;
dataFeed.Description = "This description was generated by a sample.";
// Some properties, such as IngestionStartOffset, can be reset to their default value
// when set to null during an Update operation. Check the API documentation to verify
// when a property supports this feature.
TimeSpan? originalStartOffset = dataFeed.IngestionSettings.IngestionStartOffset;
dataFeed.IngestionSettings.IngestionStartOffset = null;
response = await adminClient.UpdateDataFeedAsync(dataFeed);
DataFeed updatedDataFeed = response.Value;
Console.WriteLine($"Updated description: {updatedDataFeed.Description}");
Console.WriteLine($"Updated ingestion start offset: {updatedDataFeed.IngestionSettings.IngestionStartOffset}");
// Undo the changes to leave the data feed unaltered. Skip this step if you intend to keep
// the changes.
dataFeed.Description = originalDescription;
dataFeed.IngestionSettings.IngestionStartOffset = originalStartOffset;
await adminClient.UpdateDataFeedAsync(dataFeed);
}
[Test]
public async Task GetDataFeedsAsync()
{
string endpoint = GetEnvironmentVariable("METRICS_ADVISOR_ENDPOINT");
string subscriptionKey = GetEnvironmentVariable("METRICS_ADVISOR_KEY");
string apiKey = GetEnvironmentVariable("METRICS_ADVISOR_API_KEY");
var credential = new MetricsAdvisorKeyCredential(subscriptionKey, apiKey);
var adminClient = new MetricsAdvisorAdministrationClient(new Uri(endpoint), credential);
var filter = new DataFeedFilter()
{
Status = DataFeedStatus.Active,
GranularityType = DataFeedGranularityType.Daily
};
var options = new GetDataFeedsOptions()
{
Filter = filter,
MaxPageSize = 5
};
int dataFeedCount = 0;
await foreach (DataFeed dataFeed in adminClient.GetDataFeedsAsync(options))
{
Console.WriteLine($"Data feed ID: {dataFeed.Id}");
Console.WriteLine($"Name: {dataFeed.Name}");
Console.WriteLine($"Description: {dataFeed.Description}");
Console.WriteLine();
// Print at most 5 data feeds.
if (++dataFeedCount >= 5)
{
break;
}
}
}
}
}
运行应用程序
从应用程序目录使用 dotnet run
命令运行应用程序。
dotnet run
参考文档 | 库源代码 | 项目 (Maven) | 示例
重要
Azure 建议使用最安全的可用身份验证流。 本文所述的某些身份验证流需要极高度地信任应用程序,并且附带了其他更安全的流中不存在的风险。 请仅在无法使用其他更安全的流(例如托管标识)时才使用此流。
先决条件
- Azure 订阅 - 创建试用订阅
- 最新版本的 Java 开发工具包 (JDK)
- Gradle 生成工具,或其他依赖项管理器。
- 获得 Azure 订阅后,在 Azure 门户中创建指标顾问资源,以部署指标顾问实例。
- 带有时序数据的 SQL 数据库。
提示
- 可以在 GitHub 上找到 Java 指标顾问示例。
- 指标顾问资源可能需要 10 到 30 分钟才能部署一个服务实例供你使用。 部署成功后,选择“转到资源”。 部署完成后,可以通过 Web 门户和 REST API 这两种方式开始使用指标顾问实例。
- 可以在 Azure 门户的资源“概述”部分中找到 REST API 的 URL。 它将如下所示:
https://<instance-name>.cognitiveservices.azure.cn/
设置
创建新的 Gradle 项目
本快速入门使用 Gradle 依赖项管理器。 可在 Maven 中央存储库中找到有关客户端库的详细信息。
在控制台窗口(例如 cmd、PowerShell 或 Bash)中,为应用创建一个新目录并导航到该目录。
mkdir myapp && cd myapp
从工作目录运行 gradle init
命令。 此命令将创建 Gradle 的基本生成文件,包括 build.gradle.kts,在运行时将使用该文件创建并配置应用程序。
gradle init --type basic
当提示你选择一个 DSL 时,选择 Kotlin。
安装客户端库
找到 build.gradle.kts,并使用喜好的 IDE 或文本编辑器将其打开。 然后将以下生成配置复制到其中。 请确保包含项目依赖项。
dependencies {
compile("com.azure:azure-ai-metricsadvisor:1.1.8")
}
创建 Java 文件
为示例应用创建一个文件夹。 在工作目录中运行以下命令:
mkdir -p src/main/java
导航到新文件夹,并创建名为 MetricsAdvisorQuickstarts.java 的文件。 在喜好的编辑器或 IDE 中打开该文件并添加以下 import
语句:
提示
想要立即查看整个快速入门代码文件? 可以在 GitHub 上找到它,其中包含此快速入门中的代码示例。
环境变量
若要成功对异常检测器服务发出调用,需要使用以下值:
变量名称 | 值 |
---|---|
METRICS_ADVISOR_ENDPOINT |
从 Azure 门户检查资源时,可在“密钥和终结点”部分中找到此值。 终结点示例:https://YOUR_RESOURCE_NAME.cognitiveservices.azure.cn/ |
METRICS_ADVISOR_KEY |
从 Azure 门户检查资源时,可在“密钥和终结点”部分中找到键值。 可以使用 KEY1 或 KEY2 。 |
METRICS_ADVISOR_API_KEY |
从指标顾问门户检查资源时,可以在“设置”>“API 密钥”下找到密钥值。 可以使用 KEY1 或 KEY2 。 |
SQL_CONNECTION_STRING |
本快速入门要求你拥有自己的 SQL 数据库 + 连接字符串。 示例连接字符串类似于以下示例:Data Source=<Server>;Initial Catalog=<db-name>;User ID=<user-name>;Password=<password> 有关构造 SQL 连接字符串的详细信息,请参阅 SQL 文档。 |
SQL_QUERY |
特定于数据集的唯一查询。 |
创建环境变量
为密钥和终结点创建和分配持久环境变量。
重要
如果使用 API 密钥,请将其安全地存储在某个其他位置,例如 Azure Key Vault 中。 请不要直接在代码中包含 API 密钥,并且切勿公开发布该密钥。
有关 Azure AI 服务安全性的详细信息,请参阅对 Azure AI 服务的请求进行身份验证。
setx METRICS_ADVISOR_ENDPOINT "REPLACE_WITH_YOUR_ENDPOINT_HERE"
setx METRICS_ADVISOR_KEY "REPLACE_WITH_YOUR_KEY_VALUE_HERE"
setx METRICS_ADVISOR_API_KEY "REPLACE_WITH_YOUR_KEY_VALUE_HERE"
setx SQL_CONNECTION_STRING "REPLACE_WITH_YOUR_UNIQUE_SQL_CONNECTION_STRING"
setx SQL_QUERY "REPLACE_WITH_YOUR_UNIQUE_SQL_QUERY_BASED_ON_THE_UNDERLYING_STRUCTURE_OF_YOUR_DATA"
创建应用程序
将 .java 文件的内容替换为以下内容:
package com.azure.ai.metricsadvisor.administration;
import com.azure.ai.metricsadvisor.administration.models.AzureAppInsightsDataFeedSource;
import com.azure.ai.metricsadvisor.administration.models.DataFeed;
import com.azure.ai.metricsadvisor.administration.models.DataFeedDimension;
import com.azure.ai.metricsadvisor.administration.models.DataFeedGranularity;
import com.azure.ai.metricsadvisor.administration.models.DataFeedGranularityType;
import com.azure.ai.metricsadvisor.administration.models.DataFeedIngestionSettings;
import com.azure.ai.metricsadvisor.administration.models.DataFeedMetric;
import com.azure.ai.metricsadvisor.administration.models.DataFeedOptions;
import com.azure.ai.metricsadvisor.administration.models.DataFeedSchema;
import com.azure.ai.metricsadvisor.administration.models.DataFeedSourceType;
import com.azure.ai.metricsadvisor.models.MetricsAdvisorKeyCredential;
import java.time.OffsetDateTime;
import java.util.Arrays;
import java.util.Collections;
/**
* Sample demonstrates how to create, get, update, delete and list datafeed.
*/
public class DatafeedSample {
private static String subscription_key = System.getenv("METRICS_ADVISOR_KEY");
private static String api_key = System.getenv("METRICS_ADVISOR_API_KEY");
private static String endpoint = System.getenv("METRICS_ADVISOR_ENDPOINT");
private static String connection_string = System.getenv("SQL_CONNECTION_STRING");
private static String sql_query = System.getenv("SQL_QUERY");
public static void main(String[] args) {
final MetricsAdvisorAdministrationClient advisorAdministrationClient =
new MetricsAdvisorAdministrationClientBuilder()
.endpoint("https://{endpoint}.cognitiveservices.azure.cn/")
.credential(new MetricsAdvisorKeyCredential("subscription_key", "api_key"))
.buildClient();
// Create Data feed
DataFeed dataFeed = new DataFeed()
.setName("dataFeedName")
.setSource(new MySqlDataFeedSource(connection_string, sql_query))
.setGranularity(new DataFeedGranularity().setGranularityType(DataFeedGranularityType.DAILY))
.setSchema(new DataFeedSchema(
Arrays.asList(
new DataFeedMetric("cost"),
new DataFeedMetric("revenue")
)).setDimensions(
Arrays.asList(
new DataFeedDimension("city"),
new DataFeedDimension("category")
))
)
.setIngestionSettings(new DataFeedIngestionSettings(OffsetDateTime.parse("2020-01-01T00:00:00Z")))
.setOptions(new DataFeedOptions()
.setDescription("data feed description")
.setRollupSettings(new DataFeedRollupSettings()
.setRollupType(DataFeedRollupType.AUTO_ROLLUP)));
final DataFeed createdSqlDataFeed = metricsAdvisorAdminClient.createDataFeed(dataFeed);
System.out.printf("Data feed Id : %s%n", createdSqlDataFeed.getId());
System.out.printf("Data feed name : %s%n", createdSqlDataFeed.getName());
System.out.printf("Is the query user is one of data feed administrator : %s%n", createdSqlDataFeed.isAdmin());
System.out.printf("Data feed created time : %s%n", createdSqlDataFeed.getCreatedTime());
System.out.printf("Data feed granularity type : %s%n",
createdSqlDataFeed.getGranularity().getGranularityType());
System.out.printf("Data feed granularity value : %d%n",
createdSqlDataFeed.getGranularity().getCustomGranularityValue());
System.out.println("Data feed related metric Ids:");
dataFeed.getMetricIds().forEach((metricId, metricName)
-> System.out.printf("Metric Id : %s, Metric Name: %s%n", metricId, metricName));
System.out.printf("Data feed source type: %s%n", createdSqlDataFeed.getSourceType());
if (SQL_SERVER_DB == createdSqlDataFeed.getSourceType()) {
System.out.printf("Data feed sql server query: %s%n",
((SqlServerDataFeedSource) createdSqlDataFeed.getSource()).getQuery());
}
// Update the data feed.
System.out.printf("Updating data feed: %s%n", dataFeed.getId());
dataFeed = advisorAdministrationClient.updateDataFeed(dataFeed.setOptions(new DataFeedOptions()
.setAdmins(Collections.singletonList("admin1@admin.com"))
));
System.out.printf("Updated data feed admin list: %s%n",
String.join(",", dataFeed.getOptions().getAdmins()));
// Delete the data feed.
System.out.printf("Deleting data feed: %s%n", dataFeed.getId());
advisorAdministrationClient.deleteDataFeed(dataFeed.getId());
System.out.printf("Deleted data feed%n");
// List data feeds.
System.out.printf("Listing data feeds%n");
advisorAdministrationClient.listDataFeeds().forEach(dataFeedItem -> {
System.out.printf("Data feed Id : %s%n", dataFeedItem.getId());
System.out.printf("Data feed name : %s%n", dataFeedItem.getName());
System.out.printf("Is the query user is one of data feed administrator : %s%n", dataFeedItem.isAdmin());
System.out.printf("Data feed created time : %s%n", dataFeedItem.getCreatedTime());
System.out.printf("Data feed granularity type : %s%n", dataFeedItem.getGranularity().getGranularityType());
System.out.printf("Data feed granularity value : %d%n",
dataFeedItem.getGranularity().getCustomGranularityValue());
System.out.println("Data feed related metric Id's:");
dataFeedItem.getMetricIds().forEach((metricId, metricName)
-> System.out.printf("Metric Id : %s, Metric Name: %s%n", metricId, metricName));
System.out.printf("Data feed source type: %s%n", dataFeedItem.getSourceType());
});
}
}
可使用以下命令生成应用:
gradle build
运行应用程序
使用 run
目标运行应用程序:
gradle run
重要
Azure 建议使用最安全的可用身份验证流。 本文所述的某些身份验证流需要极高度地信任应用程序,并且附带了其他更安全的流中不存在的风险。 请仅在无法使用其他更安全的流(例如托管标识)时才使用此流。
先决条件
提示
- 可以在 GitHub 上找到 JavaScript 指标顾问示例。
- 指标顾问资源可能需要 10 到 30 分钟才能部署一个服务实例供你使用。 部署成功后,选择“转到资源”。 部署完成后,可以通过 Web 门户和 REST API 这两种方式开始使用指标顾问实例。
- 可以在 Azure 门户的资源“概述”部分中找到 REST API 的 URL。 它将如下所示:
https://<instance-name>.cognitiveservices.azure.cn/
设置
创建新的 Node.js 应用程序
在控制台窗口(例如 cmd、PowerShell 或 Bash)中,为应用创建一个新目录并导航到该目录。
mkdir myapp && cd myapp
运行 npm init
命令以使用 package.json
文件创建一个 node 应用程序。
npm init
安装客户端库
安装 @azure/ai-metrics-advisor
npm 包:
npm install @azure/ai-metrics-advisor
应用的 package.json
文件将使用依赖项进行更新。
环境变量
若要成功对异常检测器服务发出调用,需要使用以下值:
变量名称 | 值 |
---|---|
METRICS_ADVISOR_ENDPOINT |
从 Azure 门户检查资源时,可在“密钥和终结点”部分中找到此值。 终结点示例:https://YOUR_RESOURCE_NAME.cognitiveservices.azure.cn/ |
METRICS_ADVISOR_KEY |
从 Azure 门户检查资源时,可在“密钥和终结点”部分中找到键值。 可以使用 KEY1 或 KEY2 。 |
METRICS_ADVISOR_API_KEY |
从指标顾问门户检查资源时,可以在“设置”>“API 密钥”下找到密钥值。 可以使用 KEY1 或 KEY2 。 |
SQL_CONNECTION_STRING |
本快速入门要求你拥有自己的 SQL 数据库 + 连接字符串。 示例连接字符串类似于以下示例:Data Source=<Server>;Initial Catalog=<db-name>;User ID=<user-name>;Password=<password> 有关构造 SQL 连接字符串的详细信息,请参阅 SQL 文档。 |
SQL_QUERY |
特定于数据集的唯一查询。 |
创建环境变量
为密钥和终结点创建和分配持久环境变量。
重要
如果使用 API 密钥,请将其安全地存储在某个其他位置,例如 Azure Key Vault 中。 请不要直接在代码中包含 API 密钥,并且切勿公开发布该密钥。
有关 Azure AI 服务安全性的详细信息,请参阅对 Azure AI 服务的请求进行身份验证。
setx METRICS_ADVISOR_ENDPOINT "REPLACE_WITH_YOUR_ENDPOINT_HERE"
setx METRICS_ADVISOR_KEY "REPLACE_WITH_YOUR_KEY_VALUE_HERE"
setx METRICS_ADVISOR_API_KEY "REPLACE_WITH_YOUR_KEY_VALUE_HERE"
setx SQL_CONNECTION_STRING "REPLACE_WITH_YOUR_UNIQUE_SQL_CONNECTION_STRING"
setx SQL_QUERY "REPLACE_WITH_YOUR_UNIQUE_SQL_QUERY_BASED_ON_THE_UNDERLYING_STRUCTURE_OF_YOUR_DATA"
创建应用程序
创建一个名为 index.js
的文件,并复制以下代码:
/**
* @summary This sample demonstrates how to get started by creating a data feed, checking ingestion status,
* creating detection and alerting configurations, and querying for alerts and anomalies.
*/
// Load the .env file if it exists
const dotenv = require("dotenv");
dotenv.config();
const {
MetricsAdvisorKeyCredential,
MetricsAdvisorAdministrationClient,
MetricsAdvisorClient
} = require("@azure/ai-metrics-advisor");
async function main() {
// You will need to set these environment variables or edit the following values
const endpoint = process.env["METRICS_ADVISOR_ENDPOINT"] || "<service endpoint>";
const subscriptionKey = process.env["METRICS_ADVISOR_KEY"] || "<subscription key>";
const apiKey = process.env["METRICS_ADVISOR_API_KEY"] || "<api key>";
const sqlServerConnectionString =
process.env["SQL_SERVER_CONNECTION_STRING"] ||
"<connection string to SQL Server>";
const sqlServerQuery =
process.env["SQL_SERVER_QUERY"] || "<SQL Server query to retrive data>";
const credential = new MetricsAdvisorKeyCredential(subscriptionKey, apiKey);
const client = new MetricsAdvisorClient(endpoint, credential);
const adminClient = new MetricsAdvisorAdministrationClient(endpoint, credential);
const created = await createDataFeed(adminClient, sqlServerConnectionString, sqlServerQuery);
console.log(`Data feed created: ${created.id}`);
console.log(" metrics: ");
console.log(created.schema.metrics);
console.log("Waiting for a minute before checking ingestion status...");
await delay(60 * 1000);
try {
await checkIngestionStatus(
adminClient,
created.id,
new Date(Date.UTC(2020, 8, 1)),
new Date(Date.UTC(2020, 8, 12))
);
const metricId = created.schema.metrics[0].id;
const detectionConfig = await configureAnomalyDetectionConfiguration(adminClient, metricId);
console.log(`Detection configuration created: ${detectionConfig.id}`);
const hook = await createWebhookHook(adminClient);
console.log(`Webhook hook created: ${hook.id}`);
const alertConfig = await configureAlertConfiguration(adminClient, detectionConfig.id, [
hook.id
]);
console.log(`Alert configuration created: ${alertConfig.id}`);
// you can use alert configuration created in above step to query the alert.
const alerts = await queryAlerts(
client,
alertConfig.id,
new Date(Date.UTC(2020, 8, 1)),
new Date(Date.UTC(2020, 8, 12))
);
if (alerts.length > 1) {
// query anomalies using an alert id.
await queryAnomaliesByAlert(client, alerts[0]);
} else {
console.log("No alerts during the time period");
}
} finally {
console.log(`Deleting the data feed '${created.id}`);
await adminClient.deleteDataFeed(created.id);
}
}
async function createDataFeed(adminClient, sqlServerConnectionString, sqlServerQuery) {
console.log("Creating Datafeed...");
const dataFeed = {
name: "test_datafeed_" + new Date().getTime().toString(),
source: {
dataSourceType: "SqlServer",
connectionString: sqlServerConnectionString,
query: sqlServerQuery,
authenticationType: "Basic"
},
granularity: {
granularityType: "Daily"
},
schema: {
metrics: [
{
name: "revenue",
displayName: "revenue",
description: "Metric1 description"
},
{
name: "cost",
displayName: "cost",
description: "Metric2 description"
}
],
dimensions: [
{ name: "city", displayName: "city display" },
{ name: "category", displayName: "category display" }
],
timestampColumn: undefined
},
ingestionSettings: {
ingestionStartTime: new Date(Date.UTC(2020, 5, 1)),
ingestionStartOffsetInSeconds: 0,
dataSourceRequestConcurrency: -1,
ingestionRetryDelayInSeconds: -1,
stopRetryAfterInSeconds: -1
},
rollupSettings: {
rollupType: "AutoRollup",
rollupMethod: "Sum",
rollupIdentificationValue: "__SUM__"
},
missingDataPointFillSettings: {
fillType: "SmartFilling"
},
accessMode: "Private",
admins: ["xyz@microsoft.com"]
};
const result = await adminClient.createDataFeed(dataFeed);
return result;
}
async function checkIngestionStatus(adminClient, datafeedId, startTime, endTime) {
// This shows how to use for-await-of syntax to list status
console.log("Checking ingestion status...");
const listIterator = adminClient.listDataFeedIngestionStatus(datafeedId, startTime, endTime);
for await (const status of listIterator) {
console.log(` [${status.timestamp}] ${status.status} - ${status.message}`);
}
}
async function configureAnomalyDetectionConfiguration(adminClient, metricId) {
console.log(`Creating an anomaly detection configuration on metric '${metricId}'...`);
const anomalyConfig = {
name: "test_detection_configuration" + new Date().getTime().toString(),
metricId,
wholeSeriesDetectionCondition: {
smartDetectionCondition: {
sensitivity: 100,
anomalyDetectorDirection: "Both",
suppressCondition: {
minNumber: 1,
minRatio: 1
}
}
},
description: "Detection configuration description"
};
return await adminClient.createDetectionConfig(anomalyConfig);
}
async function createWebhookHook(adminClient) {
console.log("Creating a webhook hook");
const hook = {
hookType: "Webhook",
name: "web hook " + new Date().getTime().toString(),
description: "description",
hookParameter: {
endpoint: "https://httpbin.org/post",
username: "user",
password: "pass"
// certificateKey: "k",
// certificatePassword: "kp"
}
};
return await adminClient.createHook(hook);
}
async function configureAlertConfiguration(adminClient, detectionConfigId, hookIds) {
console.log("Creating a new alerting configuration...");
const anomalyAlert = {
name: "test_alert_config_" + new Date().getTime().toString(),
crossMetricsOperator: "AND",
metricAlertConfigurations: [
{
detectionConfigurationId: detectionConfigId,
alertScope: {
scopeType: "All"
},
alertConditions: {
severityCondition: {
minAlertSeverity: "Medium",
maxAlertSeverity: "High"
}
},
snoozeCondition: {
autoSnooze: 0,
snoozeScope: "Metric",
onlyForSuccessive: true
}
}
],
hookIds,
description: "Alerting config description"
};
return await adminClient.createAlertConfig(anomalyAlert);
}
async function queryAlerts(client, alertConfigId, startTime, endTime) {
console.log(`Listing alerts for alert configuration '${alertConfigId}'`);
// This shows how to use `for-await-of` syntax to list alerts
console.log(" using for-await-of syntax");
let alerts = [];
const listIterator = client.listAlerts(alertConfigId, startTime, endTime, "AnomalyTime");
for await (const alert of listIterator) {
alerts.push(alert);
console.log(" Alert");
console.log(` id: ${alert.id}`);
console.log(` timestamp: ${alert.timestamp}`);
console.log(` created on: ${alert.createdOn}`);
}
// alternatively we could list results by pages
console.log(` by pages`);
const iterator = client
.listAlerts(alertConfigId, startTime, endTime, "AnomalyTime")
.byPage({ maxPageSize: 2 });
let result = await iterator.next();
while (!result.done) {
console.log(" -- Page -- ");
for (const item of result.value) {
console.log(` id: ${item.id}`);
console.log(` timestamp: ${item.timestamp}`);
console.log(` created on: ${item.createdOn}`);
}
result = await iterator.next();
}
return alerts;
}
async function queryAnomaliesByAlert(client, alert) {
console.log(
`Listing anomalies for alert configuration '${alert.alertConfigId}' and alert '${alert.id}'`
);
const listIterator = client.listAnomaliesForAlert(alert);
for await (const anomaly of listIterator) {
console.log(
` Anomaly ${anomaly.severity} ${anomaly.status} ${anomaly.seriesKey.dimension} ${anomaly.timestamp}`
);
}
}
async function delay(milliseconds) {
return new Promise((resolve) => setTimeout(resolve, milliseconds));
}
main()
.then((_) => {
console.log("Succeeded");
})
.catch((err) => {
console.log("Error occurred:");
console.log(err);
});
运行应用程序
在快速入门文件中使用 node
命令运行应用程序。
node index.js
重要
Azure 建议使用最安全的可用身份验证流。 本文所述的某些身份验证流需要极高度地信任应用程序,并且附带了其他更安全的流中不存在的风险。 请仅在无法使用其他更安全的流(例如托管标识)时才使用此流。
先决条件
- Azure 订阅 - 创建试用订阅
- Python 3.x
- 获得 Azure 订阅后,在 Azure 门户中创建指标顾问资源,以部署指标顾问实例。
- 带有时序数据的 SQL 数据库。
提示
- 可以在 GitHub 上找到 Python 指标顾问示例。
- 指标顾问资源可能需要 10 到 30 分钟才能部署一个服务实例供你使用。 部署成功后,选择“转到资源”。 部署完成后,可以通过 Web 门户和 REST API 这两种方式开始使用指标顾问实例。
- 可以在 Azure 门户的资源“概述”部分中找到 REST API 的 URL。 它将如下所示:
https://<instance-name>.cognitiveservices.azure.cn/
设置
安装客户端库
安装客户端库。 可使用以下方式安装客户端库:
pip install azure-ai-metricsadvisor --pre
环境变量
若要成功对异常检测器服务发出调用,需要使用以下值:
变量名称 | 值 |
---|---|
METRICS_ADVISOR_ENDPOINT |
从 Azure 门户检查资源时,可在“密钥和终结点”部分中找到此值。 终结点示例:https://YOUR_RESOURCE_NAME.cognitiveservices.azure.cn/ |
METRICS_ADVISOR_KEY |
从 Azure 门户检查资源时,可在“密钥和终结点”部分中找到键值。 可以使用 KEY1 或 KEY2 。 |
METRICS_ADVISOR_API_KEY |
从指标顾问门户检查资源时,可以在“设置”>“API 密钥”下找到密钥值。 可以使用 KEY1 或 KEY2 。 |
SQL_CONNECTION_STRING |
本快速入门要求你拥有自己的 SQL 数据库 + 连接字符串。 示例连接字符串类似于以下示例:Data Source=<Server>;Initial Catalog=<db-name>;User ID=<user-name>;Password=<password> 有关构造 SQL 连接字符串的详细信息,请参阅 SQL 文档。 |
SQL_QUERY |
特定于数据集的唯一查询。 |
创建环境变量
为密钥和终结点创建和分配持久环境变量。
重要
如果使用 API 密钥,请将其安全地存储在某个其他位置,例如 Azure Key Vault 中。 请不要直接在代码中包含 API 密钥,并且切勿公开发布该密钥。
有关 Azure AI 服务安全性的详细信息,请参阅对 Azure AI 服务的请求进行身份验证。
setx METRICS_ADVISOR_ENDPOINT "REPLACE_WITH_YOUR_ENDPOINT_HERE"
setx METRICS_ADVISOR_KEY "REPLACE_WITH_YOUR_KEY_VALUE_HERE"
setx METRICS_ADVISOR_API_KEY "REPLACE_WITH_YOUR_KEY_VALUE_HERE"
setx SQL_CONNECTION_STRING "REPLACE_WITH_YOUR_UNIQUE_SQL_CONNECTION_STRING"
setx SQL_QUERY "REPLACE_WITH_YOUR_UNIQUE_SQL_QUERY_BASED_ON_THE_UNDERLYING_STRUCTURE_OF_YOUR_DATA"
创建应用程序
基于以下代码创建 Python 应用程序:
"""
FILE: sample_data_feeds.py
DESCRIPTION:
This sample demonstrates how to create, get, list, update, and delete datafeeds under your Metrics Advisor account.
USAGE:
python sample_data_feeds.py
Set the environment variables with your own values before running the sample:
1) METRICS_ADVISOR_ENDPOINT - the endpoint of your Azure AI Metrics Advisor service
2) METRICS_ADVISOR_KEY - Metrics Advisor service subscription key
3) METRICS_ADVISOR_API_KEY - Metrics Advisor service API key
4) SQL_CONNECTION_STRING - Used in this sample for demonstration, but you should
add your own credentials specific to the data source type you're using
5) SQL_QUERY - Used in this sample for demonstration, but you should
add your own query specific to the structure of the data in your datasource.
"""
import os
import datetime
def sample_create_data_feed():
from azure.ai.metricsadvisor import MetricsAdvisorKeyCredential, MetricsAdvisorAdministrationClient
from azure.ai.metricsadvisor.models import (
SqlServerDataFeedSource,
DataFeedSchema,
DataFeedMetric,
DataFeedDimension,
DataFeedRollupSettings,
DataFeedMissingDataPointFillSettings,
)
service_endpoint = os.getenv("METRICS_ADVISOR_ENDPOINT")
subscription_key = os.getenv("METRICS_ADVISOR_KEY")
api_key = os.getenv("METRICS_ADVISOR_API_KEY")
sql_server_connection_string = os.getenv("SQL_CONNECTION_STRING")
query = os.getenv("SQL_QUERY")
client = MetricsAdvisorAdministrationClient(service_endpoint,
MetricsAdvisorKeyCredential(subscription_key, api_key))
data_feed = client.create_data_feed(
name="My data feed",
source=SqlServerDataFeedSource(
connection_string=sql_server_connection_string,
query=query,
),
granularity="Daily",
schema=DataFeedSchema(
metrics=[
DataFeedMetric(name="cost", display_name="Cost"),
DataFeedMetric(name="revenue", display_name="Revenue")
],
dimensions=[
DataFeedDimension(name="category", display_name="Category"),
DataFeedDimension(name="region", display_name="region")
],
timestamp_column="Timestamp"
),
ingestion_settings=datetime.datetime(2019, 10, 1),
data_feed_description="cost/revenue data feed",
rollup_settings=DataFeedRollupSettings(
rollup_type="AutoRollup",
rollup_method="Sum",
rollup_identification_value="__CUSTOM_SUM__"
),
missing_data_point_fill_settings=DataFeedMissingDataPointFillSettings(
fill_type="SmartFilling"
),
access_mode="Private"
)
return data_feed
def sample_get_data_feed(data_feed_id):
from azure.ai.metricsadvisor import MetricsAdvisorKeyCredential, MetricsAdvisorAdministrationClient
service_endpoint = os.getenv("METRICS_ADVISOR_ENDPOINT")
subscription_key = os.getenv("METRICS_ADVISOR_KEY")
api_key = os.getenv("METRICS_ADVISOR_API_KEY")
client = MetricsAdvisorAdministrationClient(service_endpoint,
MetricsAdvisorKeyCredential(subscription_key, api_key))
data_feed = client.get_data_feed(data_feed_id)
print("ID: {}".format(data_feed.id))
print("Data feed name: {}".format(data_feed.name))
print("Created time: {}".format(data_feed.created_time))
print("Status: {}".format(data_feed.status))
print("Source type: {}".format(data_feed.source.data_source_type))
print("Granularity type: {}".format(data_feed.granularity.granularity_type))
print("Data feed metrics: {}".format([metric.name for metric in data_feed.schema.metrics]))
print("Data feed dimensions: {}".format([dimension.name for dimension in data_feed.schema.dimensions]))
print("Data feed timestamp column: {}".format(data_feed.schema.timestamp_column))
print("Ingestion data starting on: {}".format(data_feed.ingestion_settings.ingestion_begin_time))
print("Data feed description: {}".format(data_feed.data_feed_description))
print("Data feed rollup type: {}".format(data_feed.rollup_settings.rollup_type))
print("Data feed rollup method: {}".format(data_feed.rollup_settings.rollup_method))
print("Data feed fill setting: {}".format(data_feed.missing_data_point_fill_settings.fill_type))
print("Data feed access mode: {}".format(data_feed.access_mode))
def sample_list_data_feeds():
from azure.ai.metricsadvisor import MetricsAdvisorKeyCredential, MetricsAdvisorAdministrationClient
service_endpoint = os.getenv("METRICS_ADVISOR_ENDPOINT")
subscription_key = os.getenv("METRICS_ADVISOR_SUBSCRIPTION_KEY")
api_key = os.getenv("METRICS_ADVISOR_API_KEY")
client = MetricsAdvisorAdministrationClient(service_endpoint,
MetricsAdvisorKeyCredential(subscription_key, api_key))
data_feeds = client.list_data_feeds()
for feed in data_feeds:
print("Data feed name: {}".format(feed.name))
print("ID: {}".format(feed.id))
print("Created time: {}".format(feed.created_time))
print("Status: {}".format(feed.status))
print("Source type: {}".format(feed.source.data_source_type))
print("Granularity type: {}".format(feed.granularity.granularity_type))
print("\nFeed metrics:")
for metric in feed.schema.metrics:
print(metric.name)
print("\nFeed dimensions:")
for dimension in feed.schema.dimensions:
print(dimension.name)
def sample_update_data_feed(data_feed):
from azure.ai.metricsadvisor import MetricsAdvisorKeyCredential, MetricsAdvisorAdministrationClient
service_endpoint = os.getenv("METRICS_ADVISOR_ENDPOINT")
subscription_key = os.getenv("METRICS_ADVISOR_KEY")
api_key = os.getenv("METRICS_ADVISOR_API_KEY")
client = MetricsAdvisorAdministrationClient(service_endpoint,
MetricsAdvisorKeyCredential(subscription_key, api_key))
# update data feed on the data feed itself or by using available keyword arguments
data_feed.name = "updated name"
data_feed.data_feed_description = "updated description for data feed"
updated = client.update_data_feed(
data_feed,
access_mode="Public",
fill_type="CustomValue",
custom_fill_value=1
)
print("Updated name: {}".format(updated.name))
print("Updated description: {}".format(updated.data_feed_description))
print("Updated access mode: {}".format(updated.access_mode))
print("Updated fill setting, value: {}, {}".format(
updated.missing_data_point_fill_settings.fill_type,
updated.missing_data_point_fill_settings.custom_fill_value,
))
def sample_delete_data_feed(data_feed_id):
from azure.core.exceptions import ResourceNotFoundError
from azure.ai.metricsadvisor import MetricsAdvisorKeyCredential, MetricsAdvisorAdministrationClient
service_endpoint = os.getenv("METRICS_ADVISOR_ENDPOINT")
subscription_key = os.getenv("METRICS_ADVISOR_KEY")
api_key = os.getenv("METRICS_ADVISOR_API_KEY")
client = MetricsAdvisorAdministrationClient(service_endpoint,
MetricsAdvisorKeyCredential(subscription_key, api_key))
client.delete_data_feed(data_feed_id)
try:
client.get_data_feed(data_feed_id)
except ResourceNotFoundError:
print("Data feed successfully deleted.")
if __name__ == '__main__':
print("---Creating data feed...")
data_feed = sample_create_data_feed()
print("Data feed successfully created...")
print("\n---Get a data feed...")
sample_get_data_feed(data_feed.id)
print("\n---List data feeds...")
sample_list_data_feeds()
print("\n---Update a data feed...")
sample_update_data_feed(data_feed)
print("\n---Delete a data feed...")
sample_delete_data_feed(data_feed.id)
运行应用程序
在快速入门文件中使用 python
命令运行应用程序。
python quickstart-file.py
先决条件
- Azure 订阅 - 创建试用订阅
- 获得 Azure 订阅后,在 Azure 门户中创建“指标顾问”资源 ,以部署“指标顾问”实例。
- Python 3.x
- 带有时序数据的 SQL 数据库。
重要
Azure 建议使用最安全的可用身份验证流。 本文所述的某些身份验证流需要极高度地信任应用程序,并且附带了其他更安全的流中不存在的风险。 请仅在无法使用其他更安全的流(例如托管标识)时才使用此流。
设置
本快速入门的示例代码将演示如何使用 Python 调用 REST API。 有关特定的 REST API 调用,请参阅 GitHub 示例
提示
- 指标顾问资源可能需要 10 到 30 分钟才能部署一个服务实例供你使用。 部署成功后,选择“转到资源”。 部署完成后,可以通过 Web 门户和 REST API 这两种方式开始使用指标顾问实例。
- 可以在 Azure 门户的资源“概述”部分中找到 REST API 的 URL。 它将如下所示:
https://<instance-name>.cognitiveservices.azure.cn/
环境变量
若要成功对异常检测器服务发出调用,需要使用以下值:
变量名称 | 值 |
---|---|
METRICS_ADVISOR_ENDPOINT |
从 Azure 门户检查资源时,可在“密钥和终结点”部分中找到此值。 终结点示例:https://YOUR_RESOURCE_NAME.cognitiveservices.azure.cn/ |
METRICS_ADVISOR_KEY |
从 Azure 门户检查资源时,可在“密钥和终结点”部分中找到键值。 可以使用 KEY1 或 KEY2 。 |
METRICS_ADVISOR_API_KEY |
从指标顾问门户检查资源时,可以在“设置”>“API 密钥”下找到密钥值。 可以使用 KEY1 或 KEY2 。 |
SQL_CONNECTION_STRING |
本快速入门要求你拥有自己的 SQL 数据库 + 连接字符串。 示例连接字符串类似于以下示例:Data Source=<Server>;Initial Catalog=<db-name>;User ID=<user-name>;Password=<password> 有关构造 SQL 连接字符串的详细信息,请参阅 SQL 文档。 |
SQL_QUERY |
特定于数据集的唯一查询。 |
创建环境变量
为密钥和终结点创建和分配持久环境变量。
重要
如果使用 API 密钥,请将其安全地存储在某个其他位置,例如 Azure Key Vault 中。 请不要直接在代码中包含 API 密钥,并且切勿公开发布该密钥。
有关 Azure AI 服务安全性的详细信息,请参阅对 Azure AI 服务的请求进行身份验证。
setx METRICS_ADVISOR_ENDPOINT "REPLACE_WITH_YOUR_ENDPOINT_HERE"
setx METRICS_ADVISOR_KEY "REPLACE_WITH_YOUR_KEY_VALUE_HERE"
setx METRICS_ADVISOR_API_KEY "REPLACE_WITH_YOUR_KEY_VALUE_HERE"
setx SQL_CONNECTION_STRING "REPLACE_WITH_YOUR_UNIQUE_SQL_CONNECTION_STRING"
setx SQL_QUERY "REPLACE_WITH_YOUR_UNIQUE_SQL_QUERY_BASED_ON_THE_UNDERLYING_STRUCTURE_OF_YOUR_DATA"
创建应用程序
import requests
import json
import time
def add_data_feed(endpoint, subscription_key, api_key):
url = endpoint + '/dataFeeds'
data_feed_body = {
"dataSourceType": "SqlServer",
"dataFeedName": "test_data_feed_00000001",
"dataFeedDescription": "",
"dataSourceParameter": {
"connectionString": os.environ['SQL_CONNECTION_STRING'],
"query": os.environ['SQL_QUERY']
},
"granularityName": "Daily",
"granularityAmount": 0,
"metrics": [
{
"metricName": "revenue",
"metricDisplayName": "revenue",
"metricDescription": ""
},
{
"metricName": "cost",
"metricDisplayName": "cost",
"metricDescription": ""
}
],
"dimension": [
{
"dimensionName": "city",
"dimensionDisplayName": "city"
},
{
"dimensionName": "category",
"dimensionDisplayName": "category"
}
],
"timestampColumn": "timestamp",
"dataStartFrom": "2020-06-01T00:00:00.000Z",
"startOffsetInSeconds": 0,
"maxConcurrency": -1,
"minRetryIntervalInSeconds": -1,
"stopRetryAfterInSeconds": -1,
"allUpIdentification": "__SUM__",
"needRollup": "AlreadyRollup",
"fillMissingPointType": "SmartFilling",
"fillMissingPointValue": 0,
"viewMode": "Private",
"admins": [
"admin@contoso.com"
],
"viewers": [
],
"actionLinkTemplate": ""
}
res = requests.post(url, data=json.dumps(data_feed_body),
headers={'Ocp-Apim-Subscription-Key': subscription_key,
'x-api-key': api_key})
if res.status_code != 201:
raise RuntimeError("add_data_feed failed " + res.text)
else:
print("add_data_feed success " + res.text)
return res.headers['Location']
def check_ingestion_latest_status(endpoint, subscription_key, api_key, datafeed_id):
url = endpoint + '/dataFeeds/{}/ingestionProgress'.format(datafeed_id)
res = requests.get(url, headers={'Ocp-Apim-Subscription-Key': subscription_key,
'x-api-key': api_key})
if res.status_code != 200:
raise RuntimeError("check_ingestion_latest_status failed " + res.text)
else:
print("check_ingestion_latest_status success " + res.text)
def check_ingestion_detail_status(endpoint, subscription_key, api_key, datafeed_id, start_time, end_time):
url = endpoint + '/dataFeeds/{}/ingestionStatus/query'.format(datafeed_id)
ingestion_detail_status_body = {
"startTime": start_time,
"endTime": end_time
}
res = requests.post(url, data=json.dumps(ingestion_detail_status_body),
headers={'Ocp-Apim-Subscription-Key': subscription_key,
'x-api-key': api_key})
if res.status_code != 200:
raise RuntimeError("check_ingestion_detail_status failed " + res.text)
else:
print("check_ingestion_detail_status success " + res.text)
def create_detection_config(endpoint, subscription_key, api_key, metric_id):
url = endpoint + '/enrichment/anomalyDetection/configurations'
detection_config_body = {
"name": "test_detection_config0000000001",
"description": "string",
"metricId": metric_id,
"wholeMetricConfiguration": {
"smartDetectionCondition": {
"sensitivity": 100,
"anomalyDetectorDirection": "Both",
"suppressCondition": {
"minNumber": 1,
"minRatio": 1
}
}
},
"dimensionGroupOverrideConfigurations": [
],
"seriesOverrideConfigurations": [
]
}
res = requests.post(url, data=json.dumps(detection_config_body),
headers={'Ocp-Apim-Subscription-Key': subscription_key,
'x-api-key': api_key})
if res.status_code != 201:
raise RuntimeError("create_detection_config failed " + res.text)
else:
print("create_detection_config success " + res.text)
return res.headers['Location']
def create_web_hook(endpoint, subscription_key, api_key):
url = endpoint + '/hooks'
web_hook_body = {
"hookType": "Webhook",
"hookName": "test_web_hook000001",
"description": "",
"externalLink": "",
"hookParameter": {
"endpoint": "https://www.contoso.com",
"username": "",
"password": ""
}
}
res = requests.post(url, data=json.dumps(web_hook_body),
headers={'Ocp-Apim-Subscription-Key': subscription_key,
'x-api-key': api_key})
if res.status_code != 201:
raise RuntimeError("create_web_hook failed " + res.text)
else:
print("create_web_hook success " + res.text)
return res.headers['Location']
def create_alert_config(endpoint, subscription_key, api_key, anomaly_detection_configuration_id, hook_id):
url = endpoint + '/alert/anomaly/configurations'
web_hook_body = {
"name": "test_alert_config00000001",
"description": "",
"crossMetricsOperator": "AND",
"hookIds": [
hook_id
],
"metricAlertingConfigurations": [
{
"anomalyDetectionConfigurationId": anomaly_detection_configuration_id,
"anomalyScopeType": "All",
"severityFilter": {
"minAlertSeverity": "Low",
"maxAlertSeverity": "High"
},
"snoozeFilter": {
"autoSnooze": 0,
"snoozeScope": "Metric",
"onlyForSuccessive": True
},
}
]
}
res = requests.post(url, data=json.dumps(web_hook_body),
headers={'Ocp-Apim-Subscription-Key': subscription_key,
'x-api-key': api_key})
if res.status_code != 201:
raise RuntimeError("create_alert_config failed " + res.text)
else:
print("create_alert_config success " + res.text)
return res.headers['Location']
def query_alert_by_alert_config(endpoint, subscription_key, api_key, alert_config_id, start_time, end_time):
url = endpoint + '/alert/anomaly/configurations/{}/alerts/query'.format(alert_config_id)
alerts_body = {
"startTime": start_time,
"endTime": end_time,
"timeMode": "AnomalyTime"
}
res = requests.post(url, data=json.dumps(alerts_body),
headers={'Ocp-Apim-Subscription-Key': subscription_key,
'x-api-key': api_key})
if res.status_code != 200:
raise RuntimeError("query_alert_by_alert_config failed " + res.text)
else:
print("query_alert_by_alert_config success " + res.text)
return [item['alertId'] for item in json.loads(res.content)['value']]
def query_anomaly_by_alert(endpoint, subscription_key, api_key, alert_config_id, alert_id):
url = endpoint + '/alert/anomaly/configurations/{}/alerts/{}/anomalies'.format(alert_config_id, alert_id)
res = requests.get(url,
headers={'Ocp-Apim-Subscription-Key': subscription_key,
'x-api-key': api_key})
if res.status_code != 200:
raise RuntimeError("query_anomaly_by_alert failed " + res.text)
else:
print("query_anomaly_by_alert success " + res.text)
return json.loads(res.content)
def query_incident_by_alert(endpoint, subscription_key, api_key, alert_config_id, alert_id):
url = endpoint + '/alert/anomaly/configurations/{}/alerts/{}/incidents'.format(alert_config_id, alert_id)
res = requests.get(url,
headers={'Ocp-Apim-Subscription-Key': subscription_key,
'x-api-key': api_key})
if res.status_code != 200:
raise RuntimeError("query_incident_by_alert failed " + res.text)
else:
print("query_incident_by_alert success " + res.text)
return json.loads(res.content)
def query_root_cause_by_incident(endpoint, subscription_key, api_key, detection_config_id, incident_id):
url = endpoint + '/enrichment/anomalyDetection/configurations/{}/incidents/{}/rootCause'.format(detection_config_id, incident_id)
res = requests.get(url,
headers={'Ocp-Apim-Subscription-Key': subscription_key,
'x-api-key': api_key})
if res.status_code != 200:
raise RuntimeError("query_root_cause_by_incident failed " + res.text)
else:
print("query_root_cause_by_incident success " + res.text)
return json.loads(res.content)
def query_anomaly_by_detection_config(endpoint, subscription_key, api_key, detection_config_id, start_time, end_time):
url = endpoint + '/enrichment/anomalyDetection/configurations/{}/anomalies/query'.format(detection_config_id)
body = {
"startTime": start_time,
"endTime": end_time,
"filter": {
"dimensionFilter": [
],
"severityFilter": {
"min": "Low",
"max": "High"
}
}
}
res = requests.post(url, data=json.dumps(body),
headers={'Ocp-Apim-Subscription-Key': subscription_key,
'x-api-key': api_key})
if res.status_code != 200:
raise RuntimeError("query_anomaly_by_detection_config failed " + res.text)
else:
print("query_anomaly_by_detection_config success " + res.text)
return json.loads(res.content)
def query_incident_by_detection_config(endpoint, subscription_key, api_key, detection_config_id, start_time, end_time):
url = endpoint + '/enrichment/anomalyDetection/configurations/{}/incidents/query'.format(detection_config_id)
body = {
"startTime": start_time,
"endTime": end_time,
"filter": {
"dimensionFilter": [
],
}
}
res = requests.post(url, data=json.dumps(body),
headers={'Ocp-Apim-Subscription-Key': subscription_key,
'x-api-key': api_key})
if res.status_code != 200:
raise RuntimeError("query_incident_by_detection_config failed " + res.text)
else:
print("query_incident_by_detection_config success " + res.text)
return json.loads(res.content)
if __name__ == '__main__':
# Example endpoint: https://[placeholder].cognitiveservices.azure.cn/metricsadvisor/v1.0
endpoint = os.environ['METRICS_ADVISOR_ENDPOINT'] + "metricsadvisor/v1.0"
subscription_key = os.environ['METRICS_ADVISOR_KEY']
api_key = os.environ['METRICS_ADVISOR_API_KEY']
'''
First part
1.onboard datafeed
2.check datafeed latest status
3.check datafeed status details
4.create detection config
5.create webhook
6.create alert config
'''
datafeed_resource_url = add_data_feed(endpoint, subscription_key, api_key)
print(datafeed_resource_url)
# datafeed_id and metrics_id can get from datafeed_resource_url
datafeed_info = json.loads(requests.get(url=datafeed_resource_url,
headers={'Ocp-Apim-Subscription-Key': subscription_key,
'x-api-key': api_key}).content)
print(datafeed_info)
datafeed_id = datafeed_info['dataFeedId']
metrics_id = []
for metrics in datafeed_info['metrics']:
metrics_id.append(metrics['metricId'])
time.sleep(60)
check_ingestion_latest_status(endpoint, subscription_key, api_key, datafeed_id)
check_ingestion_detail_status(endpoint, subscription_key, api_key, datafeed_id,
"2020-06-01T00:00:00Z", "2020-07-01T00:00:00Z")
detection_config_resource_url = create_detection_config(endpoint, subscription_key, api_key, metrics_id[0])
print(detection_config_resource_url)
# anomaly_detection_configuration_id can get from detection_config_resource_url
detection_config = json.loads(requests.get(url=detection_config_resource_url,
headers={'Ocp-Apim-Subscription-Key': subscription_key,
'x-api-key': api_key}).content)
print(detection_config)
anomaly_detection_configuration_id = detection_config['anomalyDetectionConfigurationId']
webhook_resource_url = create_web_hook(endpoint, subscription_key, api_key)
print(webhook_resource_url)
# hook_id can get from webhook_resource_url
webhook = json.loads(requests.get(url=webhook_resource_url,
headers={'Ocp-Apim-Subscription-Key': subscription_key,
'x-api-key': api_key}).content)
print(webhook)
hook_id = webhook['hookId']
alert_config_resource_url = create_alert_config(endpoint, subscription_key, api_key,
anomaly_detection_configuration_id, hook_id)
# anomaly_alerting_configuration_id can get from alert_config_resource_url
alert_config = json.loads(requests.get(url=alert_config_resource_url,
headers={'Ocp-Apim-Subscription-Key': subscription_key,
'x-api-key': api_key}).content)
print(alert_config)
anomaly_alerting_configuration_id = alert_config['anomalyAlertingConfigurationId']
清理资源
如果想要清理并移除 Azure AI 服务订阅,可以删除资源或资源组。 删除资源组同时也会删除与之相关联的任何其他资源。