Biblioteca de cliente de Consulta do Azure Monitor para JavaScript – versão 1.2.0

A biblioteca de cliente de Consulta do Azure Monitor é utilizada para executar consultas só de leitura nas duas plataformas de dados do Azure Monitor:

  • Registos – recolhe e organiza dados de registo e desempenho de recursos monitorizados. Os dados de diferentes origens, como registos de plataformas de serviços do Azure, dados de registo e desempenho de agentes de máquinas virtuais e dados de utilização e desempenho de aplicações, podem ser consolidados numa única área de trabalho do Azure Log Analytics. Os vários tipos de dados podem ser analisados em conjunto com o Linguagem de Pesquisa Kusto.
  • Métricas – recolhe dados numéricos de recursos monitorizados para uma base de dados de série temporal. As métricas são valores numéricos que são recolhidos em intervalos regulares e descrevem alguns aspetos de um sistema num determinado momento. As métricas são leves e capazes de suportar cenários quase em tempo real, tornando-as úteis para alertas e deteção rápida de problemas.

Recursos:

Introdução

Ambientes suportados

Para obter mais informações, veja a nossa política de suporte.

Pré-requisitos

Instalar o pacote

Instale a biblioteca de cliente de Consulta do Azure Monitor para JavaScript com o npm:

npm install @azure/monitor-query

Criar o cliente

É necessário um cliente autenticado para consultar Registos ou Métricas. Para autenticar, o exemplo seguinte utiliza DefaultAzureCredential a partir do pacote de identidade/@azure .

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

Configurar o cliente para a cloud soberana do Azure

Por predefinição, LogsQueryClient estão MetricsQueryClient configurados para utilizar a Cloud Pública do Azure. Em vez disso, para utilizar uma cloud soberana, forneça o argumento correto endpoint . Por exemplo:

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

const credential = new DefaultAzureCredential();

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

// or
const metricsQueryClient = new MetricsQueryClient(credential{
  endpoint: "https://management.chinacloudapi.cn",
});

Nota: atualmente, MetricsQueryClient utiliza o ponto final do Azure Resource Manager (ARM) para consultar métricas. Precisa do ponto final de gestão correspondente para a sua cloud ao utilizar este cliente. Este detalhe está sujeito a alterações no futuro.

Executar a consulta

Para obter exemplos de consultas de Registos e Métricas, veja a secção Exemplos .

Conceitos-chave

Limites e limitação da taxa de consulta de registos

O serviço Log Analytics aplica limitação quando a taxa de pedidos é demasiado elevada. Os limites, como o número máximo de linhas devolvidas, também são aplicados nas consultas kusto. Para obter mais informações, veja API de Consulta.

Estrutura de dados de métricas

Cada conjunto de valores de métricas é uma série temporal com as seguintes características:

  • A hora em que o valor foi recolhido
  • O recurso associado ao valor
  • Um espaço de nomes que age como uma categoria para a métrica
  • Um nome de métrica
  • O valor em si
  • Algumas métricas têm múltiplas dimensões, conforme descrito em métricas multidimensionais. As métricas personalizadas podem ter até 10 dimensões.

Exemplos

Consulta de registos

Pode LogsQueryClient ser utilizado para consultar uma área de trabalho do Log Analytics com o Linguagem de Pesquisa Kusto. Pode timespan.duration ser especificado como uma cadeia num formato de duração ISO 8601. Pode utilizar as Durations constantes fornecidas para algumas durações ISO 8601 frequentemente utilizadas.

Pode consultar registos por ID de área de trabalho ou ID de recurso. O resultado é devolvido como uma tabela com uma coleção de linhas.

Consulta de registos centrados na área de trabalho

Para consultar por ID da área de trabalho, utilize o LogsQueryClient.queryWorkspace método:

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

Consulta de registos centrados em recursos

