快速入門:使用用戶端程式庫 REST API 自訂解決方案
重要
從 2023 年 9 月 20 日起,您將無法建立新的計量建議程式資源。 計量建議程式服務將於 2026 年 10 月 1 日淘汰。
開始使用 Metrics Advisor REST API 或用戶端程式庫。 請遵循下列步驟來安裝套件,並試用基本工作的程式碼範例。
使用 Metrics Advisor 可以:
- 從資料來源新增資料摘要
- 檢查內嵌狀態
- 設定威脅偵測及警示
- 查詢異常偵測結果
- 診斷異常
參考文件 | 程式庫來源程式碼 | 套件 (NuGet) | 範例
重要
Microsoft 建議您使用最安全的可用驗證流程。 本文中所述的一些驗證流程在應用程式中需要高度信任,且具有其他更安全流程中不存在的風險。 請僅在其他較安全的流程 (例如受控身分識別) 皆不具可行性的情況下,才使用這個流程。
必要條件
- Azure 訂用帳戶 - 建立免費帳戶
- 最新版 .NET Core。
- 擁有 Azure 訂用帳戶之後,在 Azure 入口網站中建立計量建議程式資源,以部署計量建議程式的執行個體。
- 包含時間序列資料的 SQL 資料庫。
提示
- 您可以在 GitHub 上找到 .NET Metrics Advisor 範例。
- 可能需要 10 到 30 分鐘,Metrics Advisor 資源才會將服務執行個體部署完成供您使用。 一旦成功部署,請選取 [移至資源]。 部署之後,您即可開始透過入口網站和 REST API 使用 Metrics Advisor 執行個體。
- 您可以經由 Azure 入口網站,在資源的 [概觀] 區段中找到 REST API 的 URL。 其看起來將會像下面這樣:
https://<instance-name>.cognitiveservices.azure.com/
設定
安裝用戶端程式庫
建立新專案後,以滑鼠右鍵按一下 [方案總管] 中的專案解決方案,然後選取 [管理 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)
...
如果您使用 Visual Studio 以外的 IDE,您可以使用下列命令來安裝適用於 .NET 的 Metrics Advisor 用戶端程式庫:
dotnet add package Azure.AI.MetricsAdvisor --version 1.1.0
環境變數
若要成功對異常偵測器服務發出呼叫,您將需要下列值:
變數名稱 | 值 |
---|---|
METRICS_ADVISOR_ENDPOINT |
從 Azure 入口網站查看您的資源時,可以在 [金鑰與端點] 區段中找到此值。 範例端點:https://YOUR_RESOURCE_NAME.cognitiveservices.azure.com/ |
METRICS_ADVISOR_KEY |
從 Azure 入口網站查看您的資源時,可以在 [金鑰與端點] 區段中找到金鑰值。 您可以使用 KEY1 或 KEY2 。 |
METRICS_ADVISOR_API_KEY |
從 Metrics Advisor 入口網站檢查資源時,可以在 [設定]>[API 金鑰] 底下找到金鑰值。 您可以使用 KEY1 或 KEY2 。 |
SQL_CONNECTION_STRING |
本快速入門要求您擁有自己的 SQL Database + 連接字串。 範例連接字串看起來類似下列範例:Data Source=<Server>;Initial Catalog=<db-name>;User ID=<user-name>;Password=<password> 如需建構 SQL 連接字串的詳細資訊,請參閱 SQL 文件。 |
SQL_QUERY |
資料集專屬的唯一查詢。 |
建立環境變數
為您的金鑰和端點建立及指派永續性環境變數。
重要
如果您使用 API 金鑰,請將其安全地儲存在別處,例如 Azure Key Vault。 請勿在程式碼中直接包含 API 金鑰,且切勿公開張貼金鑰。
如需 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) | 範例
重要
Microsoft 建議您使用最安全的可用驗證流程。 本文中所述的一些驗證流程在應用程式中需要高度信任,且具有其他更安全流程中不存在的風險。 請僅在其他較安全的流程 (例如受控身分識別) 皆不具可行性的情況下,才使用這個流程。
必要條件
- Azure 訂用帳戶 - 建立免費帳戶
- 最新版的 Java Development Kit (JDK)
- Gradle 建置工具,或其他相依性管理員。
- 擁有 Azure 訂用帳戶之後,在 Azure 入口網站中建立計量建議程式資源,以部署計量建議程式的執行個體。
- 包含時間序列資料的 SQL 資料庫。
提示
- 您可以在 GitHub 上找到 Java Metrics Advisor 範例。
- 可能需要 10 到 30 分鐘,Metrics Advisor 資源才會將服務執行個體部署完成供您使用。 一旦成功部署,請選取 [移至資源]。 部署之後,您即可開始透過入口網站和 REST API 使用 Metrics Advisor 執行個體。
- 您可以經由 Azure 入口網站,在資源的 [概觀] 區段中找到 REST API 的 URL。 它看起來像下面這樣:
https://<instance-name>.cognitiveservices.azure.com/
設定
建立新的 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.com/ |
METRICS_ADVISOR_KEY |
從 Azure 入口網站查看您的資源時,可以在 [金鑰與端點] 區段中找到金鑰值。 您可以使用 KEY1 或 KEY2 。 |
METRICS_ADVISOR_API_KEY |
從 Metrics Advisor 入口網站檢查資源時,可以在 [設定]>[API 金鑰] 底下找到金鑰值。 您可以使用 KEY1 或 KEY2 。 |
SQL_CONNECTION_STRING |
本快速入門要求您擁有自己的 SQL Database + 連接字串。 範例連接字串看起來類似下列範例:Data Source=<Server>;Initial Catalog=<db-name>;User ID=<user-name>;Password=<password> 如需建構 SQL 連接字串的詳細資訊,請參閱 SQL 文件。 |
SQL_QUERY |
資料集專屬的唯一查詢。 |
建立環境變數
為您的金鑰和端點建立及指派永續性環境變數。
重要
如果您使用 API 金鑰,請將其安全地儲存在別處,例如 Azure Key Vault。 請勿在程式碼中直接包含 API 金鑰,且切勿公開張貼金鑰。
如需 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.com/")
.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
參考文件 | 程式庫來源程式碼 | 套件 (npm) | 範例
重要
Microsoft 建議您使用最安全的可用驗證流程。 本文中所述的一些驗證流程在應用程式中需要高度信任,且具有其他更安全流程中不存在的風險。 請僅在其他較安全的流程 (例如受控身分識別) 皆不具可行性的情況下,才使用這個流程。
必要條件
- Azure 訂用帳戶 - 建立免費帳戶
- 最新版的 Node.js
- 擁有 Azure 訂用帳戶之後,在 Azure 入口網站中建立計量建議程式資源,以部署計量建議程式的執行個體。
- 包含時間序列資料的 SQL 資料庫。
提示
- 您可以在 GitHub 上找到 JavaScript Metrics Advisor 範例。
- 可能需要 10 到 30 分鐘,Metrics Advisor 資源才會將服務執行個體部署完成供您使用。 一旦成功部署,請選取 [移至資源]。 部署之後,您即可開始透過入口網站和 REST API 使用 Metrics Advisor 執行個體。
- 您可以經由 Azure 入口網站,在資源的 [概觀] 區段中找到 REST API 的 URL。 其看起來將會像下面這樣:
https://<instance-name>.cognitiveservices.azure.com/
設定
建立新的 Node.js 應用程式
在主控台視窗 (例如 cmd、PowerShell 或 Bash) 中,為您的應用程式建立新的目錄,並瀏覽至該目錄。
mkdir myapp && cd myapp
執行命令 npm init
,以使用 package.json
檔案建立節點應用程式。
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.com/ |
METRICS_ADVISOR_KEY |
從 Azure 入口網站查看您的資源時,可以在 [金鑰與端點] 區段中找到金鑰值。 您可以使用 KEY1 或 KEY2 。 |
METRICS_ADVISOR_API_KEY |
從 Metrics Advisor 入口網站檢查資源時,可以在 [設定]>[API 金鑰] 底下找到金鑰值。 您可以使用 KEY1 或 KEY2 。 |
SQL_CONNECTION_STRING |
本快速入門要求您擁有自己的 SQL Database + 連接字串。 範例連接字串看起來類似下列範例:Data Source=<Server>;Initial Catalog=<db-name>;User ID=<user-name>;Password=<password> 如需建構 SQL 連接字串的詳細資訊,請參閱 SQL 文件。 |
SQL_QUERY |
資料集專屬的唯一查詢。 |
建立環境變數
為您的金鑰和端點建立及指派永續性環境變數。
重要
如果您使用 API 金鑰,請將其安全地儲存在別處,例如 Azure Key Vault。 請勿在程式碼中直接包含 API 金鑰,且切勿公開張貼金鑰。
如需 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
參考文件 | 程式庫原始程式碼 | 套件 (PiPy) | 範例
重要
Microsoft 建議您使用最安全的可用驗證流程。 本文中所述的一些驗證流程在應用程式中需要高度信任,且具有其他更安全流程中不存在的風險。 請僅在其他較安全的流程 (例如受控身分識別) 皆不具可行性的情況下,才使用這個流程。
必要條件
- Azure 訂用帳戶 - 建立免費帳戶
- Python 3.x
- 擁有 Azure 訂用帳戶之後,在 Azure 入口網站中建立計量建議程式資源,以部署計量建議程式的執行個體。
- 包含時間序列資料的 SQL 資料庫。
提示
- 您可以在 GitHub 上找到 Python Metrics Advisor 範例。
- 可能需要 10 到 30 分鐘,Metrics Advisor 資源才會將服務執行個體部署完成供您使用。 一旦成功部署,請選取 [移至資源]。 部署之後,您即可開始透過入口網站和 REST API 使用 Metrics Advisor 執行個體。
- 您可以經由 Azure 入口網站,在資源的 [概觀] 區段中找到 REST API 的 URL。 其看起來將會像下面這樣:
https://<instance-name>.cognitiveservices.azure.com/
設定
安裝用戶端程式庫
安裝用戶端程式庫。 您可以使用下列命令來安裝用戶端程式庫:
pip install azure-ai-metricsadvisor --pre
環境變數
若要成功對異常偵測器服務發出呼叫,您將需要下列值:
變數名稱 | 值 |
---|---|
METRICS_ADVISOR_ENDPOINT |
從 Azure 入口網站查看您的資源時,可以在 [金鑰與端點] 區段中找到此值。 範例端點:https://YOUR_RESOURCE_NAME.cognitiveservices.azure.com/ |
METRICS_ADVISOR_KEY |
從 Azure 入口網站查看您的資源時,可以在 [金鑰與端點] 區段中找到金鑰值。 您可以使用 KEY1 或 KEY2 。 |
METRICS_ADVISOR_API_KEY |
從 Metrics Advisor 入口網站檢查資源時,可以在 [設定]>[API 金鑰] 底下找到金鑰值。 您可以使用 KEY1 或 KEY2 。 |
SQL_CONNECTION_STRING |
本快速入門要求您擁有自己的 SQL Database + 連接字串。 範例連接字串看起來類似下列範例:Data Source=<Server>;Initial Catalog=<db-name>;User ID=<user-name>;Password=<password> 如需建構 SQL 連接字串的詳細資訊,請參閱 SQL 文件。 |
SQL_QUERY |
資料集專屬的唯一查詢。 |
建立環境變數
為您的金鑰和端點建立及指派永續性環境變數。
重要
如果您使用 API 金鑰,請將其安全地儲存在別處,例如 Azure Key Vault。 請勿在程式碼中直接包含 API 金鑰,且切勿公開張貼金鑰。
如需 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 資料庫。
重要
Microsoft 建議您使用最安全的可用驗證流程。 本文中所述的一些驗證流程在應用程式中需要高度信任,且具有其他更安全流程中不存在的風險。 請僅在其他較安全的流程 (例如受控身分識別) 皆不具可行性的情況下,才使用這個流程。
設定
本快速入門的範例程式碼將示範如何使用 Python 呼叫 REST API。 如需特定的 REST API 呼叫,請參閱 GitHub 範例
提示
- 可能需要 10 到 30 分鐘,Metrics Advisor 資源才會將服務執行個體部署完成供您使用。 一旦成功部署,請選取 [移至資源]。 部署之後,您即可開始透過入口網站和 REST API 使用 Metrics Advisor 執行個體。
- 您可以經由 Azure 入口網站,在資源的 [概觀] 區段中找到 REST API 的 URL。 顯示如下:
https://<instance-name>.cognitiveservices.azure.com/
環境變數
若要成功對異常偵測器服務發出呼叫,您將需要下列值:
變數名稱 | 值 |
---|---|
METRICS_ADVISOR_ENDPOINT |
從 Azure 入口網站查看您的資源時,可以在 [金鑰與端點] 區段中找到此值。 範例端點:https://YOUR_RESOURCE_NAME.cognitiveservices.azure.com/ |
METRICS_ADVISOR_KEY |
從 Azure 入口網站查看您的資源時,可以在 [金鑰與端點] 區段中找到金鑰值。 您可以使用 KEY1 或 KEY2 。 |
METRICS_ADVISOR_API_KEY |
從 Metrics Advisor 入口網站檢查資源時,可以在 [設定]>[API 金鑰] 底下找到金鑰值。 您可以使用 KEY1 或 KEY2 。 |
SQL_CONNECTION_STRING |
本快速入門要求您擁有自己的 SQL Database + 連接字串。 範例連接字串看起來類似下列範例:Data Source=<Server>;Initial Catalog=<db-name>;User ID=<user-name>;Password=<password> 如需建構 SQL 連接字串的詳細資訊,請參閱 SQL 文件。 |
SQL_QUERY |
資料集專屬的唯一查詢。 |
建立環境變數
為您的金鑰和端點建立及指派永續性環境變數。
重要
如果您使用 API 金鑰,請將其安全地儲存在別處,例如 Azure Key Vault。 請勿在程式碼中直接包含 API 金鑰,且切勿公開張貼金鑰。
如需 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.com/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 服務訂用帳戶,則可以刪除資源或資源群組。 刪除資源群組也會刪除與其相關聯的任何其他資源。