Partager via


Bibliothèque cliente des journaux de requêtes Azure Monitor pour JavaScript - version 1.0.0

La bibliothèque cliente Journaux des requêtes Azure Monitor est utilisée pour exécuter des requêtes en lecture seule sur la plateforme de données Journaux d’Azure Monitor :

  • Journaux : collecte et organise les données de journal et de performance des ressources surveillées. Les données provenant de différentes sources, telles que les journaux de plateforme des services Azure, les données de journal et de performances des agents de machines virtuelles et les données d’utilisation et de performances des applications, peuvent être consolidées dans un seul espace de travail Azure Log Analytics. Les différents types de données peuvent être analysés ensemble à l’aide du langage de requête Kusto.

Migration à partir de l’avis @azure/monitor-query⚠️

Consultez le Guide de migration pour obtenir des instructions détaillées sur la mise à jour du code de votre application du package d’origine @azure/monitor-query vers la @azure/monitor-query-logs bibliothèque.

Ressources :

Mise en route

Environnements pris en charge

Pour plus d’informations, consultez notre politique d’assistance.

Conditions préalables

Installer le package

Installez la bibliothèque cliente requête Azure Monitor pour JavaScript avec npm :

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

Créer le client

Un client authentifié est requis pour interroger les journaux. Pour s’authentifier, l’exemple suivant utilise DefaultAzureCredential à partir du package @azure/identity .

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

const credential = new DefaultAzureCredential();

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

Configurer le client pour le cloud souverain Azure

Par défaut, les clients de la bibliothèque sont configurés pour utiliser le cloud public Azure. Pour utiliser un cloud souverain à la place, fournissez le point de terminaison et la valeur d’audience appropriés lors de l’instanciation d’un client. Par exemple:

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

Exécuter la requête

Pour obtenir des exemples de requêtes Logs, consultez la section Exemples .

Concepts clés

Journaux des limites et limitation du taux de requête

Le service log Analytique applique la limitation lorsque le taux de requêtes est trop élevé. Les limites, telles que le nombre maximal de lignes retournées, sont également appliquées aux requêtes Kusto. Pour plus d’informations, consultez API de requête.

Exemples

Requête journaux

Le LogsQueryClient peut être utilisé pour interroger un espace de travail Log Analytics à l’aide du langage de requête Kusto. Le timespan.duration peut être spécifié sous la forme d’une chaîne dans un format de durée ISO 8601. Vous pouvez utiliser les Durations constantes fournies pour certaines durées ISO 8601 couramment utilisées.

Vous pouvez interroger les journaux par ID d’espace de travail log Analytique ou ID de ressource Azure. Le résultat est retourné sous la forme d’une table avec une collection de lignes.

Requête des journaux centrés sur l’espace de travail

Pour effectuer une requête par ID d’espace de travail, utilisez la LogsQueryClient.queryWorkspace méthode suivante :

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

Requête des journaux centrés sur les ressources

L’exemple suivant montre comment interroger les journaux directement à partir d’une ressource Azure. Ici, la queryResource méthode est utilisée et un ID de ressource Azure est transmis. Par exemple : /subscriptions/{subscription-id}/resourceGroups/{resource-group-name}/providers/{resource-provider}/{resource-type}/{resource-name}.

Pour trouver l’ID de ressource :

  1. Accédez à la page de votre ressource dans le portail Azure.
  2. Dans le panneau Vue d’ensemble , sélectionnez le lien Vue JSON .
  3. Dans le JSON résultant, copiez la valeur de la id propriété.
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);
  }
}

Gérer la réponse de requête des journaux

La queryWorkspace fonction de LogsQueryClient renvoie un LogsQueryResult objet. Le type d’objet peut être LogsQuerySuccessfulResult ou LogsQueryPartialResult. Voici une hiérarchie de la réponse :

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

Par exemple, pour gérer une réponse avec des tables :

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

Un échantillon complet peut être trouvé ici.

Requête des journaux batch

L’exemple suivant illustre l’envoi de plusieurs requêtes en même temps à l’aide de l’API de requête batch. Les requêtes peuvent être représentées sous la forme d’une liste d’objets BatchQuery .

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

const monitorWorkspaceId = "<workspace_id>";

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

const kqlQuery = "AppEvents | project TimeGenerated, Name, AppRoleInstance | limit 1";
const queriesBatch = [
  {
    workspaceId: monitorWorkspaceId,
    query: kqlQuery,
    timespan: { duration: "P1D" },
  },
  {
    workspaceId: monitorWorkspaceId,
    query: "AzureActivity | summarize count()",
    timespan: { duration: "PT1H" },
  },
  {
    workspaceId: monitorWorkspaceId,
    query:
      "AppRequests | take 10 | summarize avgRequestDuration=avg(DurationMs) by bin(TimeGenerated, 10m), _ResourceId",
    timespan: { duration: "PT1H" },
  },
  {
    workspaceId: monitorWorkspaceId,
    query: "AppRequests | take 2",
    timespan: { duration: "PT1H" },
    includeQueryStatistics: true,
  },
];

