Поделиться через


Клиентская библиотека запросов Azure Monitor для JavaScript версии 1.3.1

Клиентская библиотека запросов Azure Monitor используется для выполнения запросов, доступных только для чтения, для двух платформ данных Azure Monitor:

  • журналы . Собирает и упорядочивает данные журнала и производительности из отслеживаемых ресурсов. Данные из разных источников, таких как журналы платформы из служб Azure, данные журнала и производительности агентов виртуальных машин, а также данные об использовании и производительности приложений можно объединить в одну рабочей области Azure Log Analytics. Различные типы данных можно анализировать вместе с помощью языка запросов Kusto.
  • метрик . Собирает числовые данные из отслеживаемых ресурсов в базу данных временных рядов. Метрики — это числовые значения, собираемые с регулярными интервалами и описывающие некоторые аспекты системы в определенное время. Метрики являются упрощенными и способными поддерживать сценарии почти в режиме реального времени, что делает их полезными для оповещения и быстрого обнаружения проблем.

ресурсы :

Начало работы

Поддерживаемые среды

Дополнительные сведения см. вполитики поддержки .

Необходимые условия

  • подписки Azure
  • Реализация TokenCredential, например тип учетных данных библиотеки удостоверений Azure.
  • Чтобы запросить журналы, необходимо выполнить одно из следующих действий.
    • рабочей области Azure Log Analytics
    • Ресурс Azure любого типа (учетная запись хранения, Key Vault, Cosmos DB и т. д.)
  • Для запроса метрик требуется ресурс Azure любого типа (учетная запись хранения, Key Vault, Cosmos DB и т. д.).

Установка пакета

Установите клиентскую библиотеку запросов Azure Monitor для JavaScript с помощью npm:

npm install --save @azure/monitor-query

Создание клиента

Для запроса журналов или метрик требуется клиент, прошедший проверку подлинности. Для проверки подлинности в следующем примере используется DefaultAzureCredential из пакета @azure/identity.

import { DefaultAzureCredential } from "@azure/identity";
import { LogsQueryClient, MetricsQueryClient, MetricsBatchQueryClient } from "@azure/monitor-query";

const credential = new DefaultAzureCredential();

const logsQueryClient: LogsQueryClient = new LogsQueryClient(credential);
// or
const metricsQueryClient: MetricsQueryClient = new MetricsQueryClient(credential);
// or
const endPoint: string = "<YOUR_METRICS_ENDPOINT>"; //for example, https://eastus.metrics.monitor.azure.com/

const metricsQueryClient: MetricsQueryClient = new MetricsQueryClient(endPoint, credential);

Настройка клиента для суверенного облака Azure

По умолчанию клиенты библиотеки настроены на использование общедоступного облака Azure. Чтобы использовать суверенное облако, укажите правильное значение конечной точки и аудитории при создании экземпляра клиента. Например:

import { DefaultAzureCredential } from "@azure/identity";
import { LogsQueryClient, MetricsQueryClient, MetricsClient } from "@azure/monitor-query";

const credential = new DefaultAzureCredential();

const logsQueryClient: LogsQueryClient = new LogsQueryClient(credential, {
  endpoint: "https://api.loganalytics.azure.cn/v1",
  audience: "https://api.loganalytics.azure.cn/.default",
});
// or
const metricsQueryClient: MetricsQueryClient = new MetricsQueryClient(credential, {
  endpoint: "https://management.chinacloudapi.cn",
  audience: "https://monitor.azure.cn/.default",
});
// or
const endPoint: string = "<YOUR_METRICS_ENDPOINT>"; //for example, https://eastus.metrics.monitor.azure.com/

const metricsClient: MetricsClient = new MetricsClient(endPoint, credential, {
  audience: "https://monitor.azure.cn/.default",
});

примечание. В настоящее время MetricsQueryClient использует конечную точку Azure Resource Manager (ARM) для запроса метрик. При использовании этого клиента требуется соответствующая конечная точка управления для облака. Эти сведения могут быть изменены в будущем.

Выполнение запроса

Примеры запросов журналов и метрик см. в разделе примеры.

Основные понятия

Ограничения частоты запросов журналов и регулирование

Служба Log Analytics применяет регулирование, если скорость запроса слишком высока. Ограничения, такие как максимальное количество возвращаемых строк, также применяются к запросам Kusto. Дополнительные сведения см. в API запросов.

