Freigeben über


Azure Monitor-Abfrageprotokolle-Clientbibliothek für JavaScript – Version 1.0.0

Die Azure Monitor-Abfrageprotokolle-Clientbibliothek wird zum Ausführen schreibgeschützter Abfragen für die Protokolldatenplattform von Azure Monitor verwendet:

  • Protokolle : Sammelt und organisiert Protokoll- und Leistungsdaten von überwachten Ressourcen. Daten aus verschiedenen Quellen, z. B. Plattformprotokolle von Azure-Diensten, Protokoll- und Leistungsdaten von VM-Agents sowie Nutzungs- und Leistungsdaten von Apps, können in einem einzelnen Azure Log Analytics-Arbeitsbereich konsolidiert werden. Die verschiedenen Datentypen können gemeinsam mit der Kusto Query Language analysiert werden.

Migrieren von @azure/monitor-query Advisory ⚠️

Im Migrationshandbuch finden Sie detaillierte Anweisungen, wie Sie Ihren Anwendungscode vom Originalpaket @azure/monitor-query in die @azure/monitor-query-logs Bibliothek aktualisieren können.

Ressourcen:

Erste Schritte

Unterstützte Umgebungen

Weitere Informationen finden Sie in unserer Supportrichtlinie.

Voraussetzungen

Installiere das Paket

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

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

Erstellen des Clients

Für die Abfrage von Protokollen ist ein authentifizierter Client erforderlich. Für die Authentifizierung wird im folgenden Beispiel DefaultAzureCredential aus dem @azure/identity-Paket verwendet.

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

const credential = new DefaultAzureCredential();

// Create a LogsQueryClient
const logsQueryClient = new LogsQueryClient(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. Beispiel:

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

Ausführen der Abfrage

Beispiele für Logs-Abfragen finden Sie im Abschnitt Beispiele .

Wichtige Begriffe

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.

Beispiele

Protokollabfrage

Die LogsQueryClient kann verwendet werden, um einen Log Analytics-Arbeitsbereich mithilfe der Kusto-Abfragesprache abzufragen. Die timespan.duration kann als Zeichenfolge in einem ISO 8601-Format für die Dauer angegeben werden. Sie können die Konstanten verwenden, die Durations für einige häufig verwendete ISO 8601-Dauern 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 die LogsQueryClient.queryWorkspace Methode, um eine Abfrage nach Arbeitsbereichs-ID durchzuführen:

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

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

Behandeln der Protokollabfrageantwort

Die queryWorkspace Funktion von LogsQueryClient gibt ein LogsQueryResult Objekt zurück. Der Objekttyp kann oder sein LogsQuerySuccessfulResultLogsQueryPartialResult. 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:

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

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.

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

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:

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

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 Eigenschaft des LogsQueryOptions Objekts serverTimeoutInSeconds verwendet, um das Servertimeout auf 10 Minuten zu erhöhen:

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;

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) Workspace-ID.
  • additionalWorkspaces - Eine Liste von Arbeitsbereichen, mit Ausnahme des im Parameter angegebenen workspaceId Arbeitsbereichs. 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:

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;

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

Sortieren Sie die Ergebnisse nach TenantId

AppEvents | order by TenantId

Filtern der Ergebnisse 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 true fest.
  2. Greifen Sie auf das statistics Feld innerhalb des Objekts LogsQueryResult zu.

Im folgenden Beispiel wird die Abfrageausführungszeit gedruckt:

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

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 von JSON. Beispiel:

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

Visualisierung einschließen

So rufen Sie Visualisierungsdaten für Protokollabfragen mit dem render-Operator ab:

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

Beispiel:

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

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
}

Problembehandlung

Informationen zum Diagnostizieren 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.

Mitarbeit

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-logs
  3. cd into sdk/monitor/monitor-query
  4. Kopieren Sie die sample.env Datei nach .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 .