JavaScript용 Azure Monitor 쿼리 클라이언트 라이브러리 - 버전 1.3.1
Azure Monitor 쿼리 클라이언트 라이브러리는 Azure Monitor두 데이터 플랫폼에 대해 읽기 전용 쿼리를 실행하는 데 사용됩니다.
- 로그 - 모니터링되는 리소스에서 로그 및 성능 데이터를 수집하고 구성합니다. Azure 서비스의 플랫폼 로그, 가상 머신 에이전트의 로그 및 성능 데이터, 앱의 사용량 및 성능 데이터와 같은 다양한 원본의 데이터를 단일 Azure Log Analytics 작업 영역통합할 수 있습니다. 다양한 데이터 형식은 Kusto 쿼리 언어사용하여 함께 분석할 수 있습니다.
- 메트릭 - 모니터링되는 리소스에서 시계열 데이터베이스로 숫자 데이터를 수집합니다. 메트릭은 일정한 간격으로 수집되고 특정 시간에 시스템의 일부 측면을 설명하는 숫자 값입니다. 메트릭은 가볍고 거의 실시간 시나리오를 지원할 수 있으므로 문제를 경고하고 빠르게 검색하는 데 유용합니다.
리소스:
- 소스 코드
- 패키지(npm)
- API 참조 설명서
- 서비스 설명서
- 샘플
- 로그 변경
시작
지원되는 환경
- LTS 버전의 Node.js
- Safari, Chrome, Microsoft Edge 및 Firefox의 최신 버전
자세한 내용은 지원 정책참조하세요.
필수 구성 요소
- Azure 구독
- TokenCredential 구현(예: Azure Identity 라이브러리 자격 증명 형식).
- 로그를 쿼리하려면 다음 중 하나가 필요합니다.
- Azure Log Analytics 작업 영역
- 모든 종류의 Azure 리소스(스토리지 계정, Key Vault, Cosmos DB 등)
- 메트릭을 쿼리하려면 모든 종류의 Azure 리소스(스토리지 계정, Key Vault, Cosmos DB 등)가 필요합니다.
패키지 설치
npm을 사용하여 JavaScript용 Azure Monitor 쿼리 클라이언트 라이브러리를 설치합니다.
npm install --save @azure/monitor-query
클라이언트 만들기
로그 또는 메트릭을 쿼리하려면 인증된 클라이언트가 필요합니다. 인증하기 위해 다음 예제에서는 @azure/ID 패키지의 DefaultAzureCredential 사용합니다.
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);
Azure 소버린 클라우드에 대한 클라이언트 구성
기본적으로 라이브러리의 클라이언트는 Azure 퍼블릭 클라우드를 사용하도록 구성됩니다. 대신 소버린 클라우드를 사용하려면 클라이언트를 인스턴스화할 때 올바른 엔드포인트 및 대상 그룹 값을 제공합니다. 예를 들어:
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",
});
참고: 현재 MetricsQueryClient
메트릭 쿼리에 ARM(Azure Resource Manager) 엔드포인트를 사용합니다. 이 클라이언트를 사용할 때 클라우드에 해당하는 관리 엔드포인트가 필요합니다. 이 세부 정보는 나중에 변경될 수 있습니다.
쿼리 실행
로그 및 메트릭 쿼리의 예제는 예제 섹션을 참조하세요.
주요 개념
쿼리 속도 제한 및 제한을 기록합니다.
Log Analytics 서비스는 요청 속도가 너무 높을 때 제한을 적용합니다. 반환되는 최대 행 수와 같은 제한은 Kusto 쿼리에도 적용됩니다. 자세한 내용은 Query API참조하세요.
메트릭 데이터 구조
각 메트릭 값 집합은 다음과 같은 특성을 가진 시계열입니다.
- 값이 수집된 시간
- 값과 연결된 리소스입니다.
- 메트릭의 범주처럼 작동하는 네임스페이스
- 메트릭 이름
- 값 자체
- 일부 메트릭에는 다차원 메트릭에 설명된 대로 여러 차원이 있습니다. 사용자 지정 메트릭에는 최대 10개의 차원이 있을 수 있습니다.
예제
-
로그 쿼리
- 작업 영역 중심 로그 쿼리
- 리소스 중심 로그 쿼리
- 로그 쿼리 응답 처리
- Batch 로그 쿼리
-
고급 로그 쿼리 시나리오
- 로그 쿼리 시간 제한 설정
- 여러 작업 영역 쿼리
- 통계 포함
- 시각화 포함
-
메트릭 쿼리
- 메트릭 쿼리 응답 처리
- 응답 처리 예제
- 여러 리소스에 대한 쿼리 메트릭
로그 쿼리
LogsQueryClient
사용하여 Kusto 쿼리 언어사용하여 Log Analytics 작업 영역을 쿼리할 수 있습니다.
timespan.duration
ISO 8601 기간 형식의 문자열로 지정할 수 있습니다. 일반적으로 사용되는 일부 ISO 8601 기간에 제공된 Durations
상수도 사용할 수 있습니다.
Log Analytics 작업 영역 ID 또는 Azure 리소스 ID로 로그를 쿼리할 수 있습니다. 결과는 행 컬렉션이 있는 테이블로 반환됩니다.
작업 영역 중심 로그 쿼리
작업 영역 ID별로 쿼리하려면 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));
리소스 중심 로그 쿼리
다음 예제에서는 Azure 리소스에서 직접 로그를 쿼리하는 방법을 보여 줍니다. 여기서는 queryResource
메서드가 사용되고 Azure 리소스 ID가 전달됩니다. 예를 들어 /subscriptions/{subscription-id}/resourceGroups/{resource-group-name}/providers/{resource-provider}/{resource-type}/{resource-name}
.
리소스 ID를 찾으려면:
- Azure Portal에서 리소스의 페이지로 이동합니다.
- 개요 블레이드에서 JSON 보기 링크를 선택합니다.
- 결과 JSON에서
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);
});
로그 쿼리 응답 처리
LogsQueryClient
queryWorkspace
함수는 LogsQueryResult
개체를 반환합니다. 개체 형식은 LogsQuerySuccessfulResult
또는 LogsQueryPartialResult
수 있습니다. 응답의 계층 구조는 다음과 같습니다.
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
예를 들어 테이블을 사용하여 응답을 처리하려면 다음을 수행합니다.
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);
}
}
}
전체 샘플은여기에서
Batch 로그 쿼리
다음 예제에서는 일괄 처리 쿼리 API를 사용하여 동시에 여러 쿼리를 보내는 방법을 보여 줍니다. 쿼리는 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);
}
}
}
로그 일괄 처리 쿼리 응답 처리
LogsQueryClient
queryBatch
함수는 LogsQueryBatchResult
개체를 반환합니다.
LogsQueryBatchResult
다음과 같은 가능한 형식의 개체 목록을 포함합니다.
LogsQueryPartialResult
LogsQuerySuccessfulResult
LogsQueryError
응답의 계층 구조는 다음과 같습니다.
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")
예를 들어 다음 코드는 일괄 처리 로그 쿼리 응답을 처리합니다.
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);
}
}
}
전체 샘플은여기에서
고급 로그 쿼리 시나리오
로그 쿼리 시간 제한 설정
일부 로그 쿼리를 실행하는 데 3분 이상 걸립니다. 기본 서버 시간 제한은 3분입니다. 서버 시간 제한을 최대 10분으로 늘릴 수 있습니다. 다음 예제에서는 LogsQueryOptions
개체의 serverTimeoutInSeconds
속성을 사용하여 서버 시간 제한을 10분으로 늘입니다.
// 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;
여러 작업 영역 쿼리
여러 Log Analytics 작업 영역에서 동일한 로그 쿼리를 실행할 수 있습니다. Kusto 쿼리 외에도 다음 매개 변수가 필요합니다.
-
workspaceId
- 첫 번째(기본) 작업 영역 ID입니다. -
additionalWorkspaces
-workspaceId
매개 변수에 제공된 작업 영역을 제외한 작업 영역 목록입니다. 매개 변수의 목록 항목은 다음 식별자 형식으로 구성됩니다.- 정규화된 작업 영역 이름
- 작업 영역 ID
- Azure 리소스 ID
예를 들어 다음 쿼리는 세 개의 작업 영역에서 실행됩니다.
const queryLogsOptions: LogsQueryOptions = {
additionalWorkspaces: ["<workspace2>", "<workspace3>"],
};
const kustoQuery = "AppEvents | limit 10";
const result = await logsQueryClient.queryWorkspace(
azureLogAnalyticsWorkspaceId,
kustoQuery,
{ duration: Durations.twentyFourHours },
queryLogsOptions,
);
각 작업 영역에 대한 결과를 보려면 TenantId
열을 사용하여 결과를 정렬하거나 Kusto 쿼리에서 필터링합니다.
TenantId
AppEvents | order by TenantId
TenantId
AppEvents | filter TenantId == "<workspace2>"
전체 샘플은여기에서
통계 포함
로그 쿼리 실행 통계(예: CPU 및 메모리 사용량)를 얻으려면 다음을 수행합니다.
-
LogsQueryOptions.includeQueryStatistics
속성을true
설정합니다. -
LogsQueryResult
개체 내의statistics
필드에 액세스합니다.
다음 예제에서는 쿼리 실행 시간을 인쇄합니다.
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
}`,
);
statistics
페이로드의 구조는 쿼리에 따라 다르므로 Record<string, unknown>
반환 형식이 사용됩니다. 원시 JSON 응답을 포함합니다. 통계는 JSON의 query
속성 내에 있습니다. 예를 들어:
{
"query": {
"executionTime": 0.0156478,
"resourceUsage": {...},
"inputDatasetStatistics": {...},
"datasetStatistics": [{...}]
}
}
시각화 포함
렌더링 연산자를 사용하여 로그 쿼리에 대한 시각화 데이터를 얻으려면.
-
LogsQueryOptions.includeVisualization
속성을true
설정합니다. -
LogsQueryResult
개체 내의visualization
필드에 액세스합니다.
예를 들어:
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);
visualization
페이로드의 구조는 쿼리에 따라 다르므로 Record<string, unknown>
반환 형식이 사용됩니다. 원시 JSON 응답을 포함합니다. 예를 들어:
{
"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
}
메트릭 쿼리
다음 예제에서는 Azure Metrics Advisor 구독에 대한 메트릭을 가져옵니다.
리소스 URI는 메트릭이 쿼리되는 리소스의 URI여야 합니다. 일반적으로 /subscriptions/<id>/resourceGroups/<rg-name>/providers/<source>/topics/<resource-name>
형식입니다.
리소스 URI를 찾으려면 다음을 수행합니다.
- Azure Portal에서 리소스의 페이지로 이동합니다.
- 개요 블레이드에서 JSON 보기 링크를 선택합니다.
- 결과 JSON에서
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);
});
앞의 샘플에서 metricsResponse
메트릭 결과는 사용자가 queryResource
함수의 metricNames
배열 인수에서 메트릭 이름을 지정하는 순서에 따라 정렬됩니다. 사용자가 [firstMetricName, secondMetricName]
지정하면 metricResponse
secondMetricName
결과 앞에 firstMetricName
결과가 표시됩니다.
메트릭 쿼리 응답 처리
메트릭 queryResource
함수는 QueryMetricsResult
개체를 반환합니다.
QueryMetricsResult
개체에는 Metric
형식의 개체, interval
, namespace
및 timespan
목록과 같은 속성이 포함됩니다.
metrics
속성을 사용하여 Metric
개체 목록에 액세스할 수 있습니다. 이 목록의 각 Metric
개체에는 TimeSeriesElement
개체 목록이 포함되어 있습니다. 각 TimeSeriesElement
data
및 metadataValues
속성을 포함합니다. 시각적 형식에서 응답의 개체 계층 구조는 다음 구조와 유사합니다.
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)
응답 처리 예제
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);
});
전체 샘플은여기에서
여러 리소스에 대한 쿼리 메트릭
단일 요청에서 여러 Azure 리소스에 대한 메트릭을 쿼리하려면 MetricsClient.queryResources
메서드를 사용합니다. 이 메서드는 다음과 같습니다.
-
MetricsClient
메서드와 다른 API를 호출합니다. - 클라이언트를 만들 때 지역 엔드포인트가 필요합니다. 예를 들어 "https://westus3.metrics.monitor.azure.com"입니다.
각 Azure 리소스는 다음 위치에 있어야 합니다.
- 클라이언트를 만들 때 지정된 엔드포인트와 동일한 지역입니다.
- 동일한 Azure 구독입니다.
더욱이:
- 사용자는 Azure 구독 수준에서 모니터링 데이터를 읽을 수 있는 권한을 부여받아야 합니다. 예를 들어 모니터링 읽기 권한자 역할은 쿼리할 구독에.
- 쿼리할 메트릭을 포함하는 메트릭 네임스페이스를 제공해야 합니다. 메트릭 네임스페이스 목록은 리소스 종류따라 지원되는 메트릭 및 로그 범주
참조하세요.
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
);
각 Azure 리소스 종류에 사용할 수 있는 메트릭 및 차원의 인벤토리는 Azure Monitor
문제 해결
다양한 오류 시나리오를 진단하려면 문제 해결 가이드참조하세요.
다음 단계
Azure Monitor에 대한 자세한 내용은 Azure Monitor 서비스 설명서참조하세요.
기여
이 라이브러리에 기여하려면 기여 가이드 읽어 코드를 빌드하고 테스트하는 방법에 대해 자세히 알아보세요.
이 모듈의 테스트는 라이브 테스트와 단위 테스트가 혼합되어 있으므로 Azure Monitor 인스턴스가 있어야 합니다. 테스트를 실행하려면 다음을 실행해야 합니다.
rush update
rush build -t @azure/monitor-query
cd into sdk/monitor/monitor-query
-
sample.env
파일을 복사하여.env
- 편집기에서
.env
파일을 열고 값을 채웁니다. -
npm run test
.
자세한 내용은 테스트 폴더를 참조하세요.
관련 프로젝트
- JavaScript용 Microsoft Azure SDK
- Azure Monitor
Azure SDK for JavaScript