Структура данных метрик

Каждый набор значений метрик — это временный ряд со следующими характеристиками:

  • Время сбора значения
  • Ресурс, связанный со значением
  • Пространство имен, которое действует как категория для метрики
  • Имя метрики
  • Само значение
  • Некоторые метрики имеют несколько измерений, как описано в многомерных метриках. Пользовательские метрики могут содержать до 10 измерений.

Примеры

Запрос журналов

LogsQueryClient можно использовать для запроса рабочей области Log Analytics с помощью языка запросов Kusto. timespan.duration можно указать как строку в формате длительности ISO 8601. Константы Durations, предоставляемые для некоторых часто используемых длительности ISO 8601.

Журналы можно запрашивать по идентификатору рабочей области Log Analytics или идентификатору ресурса Azure. Результат возвращается в виде таблицы с коллекцией строк.

Запрос журналов, ориентированных на рабочую область

Чтобы выполнить запрос по идентификатору рабочей области, используйте метод LogsQueryClient.queryWorkspace:

import { DefaultAzureCredential } from "@azure/identity";
import { Durations, LogsQueryClient, LogsQueryResultStatus, LogsTable } from "@azure/monitor-query";

const azureLogAnalyticsWorkspaceId = "<the Workspace Id for your Azure Log Analytics resource>";
const logsQueryClient = new LogsQueryClient(new DefaultAzureCredential());

async function run() {
  const kustoQuery = "AppEvents | limit 1";
  const result = await logsQueryClient.queryWorkspace(azureLogAnalyticsWorkspaceId, kustoQuery, {
    duration: Durations.twentyFourHours,
  });

  if (result.status === LogsQueryResultStatus.Success) {
    const tablesFromResult: LogsTable[] = result.tables;

    if (tablesFromResult.length === 0) {
      console.log(`No results for query '${kustoQuery}'`);
      return;
    }
    console.log(`This query has returned table(s) - `);
    processTables(tablesFromResult);
  } else {
    console.log(`Error processing the query '${kustoQuery}' - ${result.partialError}`);
    if (result.partialTables.length > 0) {
      console.log(`This query has also returned partial data in the following table(s) - `);
      processTables(result.partialTables);
    }
  }
}

async function processTables(tablesFromResult: LogsTable[]) {
  for (const table of tablesFromResult) {
    const columnHeaderString = table.columnDescriptors
      .map((column) => `${column.name}(${column.type}) `)
      .join("| ");
    console.log("| " + columnHeaderString);

    for (const row of table.rows) {
      const columnValuesString = row.map((columnValue) => `'${columnValue}' `).join("| ");
      console.log("| " + columnValuesString);
    }
  }
}

run().catch((err) => console.log("ERROR:", err));

Запрос к журналам, ориентированным на ресурсы

В следующем примере показано, как запрашивать журналы непосредственно из ресурса Azure. Здесь используется метод queryResource и передается идентификатор ресурса Azure. Например, /subscriptions/{subscription-id}/resourceGroups/{resource-group-name}/providers/{resource-provider}/{resource-type}/{resource-name}.

Чтобы найти идентификатор ресурса, выполните следующие действия.

  1. Перейдите на страницу ресурса на портале Azure.
  2. В колонке Обзор выберите ссылку представления JSON.
  3. В результирующем формате JSON скопируйте значение свойства id.
/**
 * @summary Demonstrates how to run a query against a Log Analytics workspace, using an Azure resource ID.
 */

import { DefaultAzureCredential } from "@azure/identity";
import {
  Durations,
  LogsQueryClient,
  LogsTable,
  LogsQueryOptions,
  LogsQueryResultStatus,
} from "@azure/monitor-query";
import * as dotenv from "dotenv";
dotenv.config();

const logsResourceId = process.env.LOGS_RESOURCE_ID;

