Biblioteka klienta zapytań usługi Azure Monitor dla języka JavaScript — wersja 1.2.0
Biblioteka klienta zapytań usługi Azure Monitor służy do wykonywania zapytań tylko do odczytu na dwóch platformach danych usługi Azure Monitor:
- Dzienniki — zbiera i organizuje dane dzienników 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ęzyk zapytań Kusto.
- Metryki — 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 interfejsu API
- Dokumentacja usługi
- Samples
- Dziennik zmian
Wprowadzenie
Obsługiwane środowiska
- Wersje LTS Node.js
- Najnowsze wersje przeglądarek Safari, Chrome, Microsoft Edge i Firefox
Aby uzyskać więcej informacji, zobacz nasze zasady pomocy technicznej.
Wymagania wstępne
- Subskrypcja platformy Azure
- Implementacja TokenCredential , taka jak typ poświadczeń biblioteki tożsamości platformy Azure.
- Do wykonywania zapytań dotyczących dzienników potrzebne są następujące elementy:
- Obszar roboczy usługi Azure Log Analytics
- Zasób platformy Azure dowolnego rodzaju (konto magazynu, Key Vault, cosmos DB itp.)
- Do wykonywania zapytań dotyczących metryk potrzebny jest zasób platformy Azure dowolnego rodzaju (konto magazynu, Key Vault, usługa Cosmos DB itp.).
Instalowanie pakietu
Zainstaluj bibliotekę klienta zapytań usługi Azure Monitor dla języka JavaScript przy użyciu narzędzia npm:
npm install @azure/monitor-query
Tworzenie klienta
Uwierzytelniony klient jest wymagany do wykonywania zapytań dotyczących dzienników lub metryk. Aby przeprowadzić uwierzytelnianie, w poniższym przykładzie użyto wartości DefaultAzureCredential z pakietu @azure/tożsamości .
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 LogsQueryClient
i MetricsQueryClient
są skonfigurowane do korzystania z chmury publicznej Platformy Azure. Aby zamiast tego użyć suwerennej chmury, podaj poprawny endpoint
argument. Na przykład:
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",
});
Uwaga: obecnie MetricsQueryClient
do wykonywania zapytań dotyczących metryk jest używany punkt końcowy usługi Azure Resource Manager (ARM). 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.
Wykonaj zapytanie
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ść żądania jest zbyt wysoka. Limity, takie jak maksymalna liczba zwracanych wierszy, są również stosowane do zapytań 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 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
- Zapytanie dotyczące dzienników
- Zapytanie dotyczące dzienników usługi Batch
- Zaawansowane scenariusze zapytań dzienników
- Zapytanie metryk
Zapytanie dotyczące dzienników
Element LogsQueryClient
może służyć do wykonywania zapytań względem obszaru roboczego usługi Log Analytics przy użyciu język zapytań Kusto. Można timespan.duration
go określić jako ciąg w formacie czasu trwania ISO 8601. Możesz użyć Durations
stałych podanych dla niektórych często używanych czasów trwania ISO 8601.
Możesz wykonywać zapytania dotyczące dzienników według identyfikatora obszaru roboczego lub identyfikatora zasobu. Wynik jest zwracany jako tabela z kolekcją wierszy.
Zapytanie dotyczące dzienników skoncentrowanych na obszarze roboczym
Aby wykonywać zapytania według identyfikatora LogsQueryClient.queryWorkspace
obszaru roboczego, użyj metody :
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. queryResource
W tym miejscu jest używana metoda, 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 Azure Portal.
- W bloku Przegląd wybierz link Widok JSON .
- W wynikowym formacie JSON skopiuj wartość
id
właściwości .
/**
* @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 zapytania dotyczącego dzienników
Funkcja queryWorkspace
funkcji LogsQueryClient
zwraca LogsQueryResult
obiekt. Typ obiektu może mieć wartość 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 usługi Batch
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 BatchQuery
obiektów.
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
funkcji LogsQueryClient
zwraca LogsQueryBatchResult
obiekt. 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 poniższy 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
Wykonywanie niektórych zapytań dotyczących 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 LogsQueryOptions
właściwość obiektu serverTimeoutInSeconds
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 TenantId
kolumny , aby uporządkować wyniki lub filtrować je w zapytaniu Kusto.
Order results by TenantId
AppEvents | order by TenantId
Filtrowanie wyników 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:
LogsQueryOptions.includeQueryStatistics
Ustaw właściwość natrue
wartość .statistics
Uzyskaj dostęp do pola wewnątrzLogsQueryResult
obiektu.
Poniższy przykład wyświetla czas wykonywania zapytania:
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
}`
);
Ponieważ struktura ładunku statistics
różni się w zależności od zapytania, używany jest typ zwracany Record<string, unknown>
. Zawiera on nieprzetworzoną odpowiedź JSON. Statystyki znajdują się we query
właściwości JSON. Na przykład:
{
"query": {
"executionTime": 0.0156478,
"resourceUsage": {...},
"inputDatasetStatistics": {...},
"datasetStatistics": [{...}]
}
}
Dołączanie wizualizacji
Aby uzyskać dane wizualizacji dla zapytań dotyczących dzienników przy użyciu operatora renderowania:
LogsQueryOptions.includeVisualization
Ustaw właściwość natrue
wartość .visualization
Uzyskaj dostęp do pola wewnątrzLogsQueryResult
obiektu.
Na przykład:
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);
Ponieważ struktura ładunku visualization
różni się w zależności od zapytania, używany jest typ zwracany Record<string, unknown>
. 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 URI 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 Azure Portal.
- W bloku Przegląd wybierz link Widok JSON .
- W wynikowym formacie JSON skopiuj wartość
id
właściwości .
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 metricsResponse
metryk są uporządkowane zgodnie z kolejnością, w której użytkownik określa nazwy metryk w metricNames
argumencie tablicy queryResource
dla funkcji. Jeśli użytkownik określi [firstMetricName, secondMetricName]
wartość , wynik polecenia firstMetricName
pojawi się przed wynikiem w secondMetricName
elemecie metricResponse
.
Obsługa odpowiedzi na zapytanie metryk
Funkcja metrics queryResource
zwraca QueryMetricsResult
obiekt. Obiekt QueryMetricsResult
zawiera właściwości, takie jak lista Metric
obiektów typizowane, interval
, namespace
i timespan
. Dostęp Metric
do listy obiektów można uzyskać za pomocą metrics
właściwości . Każdy Metric
obiekt na tej liście zawiera listę TimeSeriesElement
obiektów. Każdy TimeSeriesElement
zawiera data
właściwości 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 wysłać zapytanie o metryki dla wielu zasobów platformy Azure w jednym żądaniu, użyj MetricsQueryClient.queryResources
metody . Ta metoda:
- Wywołuje inny interfejs API niż
MetricsQueryClient
metody. - 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 należy podać przestrzeń nazw metryki zawierającej metryki do odpytowania. 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 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
);
Aby uzyskać spis metryk i wymiarów dostępnych dla każdego typu zasobu platformy Azure, zobacz Obsługiwane metryki w usłudze Azure Monitor.
Rozwiązywanie problemów
Aby zdiagnozować różne scenariusze awarii, 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.
Współtworzenie
Jeśli chcesz współtworzyć tę bibliotekę, przeczytaj przewodnik współtworzenia , aby dowiedzieć się więcej na temat tworzenia i testowania kodu.
Testy tego modułu są kombinacją 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
sample.env
Kopiowanie pliku do.env
.env
Otwórz plik w edytorze i wypełnij wartości.npm run test
.
Aby uzyskać więcej informacji, zobacz nasz folder testów .
Powiązane projekty
Azure SDK for JavaScript
Opinia
https://aka.ms/ContentUserFeedback.
Dostępne już wkrótce: W 2024 r. będziemy stopniowo wycofywać zgłoszenia z serwisu GitHub jako mechanizm przesyłania opinii na temat zawartości i zastępować go nowym systemem opinii. Aby uzyskać więcej informacji, sprawdź:Prześlij i wyświetl opinię dla