const result = await logsQueryClient.queryBatch(queriesBatch);

if (result == null) {
  throw new Error("No response for query");
}

let i = 0;
for (const response of result) {
  console.log(`Results for query with query: ${queriesBatch[i]}`);
  if (response.status === LogsQueryResultStatus.Success) {
    console.log(
      `Printing results from query '${queriesBatch[i].query}' for '${queriesBatch[i].timespan}'`,
    );
    processTables(response.tables);
  } else if (response.status === LogsQueryResultStatus.PartialFailure) {
    console.log(
      `Printing partial results from query '${queriesBatch[i].query}' for '${queriesBatch[i].timespan}'`,
    );
    processTables(response.partialTables);
    console.log(
      ` Query had errors:${response.partialError.message} with code ${response.partialError.code}`,
    );
  } else {
    console.log(`Printing errors from query '${queriesBatch[i].query}'`);
    console.log(` Query had errors:${response.message} with code ${response.code}`);
  }
  // next query
  i++;
}

Gérer la réponse aux requêtes par lots des journaux

La queryBatch fonction de LogsQueryClient renvoie un LogsQueryBatchResult objet. LogsQueryBatchResult Contient une liste d’objets avec les types possibles suivants :

  • LogsQueryPartialResult
  • LogsQuerySuccessfulResult
  • LogsQueryError

Voici une hiérarchie de la réponse :

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

Par exemple, le code suivant gère une réponse de requête des journaux de traitement par lots :

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

Un échantillon complet peut être trouvé ici.

Scénarios de requête de journaux avancés

Définir le délai d’expiration de la requête des journaux

Certaines requêtes de journaux prennent plus de 3 minutes pour s’exécuter. Le délai d’expiration du serveur par défaut est de 3 minutes. Vous pouvez augmenter le délai d’expiration du serveur à un maximum de 10 minutes. Dans l’exemple suivant, la propriété de LogsQueryOptions l’objet serverTimeoutInSeconds est utilisée pour augmenter le délai d’expiration du serveur à 10 minutes :

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;

Interroger plusieurs espaces de travail

La même requête de journaux d’activité peut être exécutée sur plusieurs espaces de travail log Analytique. Outre la requête Kusto, les paramètres suivants sont requis :

  • workspaceId - Le premier ID d’espace de travail (principal).
  • additionalWorkspaces - Une liste d’espaces de travail, à l’exclusion de l’espace de travail fourni dans le workspaceId paramètre. Les éléments de liste du paramètre peuvent se composer des formats d’identificateur suivants :
    • Noms d’espaces de travail qualifiés
    • ID d’espace de travail
    • ID de ressources Azure

Par exemple, la requête suivante s’exécute dans trois espaces de travail :

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;

Pour afficher les résultats de chaque espace de travail, utilisez la TenantId colonne pour trier les résultats ou les filtrer dans la requête Kusto.

Trier les résultats par TenantId

AppEvents | order by TenantId

Filtrer les résultats par TenantId

AppEvents | filter TenantId == "<workspace2>"

Un échantillon complet peut être trouvé ici.

Inclure des statistiques

Pour obtenir les statistiques d’exécution des requêtes de journaux, telles que la consommation du processeur et de la mémoire :

  1. Attribuez à la propriété LogsQueryOptions.includeQueryStatistics la valeur true.
  2. Accédez au champ à l’intérieur statistics de l’objet LogsQueryResult .

L’exemple suivant imprime l’heure d’exécution de la requête :

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

Étant donné que la structure de la charge utile varie d’une requête à l’autre statistics , un type de Record<string, unknown> retour est utilisé. Il contient la réponse JSON brute. Les statistiques se trouvent dans la query propriété du JSON. Par exemple:

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

Inclure la visualisation

Pour obtenir des données de visualisation pour les requêtes de journaux à l’aide de l’opérateur render :

  1. Attribuez à la propriété LogsQueryOptions.includeVisualization la valeur true.
  2. Accédez au champ à l’intérieur visualization de l’objet LogsQueryResult .

Par exemple:

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

Étant donné que la structure de la charge utile varie d’une requête à l’autre visualization , un type de Record<string, unknown> retour est utilisé. Il contient la réponse JSON brute. Par exemple:

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

Résolution des problèmes

Pour diagnostiquer divers scénarios de défaillance, consultez le guide de dépannage.

Étapes suivantes

Pour en savoir plus sur Azure Monitor, consultez la documentation du service Azure Monitor.

Contribuer

Si vous souhaitez contribuer à cette bibliothèque, lisez le guide de contribution pour en savoir plus sur la génération et le test du code.

Les tests de ce module sont un mélange de tests en direct et unitaires, ce qui vous oblige à disposer d’une instance Azure Monitor. Pour exécuter les tests, vous devez exécuter :

  1. rush update
  2. rush build -t @azure/monitor-query-logs
  3. cd into sdk/monitor/monitor-query
  4. Copiez le sample.env fichier dans .env
  5. Ouvrez le .env fichier dans un éditeur et remplissez les valeurs.
  6. npm run test.

Pour plus de détails, consultez notre dossier de tests .