export async function main() {
  const tokenCredential = new DefaultAzureCredential();
  const logsQueryClient = new LogsQueryClient(tokenCredential);

  if (!logsResourceId) {
    throw new Error("LOGS_RESOURCE_ID must be set in the environment for this sample");
  }

  const kustoQuery = `MyTable_CL | summarize count()`;

  console.log(`Running '${kustoQuery}' over the last One Hour`);
  const queryLogsOptions: LogsQueryOptions = {
    // explicitly control the amount of time the server can spend processing the query.
    serverTimeoutInSeconds: 600, // sets the timeout to 10 minutes
    // optionally enable returning additional statistics about the query's execution.
    // (by default, this is off)
    includeQueryStatistics: true,
  };

  const result = await logsQueryClient.queryResource(
    logsResourceId,
    kustoQuery,
    { duration: Durations.sevenDays },
    queryLogsOptions,
  );

  const executionTime =
    result.statistics && result.statistics.query && (result.statistics.query as any).executionTime;

  console.log(
    `Results for query '${kustoQuery}', execution time: ${
      executionTime == null ? "unknown" : executionTime
    }`,
  );

  if (result.status === LogsQueryResultStatus.Success) {
    const tablesFromResult: LogsTable[] = result.tables;

    if (tablesFromResult.length === 0) {
      console.log(`No results for query '${kustoQuery}'`);
      return;
    }
    console.log(`This query has returned table(s) - `);
    processTables(tablesFromResult);
  } else {
    console.log(`Error processing the query '${kustoQuery}' - ${result.partialError}`);
    if (result.partialTables.length > 0) {
      console.log(`This query has also returned partial data in the following table(s) - `);
      processTables(result.partialTables);
    }
  }
}

async function processTables(tablesFromResult: LogsTable[]) {
  for (const table of tablesFromResult) {
    const columnHeaderString = table.columnDescriptors
      .map((column) => `${column.name}(${column.type}) `)
      .join("| ");
    console.log("| " + columnHeaderString);

    for (const row of table.rows) {
      const columnValuesString = row.map((columnValue) => `'${columnValue}' `).join("| ");
      console.log("| " + columnValuesString);
    }
  }
}

main().catch((err) => {
  console.error("The sample encountered an error:", err);
  process.exit(1);
});

Обработка ответа запроса журналов

Функция queryWorkspaceLogsQueryClient возвращает объект LogsQueryResult. Тип объекта может быть LogsQuerySuccessfulResult или LogsQueryPartialResult. Ниже приведена иерархия ответа:

LogsQuerySuccessfulResult
|---statistics
|---visualization
|---status ("Success")
|---tables (list of `LogsTable` objects)
    |---name
    |---rows
    |---columnDescriptors (list of `LogsColumn` objects)
        |---name
        |---type

LogsQueryPartialResult
|---statistics
|---visualization
|---status ("PartialFailure")
|---partialError
    |--name
    |--code
    |--message
    |--stack
|---partialTables (list of `LogsTable` objects)
    |---name
    |---rows
    |---columnDescriptors (list of `LogsColumn` objects)
        |---name
        |---type

Например, чтобы обрабатывать ответ с таблицами:

async function processTables(tablesFromResult: LogsTable[]) {
  for (const table of tablesFromResult) {
    const columnHeaderString = table.columnDescriptors
      .map((column) => `${column.name}(${column.type}) `)
      .join("| ");
    console.log("| " + columnHeaderString);

    for (const row of table.rows) {
      const columnValuesString = row.map((columnValue) => `'${columnValue}' `).join("| ");
      console.log("| " + columnValuesString);
    }
  }
}

Полный пример можно найти здесь.

Запрос к журналам пакетной службы

В следующем примере показано, как отправлять несколько запросов одновременно с помощью API пакетного запроса. Запросы можно представить в виде списка BatchQuery объектов.

export async function main() {
  if (!monitorWorkspaceId) {
    throw new Error("MONITOR_WORKSPACE_ID must be set in the environment for this sample");
  }

  const tokenCredential = new DefaultAzureCredential();
  const logsQueryClient = new LogsQueryClient(tokenCredential);

  const kqlQuery = "AppEvents | project TimeGenerated, Name, AppRoleInstance | limit 1";
  const queriesBatch = [
    {
      workspaceId: monitorWorkspaceId,
      query: kqlQuery,
      timespan: { duration: "P1D" },
    },
    {
      workspaceId: monitorWorkspaceId,
      query: "AzureActivity | summarize count()",
      timespan: { duration: "PT1H" },
    },
    {
      workspaceId: monitorWorkspaceId,
      query:
        "AppRequests | take 10 | summarize avgRequestDuration=avg(DurationMs) by bin(TimeGenerated, 10m), _ResourceId",
      timespan: { duration: "PT1H" },
    },
    {
      workspaceId: monitorWorkspaceId,
      query: "AppRequests | take 2",
      timespan: { duration: "PT1H" },
      includeQueryStatistics: true,
    },
  ];

  const result = await logsQueryClient.queryBatch(queriesBatch);

  if (result == null) {
    throw new Error("No response for query");
  }

  let i = 0;
  for (const response of result) {
    console.log(`Results for query with query: ${queriesBatch[i]}`);
    if (response.status === LogsQueryResultStatus.Success) {
      console.log(
        `Printing results from query '${queriesBatch[i].query}' for '${queriesBatch[i].timespan}'`,
      );
      processTables(response.tables);
    } else if (response.status === LogsQueryResultStatus.PartialFailure) {
      console.log(
        `Printing partial results from query '${queriesBatch[i].query}' for '${queriesBatch[i].timespan}'`,
      );
      processTables(response.partialTables);
      console.log(
        ` Query had errors:${response.partialError.message} with code ${response.partialError.code}`,
      );
    } else {
      console.log(`Printing errors from query '${queriesBatch[i].query}'`);
      console.log(` Query had errors:${response.message} with code ${response.code}`);
    }
    // next query
    i++;
  }
}

