Azure Monitor Query-Clientbibliothek für JavaScript – Version 1.3.1

Die Azure Monitor Query-Clientbibliothek wird verwendet, um schreibgeschützte Abfragen für Azure Monitorzwei Datenplattformen auszuführen:

  • Protokolle – Erfasst und organisiert Protokoll- und Leistungsdaten aus überwachten Ressourcen. Daten aus verschiedenen Quellen wie Plattformprotokollen aus Azure-Diensten, Protokoll- und Leistungsdaten von Agents virtueller Computer sowie Nutzungs- und Leistungsdaten aus Apps können in einem einzigen Azure Log Analytics-Arbeitsbereichkonsolidiert werden. Die verschiedenen Datentypen können mithilfe der Kusto Query Languageanalysiert werden.
  • Metriken – Sammelt numerische Daten aus überwachten Ressourcen in einer Zeitreihendatenbank. Metriken sind numerische Werte, die in regelmäßigen Intervallen gesammelt werden und einen bestimmten Aspekt eines Systems beschreiben. Metriken sind leicht und in der Lage, nahezu echtzeitbasierte Szenarien zu unterstützen, sodass sie nützlich sind, um Probleme zu warnen und schnell zu erkennen.

Ressourcen:

Erste Schritte

Unterstützte Umgebungen

Weitere Informationen finden Sie in unserer Supportrichtlinie.

Voraussetzungen

Installieren des Pakets

Installieren Sie die Azure Monitor Query-Clientbibliothek für JavaScript mit npm:

npm install --save @azure/monitor-query

Erstellen des Clients

Ein authentifizierter Client ist erforderlich, um Protokolle oder Metriken abzufragen. Zum Authentifizieren verwendet das folgende Beispiel DefaultAzureCredential- aus dem @azure/Identity--Paket.

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

Konfigurieren des Clients für die souveräne Azure-Cloud

Standardmäßig sind die Clients der Bibliothek für die Verwendung der öffentlichen Azure-Cloud konfiguriert. Um stattdessen eine souveräne Cloud zu verwenden, stellen Sie beim Instanziieren eines Clients den richtigen Endpunkt- und Zielgruppenwert bereit. Zum Beispiel:

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

Hinweis: Derzeit verwendet MetricsQueryClient den Azure Resource Manager (ARM)-Endpunkt zum Abfragen von Metriken. Sie benötigen den entsprechenden Verwaltungsendpunkt für Ihre Cloud, wenn Sie diesen Client verwenden. Diese Details können in Zukunft geändert werden.

Ausführen der Abfrage

Beispiele für Protokolle und Metrikabfragen finden Sie im Abschnitt Beispiele.

Schlüsselkonzepte

Protokolliert Abfrageratenbeschränkungen und -drosselung

Der Log Analytics-Dienst wendet Drosselung an, wenn die Anforderungsrate zu hoch ist. Grenzwerte, z. B. die maximale Anzahl zurückgegebener Zeilen, werden auch auf die Kusto-Abfragen angewendet. Weitere Informationen finden Sie unter Abfrage-API-.

Metrikdatenstruktur

Jeder Satz von Metrikwerten ist eine Zeitreihe mit den folgenden Merkmalen:

  • Der Zeitpunkt, zu dem der Wert erfasst wurde
  • Die Ressource, die dem Wert zugeordnet ist
  • Ein Namespace, der wie eine Kategorie für die Metrik fungiert
  • Ein Metrikname
  • Der Wert selbst
  • Einige Metriken weisen mehrere Dimensionen auf, wie in mehrdimensionalen Metriken beschrieben. Benutzerdefinierte Metriken können bis zu 10 Dimensionen aufweisen.

Beispiele

Protokollabfrage

Die LogsQueryClient können verwendet werden, um einen Log Analytics-Arbeitsbereich mithilfe der Kusto Query Languageabzufragen. Die timespan.duration kann als Zeichenfolge im ISO 8601-Dauerformat angegeben werden. Sie können die Durations Konstanten verwenden, die für einige häufig verwendete ISO 8601-Dauer bereitgestellt werden.

Sie können Protokolle nach Log Analytics-Arbeitsbereichs-ID oder Azure-Ressourcen-ID abfragen. Das Ergebnis wird als Tabelle mit einer Auflistung von Zeilen zurückgegeben.

Abfrage arbeitsbereichorientierter Protokolle

Verwenden Sie zum Abfragen nach Arbeitsbereichs-ID die LogsQueryClient.queryWorkspace-Methode:

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

