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

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

  • Protokolle : Erfasst und organisiert Protokoll- und Leistungsdaten aus überwachten Ressourcen. Daten aus verschiedenen Quellen wie Plattformprotokolle von Azure-Diensten, Protokoll- und Leistungsdaten von Agents für virtuelle Computer sowie Nutzungs- und Leistungsdaten aus Apps können in einem einzelnen Azure Log Analytics-Arbeitsbereich konsolidiert werden. Die verschiedenen Datentypen können mithilfe des Kusto-Abfragesprache zusammen analysiert werden.
  • Metriken : Erfasst numerische Daten aus überwachten Ressourcen in einer Zeitreihendatenbank. Metriken sind numerische Werte, die in regelmäßigen Abständen erfasst werden und einen Aspekt eines Systems zu einem bestimmten Zeitpunkt beschreiben. Metriken sind einfach und in der Lage, Szenarien nahezu in Echtzeit zu unterstützen, sodass sie für Warnungen und schnelle Erkennung von Problemen nützlich sind.

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 @azure/monitor-query

Erstellen des Clients

Zum Abfragen von Protokollen oder Metriken ist ein authentifizierter Client erforderlich. 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 Azure Sovereign Cloud

Standardmäßig LogsQueryClient sind und MetricsQueryClient für die Verwendung der öffentlichen Azure-Cloud konfiguriert. Um stattdessen eine Sovereign Cloud zu verwenden, geben Sie das richtige endpoint Argument an. Beispiel:

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

Hinweis: Derzeit MetricsQueryClient wird der Azure Resource Manager -Endpunkt (ARM) zum Abfragen von Metriken verwendet. Sie benötigen den entsprechenden Verwaltungsendpunkt für Ihre Cloud, wenn Sie diesen Client verwenden. Dieses Detail kann sich in Zukunft ändern.

Führen Sie die Abfrage aus.

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

Wichtige Begriffe

Protokollabfrageratenlimits und Drosselung

Der Log Analytics-Dienst wendet eine 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:

  • Zeitpunkt, zu dem der Wert erfasst wurde
  • Die dem Wert zugeordnete Ressource
  • Namespace, der wie eine Kategorie für die Metrik fungiert
  • Metrikname
  • Eigentlicher Wert
  • Einige Metriken weisen mehrere Dimensionen auf, wie in mehrdimensionalen Metriken beschrieben. Benutzerdefinierte Metriken können über bis zu 10 Dimensionen verfügen.

Beispiele

Protokollabfrage

Kann LogsQueryClient verwendet werden, um einen Log Analytics-Arbeitsbereich mithilfe des Kusto-Abfragesprache abzufragen. Der timespan.duration kann als Zeichenfolge in einem ISO 8601-Dauerformat angegeben werden. Sie können die Durations angegebenen Konstanten für einige häufig verwendete ISO 8601-Daueren verwenden.

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

Arbeitsbereichsorientierte Protokollabfrage

Um nach Arbeitsbereichs-ID abzufragen, verwenden Sie 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));

Ressourcenorientierte Protokollabfrage

Im folgenden Beispiel wird veranschaulicht, wie Protokolle direkt von einer Azure-Ressource abfragt werden. Hier wird die queryResource -Methode verwendet, und eine Azure-Ressourcen-ID wird ü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 auf dem 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 von Protokollabfrageantworten

Die queryWorkspace Funktion von LogsQueryClient gibt ein LogsQueryResult Objekt zurück. Der Objekttyp kann oder LogsQueryPartialResultseinLogsQuerySuccessfulResult. Hier sehen Sie 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

Um beispielsweise eine Antwort mit Tabellen zu behandeln:

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 von Protokollbatchabfrageantworten

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 sehen Sie 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 verarbeitet z. B. eine Batchprotokollabfrageantwort:

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.

Szenarien für erweiterte Protokollabfragen

Festlegen des Abfragetimeouts für Protokolle

