Biblioteka klienta zapytań usługi Azure Monitor dla języka JavaScript — wersja 1.3.1
Biblioteka klienta zapytań usługi Azure Monitor służy do wykonywania zapytań tylko do odczytu na dwóch platform danych usługi Azure Monitor:
- Logs — zbiera i organizuje dane dziennika i wydajności z monitorowanych zasobów. Dane z różnych źródeł, takich jak dzienniki platformy z usług platformy Azure, dane dzienników i wydajności agentów maszyn wirtualnych, a dane użycia i wydajności z aplikacji można skonsolidować w jednym obszarze roboczym usługi Azure Log Analytics. Różne typy danych można analizować razem przy użyciu języka zapytań Kusto.
- Metrics — zbiera dane liczbowe z monitorowanych zasobów do bazy danych szeregów czasowych. Metryki to wartości liczbowe, które są zbierane w regularnych odstępach czasu i opisują jakiś aspekt systemu w określonym czasie. Metryki są lekkie i mogą obsługiwać scenariusze niemal w czasie rzeczywistym, co ułatwia alerty i szybkie wykrywanie problemów.
zasoby :
- kod źródłowy
- pakiet (npm)
- Dokumentacja referencyjna interfejs u API
- dokumentacja usługi Service
- przykładów
- dziennika zmian
Wprowadzenie
Obsługiwane środowiska
- wersje Node.js LTS
- Najnowsze wersje przeglądarek Safari, Chrome, Microsoft Edge i Firefox
Aby uzyskać więcej informacji, zobacz nasze zasady pomocy technicznej .
Warunki wstępne
- subskrypcji platformy Azure
- Implementacja TokenCredential, taka jak typ poświadczeń biblioteki tożsamości platformy Azure.
- Aby wykonać zapytanie dotyczące dzienników, potrzebne są następujące elementy:
- Do wykonywania zapytań dotyczących metryk potrzebny jest zasób platformy Azure dowolnego rodzaju (konto magazynu, usługa Key Vault, usługa Cosmos DB itp.).
Instalowanie pakietu
Zainstaluj bibliotekę klienta zapytań usługi Azure Monitor dla języka JavaScript za pomocą narzędzia npm:
npm install --save @azure/monitor-query
Tworzenie klienta
Uwierzytelniony klient jest wymagany do wykonywania zapytań dotyczących dzienników lub metryk. W celu uwierzytelnienia w poniższym przykładzie użyto
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);
Konfigurowanie klienta dla suwerennej chmury platformy Azure
Domyślnie klienci biblioteki są skonfigurowani do korzystania z chmury publicznej platformy Azure. Aby zamiast tego użyć suwerennej chmury, podaj prawidłową wartość punktu końcowego i odbiorców podczas tworzenia wystąpienia klienta. Na przykład:
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",
});
Uwaga: obecnie MetricsQueryClient
używa punktu końcowego usługi Azure Resource Manager (ARM) do wykonywania zapytań dotyczących metryk. Potrzebny jest odpowiedni punkt końcowy zarządzania dla chmury podczas korzystania z tego klienta. Te szczegóły mogą ulec zmianie w przyszłości.
Wykonywanie zapytania
Przykłady zapytań dzienników i metryk można znaleźć w sekcji przykłady .
Kluczowe pojęcia
Rejestruje limity szybkości zapytań i ograniczanie przepustowości
Usługa Log Analytics stosuje ograniczanie przepustowości, gdy szybkość żądań jest zbyt wysoka. Limity, takie jak maksymalna liczba zwracanych wierszy, są również stosowane w zapytaniach Kusto. Aby uzyskać więcej informacji, zobacz Interfejs API zapytań.
Struktura danych metryk
Każdy zestaw wartości metryk jest szeregiem czasowym o następujących cechach:
- Czas zbierania wartości
- Zasób skojarzony z wartością
- Przestrzeń nazw, która działa jak kategoria dla metryki
- Nazwa metryki
- Sama wartość
- Niektóre metryki mają wiele wymiarów zgodnie z opisem w metrykach wielowymiarowych. Metryki niestandardowe mogą mieć maksymalnie 10 wymiarów.
Przykłady
-
dzienników - zapytań dotyczących dzienników usługi Batch
- zaawansowane scenariusze zapytań dzienników
- Zapytania metryk
Zapytanie dotyczące dzienników
Za pomocą LogsQueryClient
można wykonywać zapytania dotyczące obszaru roboczego usługi Log Analytics przy użyciu języka zapytań Kusto.
timespan.duration
można określić jako ciąg w formacie czasu trwania ISO 8601. Możesz użyć stałych Durations
dostępnych dla niektórych powszechnie używanych czasów trwania ISO 8601.
Możesz wykonywać zapytania dotyczące dzienników według identyfikatora obszaru roboczego usługi Log Analytics lub identyfikatora zasobu platformy Azure. Wynik jest zwracany jako tabela z kolekcją wierszy.
Zapytanie dotyczące dzienników skoncentrowanych na obszarze roboczym
Aby wykonywać zapytania według identyfikatora obszaru roboczego, użyj metody LogsQueryClient.queryWorkspace
:
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));
Zapytanie dotyczące dzienników skoncentrowanych na zasobach
W poniższym przykładzie pokazano, jak wykonywać zapytania dotyczące dzienników bezpośrednio z zasobu platformy Azure. W tym miejscu jest używana metoda queryResource
, a identyfikator zasobu platformy Azure jest przekazywany. Na przykład /subscriptions/{subscription-id}/resourceGroups/{resource-group-name}/providers/{resource-provider}/{resource-type}/{resource-name}
.
Aby znaleźć identyfikator zasobu:
- Przejdź do strony zasobu w witrynie Azure Portal.
- W bloku Przegląd wybierz link Widok JSON.
- W wynikowym formacie JSON skopiuj wartość właściwości
id
.
/**
* @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);
});
Obsługa odpowiedzi na zapytania dotyczące dzienników
Funkcja queryWorkspace
LogsQueryClient
zwraca obiekt LogsQueryResult
. Typ obiektu może być LogsQuerySuccessfulResult
lub LogsQueryPartialResult
. Oto hierarchia odpowiedzi:
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
Aby na przykład obsłużyć odpowiedź z tabelami:
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);
}
}
}
Pełny przykład można znaleźć tutaj.
Zapytanie dotyczące dzienników wsadowych
W poniższym przykładzie pokazano wysyłanie wielu zapytań jednocześnie przy użyciu interfejsu API zapytań wsadowych. Zapytania mogą być reprezentowane jako lista obiektów BatchQuery
.
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);
}
}
}
Obsługa odpowiedzi zapytania wsadowego dzienników
Funkcja queryBatch
LogsQueryClient
zwraca obiekt LogsQueryBatchResult
.
LogsQueryBatchResult
zawiera listę obiektów z następującymi możliwymi typami:
LogsQueryPartialResult
LogsQuerySuccessfulResult
LogsQueryError
Oto hierarchia odpowiedzi:
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")
Na przykład następujący kod obsługuje odpowiedź zapytania dzienników wsadowych:
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);
}
}
}
Pełny przykład można znaleźć tutaj.
Zaawansowane scenariusze zapytań dzienników
Ustawianie limitu czasu zapytania dzienników
Wykonanie niektórych zapytań dzienników trwa dłużej niż 3 minuty. Domyślny limit czasu serwera wynosi 3 minuty. Limit czasu serwera można zwiększyć do maksymalnie 10 minut. W poniższym przykładzie właściwość serverTimeoutInSeconds
obiektu LogsQueryOptions
służy do zwiększenia limitu czasu serwera do 10 minut:
// 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;
Wykonywanie zapytań dotyczących wielu obszarów roboczych
To samo zapytanie dzienników można wykonać w wielu obszarach roboczych usługi Log Analytics. Oprócz zapytania Kusto wymagane są następujące parametry:
-
workspaceId
— pierwszy (podstawowy) identyfikator obszaru roboczego. -
additionalWorkspaces
— lista obszarów roboczych z wyłączeniem obszaru roboczego podanego w parametrzeworkspaceId
. Elementy listy parametru mogą składać się z następujących formatów identyfikatorów:- Kwalifikowane nazwy obszarów roboczych
- Identyfikatory obszarów roboczych
- Identyfikatory zasobów platformy Azure
Na przykład następujące zapytanie jest wykonywane w trzech obszarach roboczych:
const queryLogsOptions: LogsQueryOptions = {
additionalWorkspaces: ["<workspace2>", "<workspace3>"],
};
const kustoQuery = "AppEvents | limit 10";
const result = await logsQueryClient.queryWorkspace(
azureLogAnalyticsWorkspaceId,
kustoQuery,
{ duration: Durations.twentyFourHours },
queryLogsOptions,
);
Aby wyświetlić wyniki dla każdego obszaru roboczego, użyj kolumny TenantId
, aby uporządkować wyniki lub filtrować je w zapytaniu Kusto.
order results by TenantId
AppEvents | order by TenantId
Filtruj wyniki według identyfikatora dzierżawy
AppEvents | filter TenantId == "<workspace2>"
Pełny przykład można znaleźć tutaj.
Uwzględnij statystyki
Aby uzyskać statystyki wykonywania zapytań dzienników, takie jak użycie procesora CPU i pamięci:
- Ustaw właściwość
LogsQueryOptions.includeQueryStatistics
na wartośćtrue
. - Uzyskaj dostęp do pola
statistics
wewnątrz obiektuLogsQueryResult
.
Poniższy przykład wyświetla czas wykonywania zapytania:
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
}`,
);
Ponieważ struktura ładunku statistics
różni się w zależności od zapytania, używany jest Record<string, unknown>
zwracany typ. Zawiera on nieprzetworzoną odpowiedź JSON. Statystyki znajdują się w query
właściwości JSON. Na przykład:
{
"query": {
"executionTime": 0.0156478,
"resourceUsage": {...},
"inputDatasetStatistics": {...},
"datasetStatistics": [{...}]
}
}
Uwzględnij wizualizację
Aby uzyskać dane wizualizacji dla zapytań dzienników przy użyciu operatora renderowania :
- Ustaw właściwość
LogsQueryOptions.includeVisualization
na wartośćtrue
. - Uzyskaj dostęp do pola
visualization
wewnątrz obiektuLogsQueryResult
.
Na przykład:
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);
Ponieważ struktura ładunku visualization
różni się w zależności od zapytania, używany jest Record<string, unknown>
zwracany typ. Zawiera on nieprzetworzoną odpowiedź JSON. Na przykład:
{
"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
}
Zapytanie metryk
Poniższy przykład pobiera metryki dla subskrypcji usługi Azure Metrics Advisor.
Identyfikator URI zasobu musi być identyfikatorem zasobu, dla którego są wykonywane zapytania dotyczące metryk. Zwykle jest to format /subscriptions/<id>/resourceGroups/<rg-name>/providers/<source>/topics/<resource-name>
.
Aby znaleźć identyfikator URI zasobu:
- Przejdź do strony zasobu w witrynie Azure Portal.
- W bloku Przegląd wybierz link Widok JSON.
- W wynikowym formacie JSON skopiuj wartość właściwości
id
.
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);
});
W poprzednim przykładzie wyniki metryki w metricsResponse
są uporządkowane zgodnie z kolejnością, w której użytkownik określa nazwy metryk w metricNames
argument tablicy dla funkcji queryResource
. Jeśli użytkownik określi [firstMetricName, secondMetricName]
, wynik firstMetricName
pojawi się przed wynikiem secondMetricName
w metricResponse
.
Obsługa odpowiedzi na zapytanie metryk
Funkcja queryResource
metrics zwraca obiekt QueryMetricsResult
. Obiekt QueryMetricsResult
zawiera właściwości, takie jak lista obiektów typu Metric
, interval
, namespace
i timespan
. Dostęp do listy obiektów Metric
można uzyskać przy użyciu właściwości metrics
. Każdy obiekt Metric
na tej liście zawiera listę obiektów TimeSeriesElement
. Każdy TimeSeriesElement
zawiera właściwości data
i metadataValues
. W formie wizualizacji hierarchia obiektów odpowiedzi przypomina następującą 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)
Przykład obsługi odpowiedzi
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);
});
Pełny przykład można znaleźć tutaj.
Wykonywanie zapytań dotyczących metryk dla wielu zasobów
Aby wysyłać zapytania o metryki dla wielu zasobów platformy Azure w jednym żądaniu, użyj metody MetricsClient.queryResources
. Ta metoda:
- Wywołuje inny interfejs API niż metody
MetricsClient
. - Wymaga regionalnego punktu końcowego podczas tworzenia klienta. Na przykład "https://westus3.metrics.monitor.azure.com".
Każdy zasób platformy Azure musi znajdować się w:
- Ten sam region co punkt końcowy określony podczas tworzenia klienta.
- Ta sama subskrypcja platformy Azure.
Ponadto:
- Użytkownik musi mieć uprawnienia do odczytywania danych monitorowania na poziomie subskrypcji platformy Azure. Na przykład rola czytelnika monitorowania w subskrypcji do odpytowania.
- Należy podać przestrzeń nazw metryki zawierającej metryki do wykonania zapytania. Aby uzyskać listę przestrzeni nazw metryk, zobacz Obsługiwane metryki i kategorie dzienników według typu zasobu.
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
);
Aby uzyskać spis metryk i wymiarów dostępnych dla każdego typu zasobu platformy Azure, zobacz Obsługiwane metryki za pomocą usługi Azure Monitor.
Rozwiązywanie problemów
Aby zdiagnozować różne scenariusze błędów, zobacz przewodnik rozwiązywania problemów .
Następne kroki
Aby dowiedzieć się więcej na temat usługi Azure Monitor, zobacz dokumentację usługi Azure Monitor.
Przyczyniając się
Jeśli chcesz współtworzyć tę bibliotekę, przeczytaj przewodnik dotyczący współtworzenia , aby dowiedzieć się więcej na temat tworzenia i testowania kodu.
Testy tego modułu to mieszanka testów na żywo i testów jednostkowych, które wymagają posiadania wystąpienia usługi Azure Monitor. Aby wykonać testy, należy uruchomić następujące polecenie:
rush update
rush build -t @azure/monitor-query
cd into sdk/monitor/monitor-query
- Kopiowanie pliku
sample.env
do.env
- Otwórz plik
.env
w edytorze i wypełnij wartości. -
npm run test
.
Aby uzyskać więcej informacji, zobacz nasze testy folderze.
Powiązane projekty
- zestaw SDK platformy Microsoft Azure dla języka JavaScript
- usługi Azure Monitor
Azure SDK for JavaScript