O exemplo seguinte demonstra como consultar registos diretamente a partir de um recurso do Azure. Aqui, o queryResource método é utilizado e é transmitido um ID de recurso do Azure. Por exemplo, /subscriptions/{subscription-id}/resourceGroups/{resource-group-name}/providers/{resource-provider}/{resource-type}/{resource-name}.

Para localizar o ID do recurso:

  1. Navegue para a página do recurso no portal do Azure.
  2. No painel Descrição geral , selecione a ligação Vista JSON .
  3. No JSON resultante, copie o valor da id propriedade.
/**
 * @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);
});

Processar a resposta da consulta de registos

A queryWorkspace função de LogsQueryClient devolve um LogsQueryResult objeto. O tipo de objeto pode ser LogsQuerySuccessfulResult ou LogsQueryPartialResult. Segue-se uma hierarquia da resposta:

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

Por exemplo, para processar uma resposta com tabelas:

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

Pode encontrar um exemplo completo aqui.

Consulta de registos do Batch

O exemplo seguinte demonstra o envio de várias consultas ao mesmo tempo através da API de consulta em lote. As consultas podem ser representadas como uma lista de BatchQuery objetos.

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

Processar a resposta da consulta do batch de registos

A queryBatch função de LogsQueryClient devolve um LogsQueryBatchResult objeto. LogsQueryBatchResult contém uma lista de objetos com os seguintes tipos possíveis:

  • LogsQueryPartialResult
  • LogsQuerySuccessfulResult
  • LogsQueryError

Segue-se uma hierarquia da resposta:

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")

Por exemplo, o seguinte código processa uma resposta de consulta de registos em lote:

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

Pode encontrar um exemplo completo aqui.

Cenários de consulta de registos avançados

Definir o tempo limite da consulta de registos

Algumas consultas de registos demoram mais de 3 minutos a ser executadas. O tempo limite predefinido do servidor é de 3 minutos. Pode aumentar o tempo limite do servidor para um máximo de 10 minutos. No exemplo seguinte, a LogsQueryOptions propriedade do objeto é utilizada para aumentar o tempo limite do serverTimeoutInSeconds servidor para 10 minutos:

// 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;

Consultar várias áreas de trabalho

A mesma consulta de registos pode ser executada em várias áreas de trabalho do Log Analytics. Além da consulta Kusto, são necessários os seguintes parâmetros:

  • workspaceId - O primeiro ID (primário) da área de trabalho.
  • additionalWorkspaces - Uma lista de áreas de trabalho, excluindo a área de trabalho fornecida no workspaceId parâmetro . Os itens de lista do parâmetro podem consistir nos seguintes formatos de identificador:
    • Nomes de áreas de trabalho qualificadas
    • IDs da Área de Trabalho
    • IDs de recursos do Azure

Por exemplo, a seguinte consulta é executada em três áreas de trabalho:

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

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

Para ver os resultados de cada área de trabalho, utilize a TenantId coluna para ordenar os resultados ou filtrá-los na consulta Kusto.

Resultados da encomenda por TenantId

AppEvents | order by TenantId

Filtrar resultados por TenantId

AppEvents | filter TenantId == "<workspace2>"

Pode encontrar um exemplo completo aqui.

Incluir estatísticas

Para obter estatísticas de execução de consultas de registos, tais como consumo de CPU e memória:

  1. Defina a LogsQueryOptions.includeQueryStatistics propriedade como true.
  2. Aceda ao statistics campo dentro do LogsQueryResult objeto.

O exemplo seguinte imprime o tempo de execução da consulta:

const workspaceId = "<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
  }`
);

Uma vez que a estrutura do statistics payload varia de acordo com a consulta, é utilizado um Record<string, unknown> tipo de retorno. Contém a resposta JSON não processada. As estatísticas encontram-se na query propriedade do JSON. Por exemplo:

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

Incluir visualização

Para obter dados de visualização para consultas de registos com o operador de composição:

  1. Defina a LogsQueryOptions.includeVisualization propriedade como true.
  2. Aceda ao visualization campo dentro do LogsQueryResult objeto.

Por exemplo:

const workspaceId = "<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);

Uma vez que a estrutura do visualization payload varia de acordo com a consulta, é utilizado um Record<string, unknown> tipo de retorno. Contém a resposta JSON não processada. Por exemplo:

{
  "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
}

Consulta de métricas

O exemplo seguinte obtém métricas para uma subscrição do Assistente de Métricas do Azure . O URI do recurso tem de ser o do recurso para o qual as métricas estão a ser consultadas. Normalmente, é do formato /subscriptions/<id>/resourceGroups/<rg-name>/providers/<source>/topics/<resource-name>.

Para localizar o URI do recurso:

  1. Navegue para a página do recurso no portal do Azure.
  2. No painel Descrição geral , selecione a ligação Vista JSON .
  3. No JSON resultante, copie o valor da id propriedade .
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);
});

No exemplo anterior, os resultados das métricas em metricsResponse são ordenados de acordo com a ordem pela qual o utilizador especifica os nomes das métricas no argumento de metricNames matriz da queryResource função. Se o utilizador especificar [firstMetricName, secondMetricName], o resultado de firstMetricName será apresentado antes do resultado secondMetricName de em metricResponse.

Processar resposta de consulta de métricas

A função metrics queryResource devolve um QueryMetricsResult objeto. O QueryMetricsResult objeto contém propriedades como uma lista de Metricobjetos digitados, interval, namespacee timespan. A Metric lista de objetos pode ser acedida com a metrics propriedade . Cada Metric objeto nesta lista contém uma lista de TimeSeriesElement objetos. Cada TimeSeriesElement um contém data e metadataValues propriedades. No formato visual, a hierarquia de objetos da resposta assemelha-se à seguinte estrutura:

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)

Exemplo de processamento de resposta

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

Pode encontrar um exemplo completo aqui.

Métricas de consulta para vários recursos

Para consultar métricas de vários recursos do Azure num único pedido, utilize o MetricsQueryClient.queryResources método . Este método:

  • Chama uma API diferente dos MetricsQueryClient métodos.
  • Requer um ponto final regional ao criar o cliente. Por exemplo, "https://westus3.metrics.monitor.azure.com".

Cada recurso do Azure tem de residir em:

  • A mesma região que o ponto final especificado ao criar o cliente.
  • A mesma subscrição do Azure.

Além disso, o espaço de nomes de métricas que contém as métricas a consultar tem de ser fornecido. Para obter uma lista de espaços de nomes de métricas, veja Métricas suportadas e categorias de registo por tipo de recurso.

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 batchEndPoint: string = "<YOUR_METRICS_ENDPOINT>"; //for example, https://eastus.metrics.monitor.azure.com/

const credential = new DefaultAzureCredential();
const metricsQueryClient: MetricsQueryClient = new MetricsQueryClient(
  batchEndPoint,
  credential
);

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

Para obter um inventário de métricas e dimensões disponíveis para cada tipo de recurso do Azure, veja Métricas suportadas com o Azure Monitor.

Resolução de problemas

Para diagnosticar vários cenários de falha, veja o guia de resolução de problemas.

Passos seguintes

Para saber mais sobre o Azure Monitor, veja a documentação do serviço Azure Monitor.

Contribuir

Se quiser contribuir para esta biblioteca, leia o guia de contribuição para saber mais sobre como criar e testar o código.

Os testes deste módulo são uma mistura de testes em direto e de unidades, que requerem que tenha uma instância do Azure Monitor. Para executar os testes, terá de executar:

  1. rush update
  2. rush build -t @azure/monitor-query
  3. cd into sdk/monitor/monitor-query
  4. Copiar o sample.env ficheiro para .env
  5. Abra o .env ficheiro num editor e preencha os valores.
  6. npm run test.

Para obter mais detalhes, veja a nossa pasta de testes .

Impressões