Die Ausführung einiger Protokollabfragen dauert 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 LogsQueryOptions -Eigenschaft des serverTimeoutInSeconds 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 im workspaceId -Parameter angegebenen Arbeitsbereichs. Die Listenelemente des Parameters können aus den folgenden Bezeichnerformaten bestehen:
    • Qualifizierte Arbeitsbereichsnamen
    • 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 entweder zu sortieren oder sie in der Kusto-Abfrage zu filtern.

Sortieren der Ergebnisse nach TenantId

AppEvents | order by TenantId

Filtern der Ergebnisse nach TenantId

AppEvents | filter TenantId == "<workspace2>"

Ein vollständiges Beispiel finden Sie hier.

Einschließen von Statistiken

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

  1. Setzen Sie die LogsQueryOptions.includeQueryStatistics-Eigenschaft auf true.
  2. Greifen Sie auf das statistics Feld innerhalb des LogsQueryResult -Objekts zu.

Im folgenden Beispiel wird die Abfrageausführungszeit ausgegeben:

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

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 befinden sich in der query -Eigenschaft des JSON-Codes. Beispiel:

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

Einschließen der Visualisierung

So rufen Sie Visualisierungsdaten für Protokollabfragen mithilfe des Renderoperators ab:

  1. Setzen Sie die LogsQueryOptions.includeVisualization-Eigenschaft auf true.
  2. Greifen Sie auf das visualization Feld innerhalb des LogsQueryResult -Objekts zu.

Beispiel:

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

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. 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

Im folgenden Beispiel werden Metriken für ein Azure Metrics Advisor-Abonnement abgerufen. Der Ressourcen-URI muss dem der Ressource entsprechen, für die Metriken abgefragt werden. Sie hat 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 auf dem 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 queryResource Funktion angibt. Wenn der Benutzer angibt [firstMetricName, secondMetricName], wird das Ergebnis für firstMetricName vor dem Ergebnis für secondMetricName in der metricResponseangezeigt.

Verarbeiten der Antwort auf Metrikabfragen

Die Metrikfunktion queryResource gibt ein QueryMetricsResult -Objekt zurück. Das QueryMetricsResult -Objekt enthält Eigenschaften wie eine Liste von Metric-typisierten Objekten, interval, namespaceund timespan. Auf die Metric Objektliste kann über die metrics -Eigenschaft zugegriffen werden. Jedes Metric Objekt in dieser Liste enthält eine Liste von TimeSeriesElement Objekten. Jede TimeSeriesElement enthält data eigenschaften und metadataValues . 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 einer Antwort

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.

Abfragen von Metriken für mehrere Ressourcen

Verwenden Sie die MetricsQueryClient.queryResources -Methode, um Metriken für mehrere Azure-Ressourcen in einer einzelnen Anforderung abzufragen. Diese Methode:

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

Jede Azure-Ressource muss sich in folgendem Speicherort befinden:

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

Darüber hinaus muss der Metriknamespace angegeben werden, der die abzufragten Metriken enthält. Eine Liste der Metriknamespaces finden Sie unter Unterstützte Metriken und Protokollkategorien nach Ressourcentyp.

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

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

Problembehandlung

Informationen zur Diagnose verschiedener Fehlerszenarien finden Sie im Leitfaden zur Problembehandlung.

Nächste Schritte

Weitere Informationen zu Azure Monitor finden Sie in der Dokumentation zum Azure Monitor-Dienst.

Mitwirken

Wenn Sie an dieser Bibliothek mitwirken möchten, lesen Sie die Anleitung für Mitwirkende, um mehr darüber zu erfahren, wie Sie den Code erstellen und testen können.

Die Tests dieses Moduls sind eine Mischung aus Live- und Komponententests, die eine Azure Monitor-instance erfordern. 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 Sie die sample.env Datei in .env
  5. Öffnen Sie die .env Datei in einem Editor, und geben Sie die Werte ein.
  6. npm run test.

Weitere Informationen finden Sie in unserem Testordner .

Aufrufe