async function processTables(tablesFromResult: LogsTable[]) {
  for (const table of tablesFromResult) {
    const columnHeaderString = table.columnDescriptors
      .map((column) => `${column.name}(${column.type}) `)
      .join("| ");
    console.log("| " + columnHeaderString);

    for (const row of table.rows) {
      const columnValuesString = row.map((columnValue) => `'${columnValue}' `).join("| ");
      console.log("| " + columnValuesString);
    }
  }
}

Обработка ответа пакетного запроса журналов

Функция queryBatchLogsQueryClient возвращает объект LogsQueryBatchResult. LogsQueryBatchResult содержит список объектов со следующими возможными типами:

  • LogsQueryPartialResult
  • LogsQuerySuccessfulResult
  • LogsQueryError

Ниже приведена иерархия ответа:

LogsQuerySuccessfulResult
|---statistics
|---visualization
|---status ("Success")
|---tables (list of `LogsTable` objects)
    |---name
    |---rows
    |---columnDescriptors (list of `LogsColumn` objects)
        |---name
        |---type

LogsQueryPartialResult
|---statistics
|---visualization
|---status ("PartialFailure")
|---partialError
    |--name
    |--code
    |--message
    |--stack
|---partialTables (list of `LogsTable` objects)
    |---name
    |---rows
    |---columnDescriptors (list of `LogsColumn` objects)
        |---name
        |---type

LogsQueryError
|--name
|--code
|--message
|--stack
|--status ("Failure")

Например, следующий код обрабатывает ответ запроса пакетных журналов:

async function processBatchResult(result: LogsQueryBatchResult) {
  let i = 0;
  for (const response of result) {
    console.log(`Results for query with query: ${queriesBatch[i]}`);
    if (response.status === LogsQueryResultStatus.Success) {
      console.log(
        `Printing results from query '${queriesBatch[i].query}' for '${queriesBatch[i].timespan}'`,
      );
      processTables(response.tables);
    } else if (response.status === LogsQueryResultStatus.PartialFailure) {
      console.log(
        `Printing partial results from query '${queriesBatch[i].query}' for '${queriesBatch[i].timespan}'`,
      );
      processTables(response.partialTables);
      console.log(
        ` Query had errors:${response.partialError.message} with code ${response.partialError.code}`,
      );
    } else {
      console.log(`Printing errors from query '${queriesBatch[i].query}'`);
      console.log(` Query had errors:${response.message} with code ${response.code}`);
    }
    // next query
    i++;
  }
}

async function processTables(tablesFromResult: LogsTable[]) {
  for (const table of tablesFromResult) {
    const columnHeaderString = table.columnDescriptors
      .map((column) => `${column.name}(${column.type}) `)
      .join("| ");
    console.log("| " + columnHeaderString);

    for (const row of table.rows) {
      const columnValuesString = row.map((columnValue) => `'${columnValue}' `).join("| ");
      console.log("| " + columnValuesString);
    }
  }
}

Полный пример можно найти здесь.

Расширенные сценарии запросов журналов

Установка времени ожидания запроса журналов

Выполнение некоторых запросов журналов занимает более 3 минут. Время ожидания сервера по умолчанию — 3 минуты. Время ожидания сервера можно увеличить до 10 минут. В следующем примере свойство serverTimeoutInSeconds объекта LogsQueryOptions используется для увеличения времени ожидания сервера до 10 минут:

// setting optional parameters
const queryLogsOptions: LogsQueryOptions = {
  // explicitly control the amount of time the server can spend processing the query.
  serverTimeoutInSeconds: 600, // 600 seconds = 10 minutes
};

const result = await logsQueryClient.queryWorkspace(
  azureLogAnalyticsWorkspaceId,
  kustoQuery,
  { duration: Durations.twentyFourHours },
  queryLogsOptions,
);

const tablesFromResult = result.tables;

Запрос нескольких рабочих областей

Один и тот же запрос журналов можно выполнять в нескольких рабочих областях Log Analytics. Помимо запроса Kusto, требуются следующие параметры:

  • workspaceId — первый (основной) идентификатор рабочей области.
  • additionalWorkspaces — список рабочих областей, за исключением рабочей области, предоставленной в параметре workspaceId. Элементы списка параметров могут состоять из следующих форматов идентификаторов:
    • Квалифицированные имена рабочих областей
    • Идентификаторы рабочих областей
    • Идентификаторы ресурсов Azure

Например, следующий запрос выполняется в трех рабочих областях:

const queryLogsOptions: LogsQueryOptions = {
  additionalWorkspaces: ["<workspace2>", "<workspace3>"],
};

const kustoQuery = "AppEvents | limit 10";
const result = await logsQueryClient.queryWorkspace(
  azureLogAnalyticsWorkspaceId,
  kustoQuery,
  { duration: Durations.twentyFourHours },
  queryLogsOptions,
);

Чтобы просмотреть результаты для каждой рабочей области, используйте столбец TenantId, чтобы упорядочить результаты или отфильтровать их в запросе Kusto.

Результаты заказа по Идентификатору клиента

AppEvents | order by TenantId

результаты фильтрации по Идентификатору клиента

AppEvents | filter TenantId == "<workspace2>"

Полный пример можно найти здесь.

Включение статистики

Чтобы получить статистику выполнения запросов журналов, например использование ЦП и памяти:

  1. Задайте для свойства LogsQueryOptions.includeQueryStatistics значение true.
  2. Доступ к полю statistics внутри объекта LogsQueryResult.

В следующем примере выводится время выполнения запроса:

const monitorWorkspaceId = "<workspace_id>";
const logsQueryClient = new LogsQueryClient(new DefaultAzureCredential());
const kustoQuery = "AzureActivity | top 10 by TimeGenerated";

const result = await logsQueryClient.queryWorkspace(
  monitorWorkspaceId,
  kustoQuery,
  { duration: Durations.oneDay },
  {
    includeQueryStatistics: true,
  },
);

const executionTime =
  result.statistics && result.statistics.query && result.statistics.query.executionTime;

console.log(
  `Results for query '${kustoQuery}', execution time: ${
    executionTime == null ? "unknown" : executionTime
  }`,
);

Поскольку структура полезных данных statistics зависит от запроса, используется тип возврата Record<string, unknown>. Он содержит необработанный ответ JSON. Статистика находится в свойстве query JSON. Например:

{
  "query": {
    "executionTime": 0.0156478,
    "resourceUsage": {...},
    "inputDatasetStatistics": {...},
    "datasetStatistics": [{...}]
  }
}

Включение визуализации

Получение данных визуализации для запросов журналов с помощью оператора отрисовки:

  1. Задайте для свойства LogsQueryOptions.includeVisualization значение true.
  2. Доступ к полю visualization внутри объекта LogsQueryResult.

Например:

const monitorWorkspaceId = "<workspace_id>";
const logsQueryClient = new LogsQueryClient(new DefaultAzureCredential());

const result = await logsQueryClient.queryWorkspace(
    monitorWorkspaceId,
    `StormEvents
        | summarize event_count = count() by State
        | where event_count > 10
        | project State, event_count
        | render columnchart`,
    { duration: Durations.oneDay },
    {
      includeVisualization: true
    }
  );
console.log("visualization result:", result.visualization);

Поскольку структура полезных данных visualization зависит от запроса, используется тип возврата Record<string, unknown>. Он содержит необработанный ответ JSON. Например:

{
  "visualization": "columnchart",
  "title": "the chart title",
  "accumulate": false,
  "isQuerySorted": false,
  "kind": null,
  "legend": null,
  "series": null,
  "yMin": "NaN",
  "yMax": "NaN",
  "xAxis": null,
  "xColumn": null,
  "xTitle": "x axis title",
  "yAxis": null,
  "yColumns": null,
  "ySplit": null,
  "yTitle": null,
  "anomalyColumns": null
}

Запрос метрик

В следующем примере возвращаются метрики для подписки Помощника по метрикам Azure. URI ресурса должен быть ресурсом, для которого запрашиваются метрики. Обычно это формат /subscriptions/<id>/resourceGroups/<rg-name>/providers/<source>/topics/<resource-name>.

Чтобы найти URI ресурса, выполните следующие действия.

  1. Перейдите на страницу ресурса на портале Azure.
  2. В колонке Обзор выберите ссылку представления JSON.
  3. В результирующем формате JSON скопируйте значение свойства id.
import { DefaultAzureCredential } from "@azure/identity";
import { Durations, Metric, MetricsQueryClient } from "@azure/monitor-query";
import * as dotenv from "dotenv";

dotenv.config();

const metricsResourceId = process.env.METRICS_RESOURCE_ID;

export async function main() {
  const tokenCredential = new DefaultAzureCredential();
  const metricsQueryClient = new MetricsQueryClient(tokenCredential);

  if (!metricsResourceId) {
    throw new Error("METRICS_RESOURCE_ID must be set in the environment for this sample");
  }

  const iterator = metricsQueryClient.listMetricDefinitions(metricsResourceId);
  let result = await iterator.next();
  let metricNames: string[] = [];
  for await (const result of iterator) {
    console.log(` metricDefinitions - ${result.id}, ${result.name}`);
    if (result.name) {
      metricNames.push(result.name);
    }
  }
  const firstMetricName = metricNames[0];
  const secondMetricName = metricNames[1];
  if (firstMetricName && secondMetricName) {
    console.log(`Picking an example metric to query: ${firstMetricName} and ${secondMetricName}`);
    const metricsResponse = await metricsQueryClient.queryResource(
      metricsResourceId,
      [firstMetricName, secondMetricName],
      {
        granularity: "PT1M",
        timespan: { duration: Durations.fiveMinutes },
      },
    );

    console.log(
      `Query cost: ${metricsResponse.cost}, interval: ${metricsResponse.granularity}, time span: ${metricsResponse.timespan}`,
    );

    const metrics: Metric[] = metricsResponse.metrics;
    console.log(`Metrics:`, JSON.stringify(metrics, undefined, 2));
    const metric = metricsResponse.getMetricByName(firstMetricName);
    console.log(`Selected Metric: ${firstMetricName}`, JSON.stringify(metric, undefined, 2));
  } else {
    console.error(`Metric names are not defined - ${firstMetricName} and ${secondMetricName}`);
  }
}

main().catch((err) => {
  console.error("The sample encountered an error:", err);
  process.exit(1);
});

В предыдущем примере метрика приводит к metricsResponse упорядочивается в соответствии с порядком, в котором пользователь задает имена метрик в аргументе массива metricNames для функции queryResource. Если пользователь указывает [firstMetricName, secondMetricName], результат firstMetricName появится перед результатом secondMetricName в metricResponse.

Обработка ответа на запрос метрик

Функция метрик queryResource возвращает объект QueryMetricsResult. Объект QueryMetricsResult содержит такие свойства, как список Metricтипизированных объектов, interval, namespaceи timespan. Доступ к списку объектов Metric можно получить с помощью свойства metrics. Каждый объект Metric в этом списке содержит список TimeSeriesElement объектов. Каждый TimeSeriesElement содержит свойства data и metadataValues. В визуальной форме иерархия объектов ответа напоминает следующую структуру:

QueryMetricsResult
|---cost
|---timespan (of type `QueryTimeInterval`)
|---granularity
|---namespace
|---resourceRegion
|---metrics (list of `Metric` objects)
    |---id
    |---type
    |---name
    |---unit
    |---displayDescription
    |---errorCode
    |---timeseries (list of `TimeSeriesElement` objects)
        |---metadataValues
        |---data (list of data points represented by `MetricValue` objects)
            |---timeStamp
            |---average
            |---minimum
            |---maximum
            |---total
            |---count
|---getMetricByName(metricName): Metric | undefined (convenience method)

Пример обработки ответа