Abfrage ressourcenorientierter Protokolle

Im folgenden Beispiel wird veranschaulicht, wie Protokolle direkt aus einer Azure-Ressource abgerufen werden. Hier wird die queryResource-Methode verwendet und eine Azure-Ressourcen-ID übergeben. Beispiel: /subscriptions/{subscription-id}/resourceGroups/{resource-group-name}/providers/{resource-provider}/{resource-type}/{resource-name}.

So suchen Sie die Ressourcen-ID:

  1. Navigieren Sie im Azure-Portal zur Seite Ihrer Ressource.
  2. Wählen Sie im Blatt Übersicht den Link JSON-Ansicht aus.
  3. Kopieren Sie im resultierenden JSON-Code den Wert der id-Eigenschaft.
/**
 * @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);
});

Behandeln der Protokollabfrageantwort

Die queryWorkspace-Funktion von LogsQueryClient gibt ein LogsQueryResult-Objekt zurück. Der Objekttyp kann LogsQuerySuccessfulResult oder LogsQueryPartialResultwerden. Hier ist eine Hierarchie der Antwort:

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

So behandeln Sie z. B. eine Antwort mit Tabellen:

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

Ein vollständiges Beispiel finden Sie hier.

Batchprotokollabfrage

Das folgende Beispiel veranschaulicht das gleichzeitige Senden mehrerer Abfragen mithilfe der Batchabfrage-API. Die Abfragen können als Liste von BatchQuery Objekten dargestellt werden.

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

Behandeln der Batchabfrageantwort für Protokolle

Die queryBatch-Funktion von LogsQueryClient gibt ein LogsQueryBatchResult-Objekt zurück. LogsQueryBatchResult enthält eine Liste von Objekten mit den folgenden möglichen Typen:

  • LogsQueryPartialResult
  • LogsQuerySuccessfulResult
  • LogsQueryError

Hier ist eine Hierarchie der Antwort:

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

Der folgende Code behandelt beispielsweise eine Abfrageantwort für Batchprotokolle:

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

Ein vollständiges Beispiel finden Sie hier.

Erweiterte Protokollabfrageszenarien

Festlegen des Protokollabfragetimeouts

Einige Protokollabfragen dauern länger als 3 Minuten. Das Standardmäßige Servertimeout beträgt 3 Minuten. Sie können das Servertimeout auf maximal 10 Minuten erhöhen. Im folgenden Beispiel wird die serverTimeoutInSeconds Eigenschaft des LogsQueryOptions Objekts verwendet, um das Servertimeout auf 10 Minuten zu erhöhen:

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

Abfragen mehrerer Arbeitsbereiche

Dieselbe Protokollabfrage kann in mehreren Log Analytics-Arbeitsbereichen ausgeführt werden. Zusätzlich zur Kusto-Abfrage sind die folgenden Parameter erforderlich:

  • workspaceId – Die erste (primäre) Arbeitsbereichs-ID.
  • additionalWorkspaces – Eine Liste von Arbeitsbereichen, mit Ausnahme des Arbeitsbereichs, der im parameter workspaceId angegeben ist. Die Listenelemente des Parameters können aus den folgenden Bezeichnerformaten bestehen:
    • Namen qualifizierter Arbeitsbereiche
    • Arbeitsbereichs-IDs
    • Azure-Ressourcen-IDs

Die folgende Abfrage wird beispielsweise in drei Arbeitsbereichen ausgeführt:

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

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

Um die Ergebnisse für jeden Arbeitsbereich anzuzeigen, verwenden Sie die TenantId Spalte, um die Ergebnisse zu sortieren oder in der Kusto-Abfrage zu filtern.

Bestellergebnisse nach TenantId-

AppEvents | order by TenantId

Filtern von Ergebnissen nach TenantId-

AppEvents | filter TenantId == "<workspace2>"

Ein vollständiges Beispiel finden Sie hier.

Statistiken einschließen

So rufen Sie Protokollabfrageausführungsstatistiken ab, z. B. CPU- und Arbeitsspeicherverbrauch:

  1. Legen Sie die LogsQueryOptions.includeQueryStatistics-Eigenschaft auf truefest.
  2. Zugreifen auf das statistics-Feld innerhalb des LogsQueryResult-Objekts.

Im folgenden Beispiel wird die Abfrageausführungszeit gedruckt:

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

Da die Struktur der statistics Nutzlast je nach Abfrage variiert, wird ein Record<string, unknown> Rückgabetyp verwendet. Sie enthält die unformatierte JSON-Antwort. Die Statistiken werden in der query-Eigenschaft des JSON-Codes gefunden. Zum Beispiel:

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

Visualisierung einschließen

So rufen Sie Visualisierungsdaten für Protokollabfragen mithilfe des Renderoperatorsab:

  1. Legen Sie die LogsQueryOptions.includeVisualization-Eigenschaft auf truefest.
  2. Zugreifen auf das visualization-Feld innerhalb des LogsQueryResult-Objekts.

Zum Beispiel:

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

Da die Struktur der visualization Nutzlast je nach Abfrage variiert, wird ein Record<string, unknown> Rückgabetyp verwendet. Sie enthält die unformatierte JSON-Antwort. Zum Beispiel:

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

Metrikabfrage

Das folgende Beispiel ruft Metriken für ein Azure Metrics Advisor Abonnement ab. Der Ressourcen-URI muss die Ressource sein, für die Metriken abgefragt werden. Es ist normalerweise das Format /subscriptions/<id>/resourceGroups/<rg-name>/providers/<source>/topics/<resource-name>.

So suchen Sie den Ressourcen-URI:

  1. Navigieren Sie im Azure-Portal zur Seite Ihrer Ressource.
  2. Wählen Sie im Blatt Übersicht den Link JSON-Ansicht aus.
  3. Kopieren Sie im resultierenden JSON-Code den Wert der id-Eigenschaft.
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);
});

Im vorherigen Beispiel werden die Metrikergebnisse in metricsResponse entsprechend der Reihenfolge sortiert, in der der Benutzer die Metriknamen im metricNames Arrayargument für die funktion queryResource angibt. Wenn der Benutzer [firstMetricName, secondMetricName]angibt, wird das Ergebnis für firstMetricName vor dem Ergebnis für secondMetricName im metricResponseangezeigt.

Behandeln der Abfrageantwort für Metriken

Die Metriken queryResource Funktion gibt ein QueryMetricsResult-Objekt zurück. Das QueryMetricsResult-Objekt enthält Eigenschaften wie eine Liste der Metric-typd-Objekte, interval, namespaceund timespan. Auf die Liste der Metric Objekte kann mithilfe der eigenschaft metrics zugegriffen werden. Jedes Metric-Objekt in dieser Liste enthält eine Liste von TimeSeriesElement Objekten. Jede TimeSeriesElement enthält data- und metadataValues Eigenschaften. In visueller Form ähnelt die Objekthierarchie der Antwort der folgenden Struktur:

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)

Beispiel für die Behandlung von Antworten

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

Ein vollständiges Beispiel finden Sie hier.

Abfragemetriken für mehrere Ressourcen

Um Metriken für mehrere Azure-Ressourcen in einer einzigen Anforderung abzufragen, verwenden Sie die MetricsClient.queryResources-Methode. Diese Methode:

  • Ruft eine andere API als die MetricsClient Methoden auf.
  • Erfordert einen regionalen Endpunkt beim Erstellen des Clients. Beispiel: "https://westus3.metrics.monitor.azure.com".

Jede Azure-Ressource muss sich in:

  • Derselbe Bereich wie der Endpunkt, der beim Erstellen des Clients angegeben wurde.
  • Dasselbe Azure-Abonnement.

Außerdem:

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

Eine Bestandsaufnahme der Metriken und Dimensionen, die für jeden Azure-Ressourcentyp verfügbar sind, finden Sie unter Unterstützte Metriken mit Azure Monitor.

Fehlerbehebung

Informationen zum Diagnostizieren verschiedener Fehlerszenarien finden Sie im Anleitung zur Problembehandlung.

Nächste Schritte

Weitere Informationen zu Azure Monitor finden Sie in der Azure Monitor-Dienstdokumentation.

Beitragend

Wenn Sie an dieser Bibliothek mitwirken möchten, lesen Sie bitte den mitwirkenden Leitfaden, um mehr über das Erstellen und Testen des Codes zu erfahren.

Die Tests dieses Moduls sind eine Mischung aus Live- und Komponententests, die erfordern, dass Sie über eine Azure Monitor-Instanz verfügen. Um die Tests auszuführen, müssen Sie Folgendes ausführen:

  1. rush update
  2. rush build -t @azure/monitor-query
  3. cd into sdk/monitor/monitor-query
  4. Kopieren der sample.env-Datei in .env
  5. Öffnen Sie die .env Datei in einem Editor, und füllen Sie die Werte aus.
  6. npm run test.

Weitere Details erhalten Sie in unseren Tests Ordner.

Aufrufe