Краткое руководство. Использование клиентских библиотек или ИНТЕРФЕЙСов REST API для настройки решения
Внимание
Начиная с 20 сентября 2023 г. вы не сможете создавать новые ресурсы помощника по метрикам. Служба помощника по метрикам отменяется 1 октября 2026 года.
Узнайте, как начать работу с REST API или клиентскими библиотеками Помощника по метрикам. Выполните приведенные здесь действия, чтобы установить пакет и протестировать пример кода для выполнения базовых задач.
Помощник по метрикам позволяет выполнять следующие действия:
- добавление веб-канала данных из источника данных;
- Проверка состояния приема
- настройка обнаружения и оповещений;
- запрашивание результатов обнаружения аномалий;
- диагностика аномалий.
Справочная документация | Исходный код библиотеки | Пакет (NuGet) | Примеры
Внимание
Корпорация Майкрософт рекомендует использовать самый безопасный поток проверки подлинности. Некоторые потоки проверки подлинности, описанные в этой статье, требуют очень высокого уровня доверия к приложению и несут риски, которые не присутствуют в других более безопасных потоках. Этот поток следует использовать только в том случае, если другие более безопасные потоки, такие как управляемые удостоверения, не являются жизнеспособными.
Необходимые компоненты
- Подписка Azure — создайте бесплатную учетную запись.
- Текущая версия .NET Core.
- После получения подписки Azure создайте ресурс помощника по метрикам в портал Azure для развертывания экземпляра Помощника по метрикам.
- Собственная база данных SQL с данными временных рядов.
Совет
- Пример Помощника по метрикам для .NET можно найти на сайте GitHub.
- Ресурс Помощника по метрикам позволяет развернуть экземпляр службы за период от 10 до 30 минут. Когда развертывание завершится, щелкните Перейти к ресурсу. После развертывания можно начать работу с экземпляром Помощника по метрикам, используя веб-портал и REST API.
- URL-адрес для REST API на портале Azure можно найти в разделе Обзор ресурса. Он будет выглядеть следующим образом.
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, можно установить клиентскую библиотеку Помощника по метрикам для .NET с помощью следующей команды:
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 |
Значение ключа можно найти в разделе "Ключи> 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".
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 — создайте бесплатную учетную запись.
- Текущая версия пакета средств разработки Java (JDK).
- Средство сборки Gradle или другой диспетчер зависимостей.
- После получения подписки Azure создайте ресурс помощника по метрикам в портал Azure для развертывания экземпляра Помощника по метрикам.
- Собственная база данных SQL с данными временных рядов.
Совет
- Пример Помощника по метрикам для Java можно найти на сайте GitHub.
- Ресурс Помощника по метрикам позволяет развернуть экземпляр службы за период от 10 до 30 минут. Когда развертывание завершится, щелкните Перейти к ресурсу. После развертывания можно начать работу с экземпляром Помощника по метрикам, используя веб-портал и REST API.
- URL-адрес для REST API на портале Azure можно найти в разделе Обзор ресурса. Он должен выглядеть так:
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
Когда появится запрос на выбор предметно-ориентированного языка, выберите Kotlin.
Установка клиентской библиотеки
Найдите файл build.gradle.kts и откройте его в предпочитаемой интегрированной среде разработки или текстовом редакторе. Затем скопируйте и вставьте в файл эту конфигурацию сборки. Обязательно включите зависимости проекта.
dependencies {
compile("com.azure:azure-ai-metricsadvisor:1.1.8")
}
Создание файла Java
Создайте папку для примера приложения. Выполните следующие команды из рабочего каталога:
mkdir -p src/main/java
Перейдите в новую папку и создайте файл с именем MetricsAdvisorQuickstarts.java. Откройте его в предпочитаемом редакторе или интегрированной среде разработки и добавьте следующие операторы import
:
Совет
Хотите просмотреть готовый файл с кодом для этого краткого руководства? Его можно найти на сайте GitHub, где размещены примеры кода для этого краткого руководства.
Переменные среды
Чтобы успешно вызвать службу Детектор аномалий, вам потребуется следующее:
Имя переменной | Значение |
---|---|
METRICS_ADVISOR_ENDPOINT |
Это значение можно найти в разделе Ключи и конечная точка при просмотре ресурса на портале Azure. Пример конечной точки: https://YOUR_RESOURCE_NAME.cognitiveservices.azure.com/ |
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".
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("[email protected]"))
));
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) | Примеры
Внимание
Корпорация Майкрософт рекомендует использовать самый безопасный поток проверки подлинности. Некоторые потоки проверки подлинности, описанные в этой статье, требуют очень высокого уровня доверия к приложению и несут риски, которые не присутствуют в других более безопасных потоках. Этот поток следует использовать только в том случае, если другие более безопасные потоки, такие как управляемые удостоверения, не являются жизнеспособными.
Необходимые компоненты
- Подписка Azure — создайте бесплатную учетную запись.
- Текущая версия Node.js
- После получения подписки Azure создайте ресурс помощника по метрикам в портал Azure для развертывания экземпляра Помощника по метрикам.
- Собственная база данных SQL с данными временных рядов.
Совет
- Пример Помощника по метрикам для JavaScript можно найти на сайте GitHub.
- Ресурс Помощника по метрикам позволяет развернуть экземпляр службы за период от 10 до 30 минут. Когда развертывание завершится, щелкните Перейти к ресурсу. После развертывания можно начать работу с экземпляром Помощника по метрикам, используя веб-портал и REST API.
- URL-адрес для REST API на портале Azure можно найти в разделе Обзор ресурса. Он будет выглядеть следующим образом.
https://<instance-name>.cognitiveservices.azure.com/
Настройка
Создание нового приложения Node.js
В окне консоли (например, cmd, PowerShell или Bash) создайте новый каталог для приложения и перейдите в него.
mkdir myapp && cd myapp
Выполните команду npm init
, чтобы создать приложение узла с помощью файла package.json
.
npm init
Установка клиентской библиотеки
Установите пакет npm @azure/ai-metrics-advisor
:
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 |
Значение ключа можно найти в разделе "Ключи> 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".
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: ["[email protected]"]
};
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
для файла quickstart.
node index.js
Справочная документация | Исходный код библиотеки | Пакет (PiPy) | Примеры
Внимание
Корпорация Майкрософт рекомендует использовать самый безопасный поток проверки подлинности. Некоторые потоки проверки подлинности, описанные в этой статье, требуют очень высокого уровня доверия к приложению и несут риски, которые не присутствуют в других более безопасных потоках. Этот поток следует использовать только в том случае, если другие более безопасные потоки, такие как управляемые удостоверения, не являются жизнеспособными.
Необходимые компоненты
- Подписка Azure — создайте бесплатную учетную запись.
- Python 3.x
- После получения подписки Azure создайте ресурс помощника по метрикам в портал Azure для развертывания экземпляра Помощника по метрикам.
- Собственная база данных SQL с данными временных рядов.
Совет
- Пример Помощника по метрикам для Python можно найти на сайте GitHub.
- Ресурс Помощника по метрикам позволяет развернуть экземпляр службы за период от 10 до 30 минут. Когда развертывание завершится, щелкните Перейти к ресурсу. После развертывания можно начать работу с экземпляром Помощника по метрикам, используя веб-портал и REST API.
- URL-адрес для REST API на портале Azure можно найти в разделе Обзор ресурса. Он будет выглядеть следующим образом.
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 |
Значение ключа можно найти в разделе "Ключи> 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".
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
для файла quickstart.
python quickstart-file.py
Необходимые компоненты
- Подписка Azure — создайте бесплатную учетную запись.
- После получения подписки Azure создайте ресурс помощника по метрикам в портал Azure для развертывания экземпляра Помощника по метрикам.
- Python 3.x
- Собственная база данных SQL с данными временных рядов.
Внимание
Корпорация Майкрософт рекомендует использовать самый безопасный поток проверки подлинности. Некоторые потоки проверки подлинности, описанные в этой статье, требуют очень высокого уровня доверия к приложению и несут риски, которые не присутствуют в других более безопасных потоках. Этот поток следует использовать только в том случае, если другие более безопасные потоки, такие как управляемые удостоверения, не являются жизнеспособными.
Настройка
В примере кода для этого краткого руководства показано, как вызвать REST API с помощью Python. Сведения о конкретных вызовах REST API см. в примерах GitHub
Совет
- Ресурс Помощника по метрикам развертывает экземпляр службы от 10 до 30 минут. Когда развертывание завершится, щелкните Перейти к ресурсу. После развертывания можно начать работу с экземпляром Помощника по метрикам, используя веб-портал и REST API.
- URL-адрес для REST API на портале Azure можно найти в разделе Обзор ресурса. Он будет выглядеть так:
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 |
Значение ключа можно найти в разделе "Ключи> 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".
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": [
"[email protected]"
],
"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, можно удалить ресурс или группу ресурсов. При удалении группы ресурсов также удаляются все связанные с ней ресурсы.