import { DefaultAzureCredential } from "@azure/identity";
import { Durations, Metric, MetricsQueryClient } from "@azure/monitor-query";
import * as dotenv from "dotenv";
dotenv.config();

const metricsResourceId = process.env.METRICS_RESOURCE_ID;
export async function main() {
  const tokenCredential = new DefaultAzureCredential();
  const metricsQueryClient = new MetricsQueryClient(tokenCredential);

  if (!metricsResourceId) {
    throw new Error(
      "METRICS_RESOURCE_ID for an Azure Metrics Advisor subscription must be set in the environment for this sample",
    );
  }

  console.log(`Picking an example metric to query: MatchedEventCount`);

  const metricsResponse = await metricsQueryClient.queryResource(
    metricsResourceId,
    ["MatchedEventCount"],
    {
      timespan: {
        duration: Durations.fiveMinutes,
      },
      granularity: "PT1M",
      aggregations: ["Count"],
    },
  );

  console.log(
    `Query cost: ${metricsResponse.cost}, granularity: ${metricsResponse.granularity}, time span: ${metricsResponse.timespan}`,
  );

  const metrics: Metric[] = metricsResponse.metrics;
  for (const metric of metrics) {
    console.log(metric.name);
    for (const timeseriesElement of metric.timeseries) {
      for (const metricValue of timeseriesElement.data!) {
        if (metricValue.count !== 0) {
          console.log(`There are ${metricValue.count} matched events at ${metricValue.timeStamp}`);
        }
      }
    }
  }
}

main().catch((err) => {
  console.error("The sample encountered an error:", err);
  process.exit(1);
});

Полный пример можно найти здесь.

Метрики запросов для нескольких ресурсов

Чтобы запросить метрики для нескольких ресурсов Azure в одном запросе, используйте метод MetricsClient.queryResources. Этот метод:

  • Вызывает другой API, отличный от методов MetricsClient.
  • Требуется региональная конечная точка при создании клиента. Например, "https://westus3.metrics.monitor.azure.com".

Каждый ресурс Azure должен находиться в:

  • Тот же регион, что и конечная точка, указанная при создании клиента.
  • Та же подписка Azure.

Кроме того:

  • Пользователь должен быть авторизован для чтения данных мониторинга на уровне подписки Azure. Например, роль средства чтения мониторинга в подписке, запрашиваемой.
  • Пространство имен метрик, содержащее метрики для запроса, должно быть предоставлено. Список пространств имен метрик см. в разделе Поддерживаемые метрики и категории журналов по типу ресурса.
let resourceIds: string[] = [
  "/subscriptions/0000000-0000-000-0000-000000/resourceGroups/test/providers/Microsoft.OperationalInsights/workspaces/test-logs",
  "/subscriptions/0000000-0000-000-0000-000000/resourceGroups/test/providers/Microsoft.OperationalInsights/workspaces/test-logs2",
];
let metricsNamespace: string = "<YOUR_METRICS_NAMESPACE>";
let metricNames: string[] = ["requests", "count"];
const endpoint: string = "<YOUR_METRICS_ENDPOINT>"; //for example, https://eastus.metrics.monitor.azure.com/

const credential = new DefaultAzureCredential();
const metricsClient: MetricsClient = new MetricsClient(
  endpoint,
  credential
);

const result: : MetricsQueryResult[] = await metricsClient.queryResources(
  resourceIds,
  metricNames,
  metricsNamespace
);

Список метрик и измерений, доступных для каждого типа ресурсов Azure, см. в разделе Поддерживаемые метрики с помощью Azure Monitor.

Устранение неполадок

Сведения о диагностике различных сценариев сбоя см. в руководстве по устранению неполадок .

Дальнейшие действия

Дополнительные сведения об Azure Monitor см. в документации по службе Azure Monitor.

Способствует

Если вы хотите внести свой вклад в эту библиотеку, ознакомьтесь с руководством по вкладу, чтобы узнать больше о том, как создавать и тестировать код.

Тесты этого модуля — это смесь динамических и модульных тестов, которые требуют наличия экземпляра Azure Monitor. Чтобы выполнить тесты, необходимо выполнить следующее:

  1. rush update
  2. rush build -t @azure/monitor-query
  3. cd into sdk/monitor/monitor-query
  4. Скопируйте файл sample.env в .env
  5. Откройте файл .env в редакторе и заполните значения.
  6. npm run test.

Дополнительные сведения см. в тестах папке.

впечатлений