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


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

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

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

Миграция с @azure/monitor-query консультативного ⚠️

Ознакомьтесь с Руководством по миграции , чтобы получить подробные инструкции о том, как обновить код приложения из исходного @azure/monitor-query пакета в библиотеку @azure/monitor-query-logs .

Ресурсы:

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

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

Для получения дополнительной информации ознакомьтесь с нашей политикой поддержки.

Предпосылки

  • Подписка Azure
  • Реализация TokenCredential, например, такой тип учетных данных, как в библиотеке удостоверений Azure .
  • Чтобы запросить журналы, необходимо выполнить одно из следующих действий.

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

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

npm install --save @azure/monitor-query-logs

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

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

import { DefaultAzureCredential } from "@azure/identity";
import { LogsQueryClient } from "@azure/monitor-query-logs";

const credential = new DefaultAzureCredential();

// Create a LogsQueryClient
const logsQueryClient = new LogsQueryClient(credential);

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

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

import { DefaultAzureCredential } from "@azure/identity";
import { LogsQueryClient } from "@azure/monitor-query-logs";

const credential = new DefaultAzureCredential();

// Create a LogsQueryClient
const logsQueryClient: LogsQueryClient = new LogsQueryClient(credential, {
  endpoint: "https://api.loganalytics.azure.cn/v1",
  audience: "https://api.loganalytics.azure.cn/.default",
});

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

Примеры запросов Logs см. в разделе Примеры .

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

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

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

Примеры

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

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

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

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

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

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

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

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

if (result.status === LogsQueryResultStatus.Success) {
  const tablesFromResult = 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);
  }
}

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

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

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

  1. Перейдите на страницу ресурса на портале Azure.
  2. В колонке Обзор выберите ссылку Представление JSON .
  3. В полученном JSON скопируйте значение id свойства.
import { DefaultAzureCredential } from "@azure/identity";
import { LogsQueryClient, Durations, LogsQueryResultStatus } from "@azure/monitor-query-logs";

const logsResourceId = "<the Resource Id for your logs resource>";

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

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

console.log(`Running '${kustoQuery}' over the last One Hour`);
const queryLogsOptions = {
  // 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,
);

console.log(`Results for query '${kustoQuery}'`);

if (result.status === LogsQueryResultStatus.Success) {
  const tablesFromResult = 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);
  }
}

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

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

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

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

function processTables(tablesFromResult) {
  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 объектов.

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

const monitorWorkspaceId = "<workspace_id>";

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++;
}

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

Функция queryBatch возвращает LogsQueryClientLogsQueryBatchResult объект. 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")

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

import { LogsQueryResultStatus } from "@azure/monitor-query-logs";

async function processBatchResult(result, queriesBatch) {
  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++;
  }
}
function processTables(tablesFromResult) {
  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 минут. В следующем примере LogsQueryOptions свойство объекта serverTimeoutInSeconds используется для увеличения времени ожидания сервера до 10 минут:

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

const azureLogAnalyticsWorkspaceId = "<workspace_id>";

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

const kqlQuery = "AppEvents | project TimeGenerated, Name, AppRoleInstance | limit 1";

// setting optional parameters
const queryLogsOptions = {
  // 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,
  kqlQuery,
  { duration: Durations.twentyFourHours },
  queryLogsOptions,
);

const status = result.status;

Запрос данных из нескольких рабочих пространств

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

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

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

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

const azureLogAnalyticsWorkspaceId = "<workspace_id>";

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

const kqlQuery = "AppEvents | project TimeGenerated, Name, AppRoleInstance | limit 1";

// setting optional parameters
const queryLogsOptions = {
  additionalWorkspaces: ["<workspace2>", "<workspace3>"],
};

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

const status = result.status;

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

Результаты заказа по TenantId

AppEvents | order by TenantId

Фильтрация результатов по TenantId

AppEvents | filter TenantId == "<workspace2>"

С полным образцом можно ознакомиться здесь.

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

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

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

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

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

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,
  },
);

console.log(`Results for query '${kustoQuery}'`);

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

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

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

Чтобы получить данные визуализации для запросов к логам с помощью оператора render, выполните следующие действия:

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

Рассмотрим пример.

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

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 Monitor см. в документации по службе Azure Monitor.

Вклад

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

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

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

Для получения более подробной информации просмотрите нашу папку с тестами .