JavaScript용 Azure Monitor 쿼리 클라이언트 라이브러리 - 버전 1.3.1

Azure Monitor 쿼리 클라이언트 라이브러리는 Azure Monitor두 데이터 플랫폼에 대해 읽기 전용 쿼리를 실행하는 데 사용됩니다.

  • 로그 - 모니터링되는 리소스에서 로그 및 성능 데이터를 수집하고 구성합니다. Azure 서비스의 플랫폼 로그, 가상 머신 에이전트의 로그 및 성능 데이터, 앱의 사용량 및 성능 데이터와 같은 다양한 원본의 데이터를 단일 Azure Log Analytics 작업 영역통합할 수 있습니다. 다양한 데이터 형식은 Kusto 쿼리 언어사용하여 함께 분석할 수 있습니다.
  • 메트릭 - 모니터링되는 리소스에서 시계열 데이터베이스로 숫자 데이터를 수집합니다. 메트릭은 일정한 간격으로 수집되고 특정 시간에 시스템의 일부 측면을 설명하는 숫자 값입니다. 메트릭은 가볍고 거의 실시간 시나리오를 지원할 수 있으므로 문제를 경고하고 빠르게 검색하는 데 유용합니다.

리소스:

시작

지원되는 환경

자세한 내용은 지원 정책참조하세요.

필수 구성 요소

패키지 설치

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개의 차원이 있을 수 있습니다.

예제

로그 쿼리

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를 찾으려면:

  1. Azure Portal에서 리소스의 페이지로 이동합니다.
  2. 개요 블레이드에서 JSON 보기 링크를 선택합니다.
  3. 결과 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 및 메모리 사용량)를 얻으려면 다음을 수행합니다.

  1. LogsQueryOptions.includeQueryStatistics 속성을 true설정합니다.
  2. 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": [{...}]
  }
}

시각화 포함

렌더링 연산자를 사용하여 로그 쿼리에 대한 시각화 데이터를 얻으려면.

  1. LogsQueryOptions.includeVisualization 속성을 true설정합니다.
  2. 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를 찾으려면 다음을 수행합니다.

  1. Azure Portal에서 리소스의 페이지로 이동합니다.
  2. 개요 블레이드에서 JSON 보기 링크를 선택합니다.
  3. 결과 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]지정하면 metricResponsesecondMetricName 결과 앞에 firstMetricName 결과가 표시됩니다.

메트릭 쿼리 응답 처리

메트릭 queryResource 함수는 QueryMetricsResult 개체를 반환합니다. QueryMetricsResult 개체에는 Metric형식의 개체, interval, namespacetimespan목록과 같은 속성이 포함됩니다. metrics 속성을 사용하여 Metric 개체 목록에 액세스할 수 있습니다. 이 목록의 각 Metric 개체에는 TimeSeriesElement 개체 목록이 포함되어 있습니다. 각 TimeSeriesElementdatametadataValues 속성을 포함합니다. 시각적 형식에서 응답의 개체 계층 구조는 다음 구조와 유사합니다.

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 인스턴스가 있어야 합니다. 테스트를 실행하려면 다음을 실행해야 합니다.

  1. rush update
  2. rush build -t @azure/monitor-query
  3. cd into sdk/monitor/monitor-query
  4. sample.env 파일을 복사하여 .env
  5. 편집기에서 .env 파일을 열고 값을 채웁니다.
  6. npm run test.

자세한 내용은 테스트 폴더를 참조하세요.

  • JavaScript용 Microsoft Azure SDK
  • Azure Monitor

노출