Azure Monitor용 Microsoft OpenTelemetry 내보내기

Azure Monitor의 내보내기를 사용하면 OpenTelemetry SDK를 사용하여 데이터를 내보내고 Python으로 작성된 애플리케이션에 대한 원격 분석 데이터를 Azure Monitor로 보낼 수 있습니다.

소스 코드 | 패키지(PyPi) | API 참조 설명서 | 제품 설명서 | 샘플 | Changelog

시작

패키지 설치

pip를 사용하여 Azure Monitor용 Microsoft OpenTelemetry 내보내기를 설치합니다.

pip install azure-monitor-opentelemetry-exporter --pre

사전 요구 사항

이 패키지를 사용하려면 다음이 있어야 합니다.

클라이언트 인스턴스화

Azure Monitor 내보내기와의 상호 작용은 분산 추적, AzureMonitorLogExporter 로깅 및 AzureMonitorMetricExporter 메트릭에 대한 클래스의 AzureMonitorTraceExporter instance 시작합니다. 개체를 인스턴스화하려면 connection_string 필요합니다. 연결 문자열 사용하여 내보내기를 생성하는 방법에 대한 데모를 위해 아래에 연결된 샘플을 찾습니다.

로깅(실험적)

참고: 에 대한 AzureMonitorLogExporter 로깅 신호는 현재 실험 상태입니다. 향후 호환성이 손상되는 변경이 발생할 수 있습니다.

from azure.monitor.opentelemetry.exporter import AzureMonitorLogExporter
exporter = AzureMonitorLogExporter(
    connection_string=os.environ["APPLICATIONINSIGHTS_CONNECTION_STRING"]
)

메트릭

from azure.monitor.opentelemetry.exporter import AzureMonitorMetricExporter
exporter = AzureMonitorMetricExporter(
    connection_string=os.environ["APPLICATIONINSIGHTS_CONNECTION_STRING"]
)

추적

from azure.monitor.opentelemetry.exporter import AzureMonitorTraceExporter
exporter = AzureMonitorTraceExporter(
    connection_string=os.environ["APPLICATIONINSIGHTS_CONNECTION_STRING"]
)

생성자를 통해 직접 내보내기를 인스턴스화할 수도 있습니다. 이 경우 환경 변수에서 APPLICATIONINSIGHTS_CONNECTION_STRING 연결 문자열 자동으로 채워집니다.

from azure.monitor.opentelemetry.exporter import AzureMonitorLogExporter
exporter = AzureMonitorLogExporter()
from azure.monitor.opentelemetry.exporter import AzureMonitorMetricExporter
exporter = AzureMonitorMetricExporter()
from azure.monitor.opentelemetry.exporter import AzureMonitorTraceExporter
exporter = AzureMonitorTraceExporter()

주요 개념

Azure Monitor 내보내기의 주요 개념 중 일부는 다음과 같습니다.

  • OpenTelemetry: OpenTelemetry는 소프트웨어의 성능과 동작을 이해하기 위해 분석을 위해 원격 분석 데이터(메트릭, 로그 및 추적)를 수집하고 내보내는 데 사용되는 라이브러리 집합입니다.

  • 계측: 모든 애플리케이션에서 직접 OpenTelemetry API를 호출하는 기능은 계측을 통해 촉진됩니다. 다른 라이브러리에 대해 OpenTelemetry 가시성을 사용하도록 설정하는 라이브러리를 계측 라이브러리라고 합니다.

  • 로그: 로그는 로깅, 예외 및 이벤트의 캡처를 나타냅니다.

  • LogRecord: 지원되는 로깅 라이브러리에서 내보낸 로그 레코드를 나타냅니다.

  • 로거: 을 LogRecord 읽을 수 LogData있는 로 변환하고 내보낼 SDK를 통해 푸시됩니다.

  • 로거 공급자: 지정된 계측 라이브러리에 대한 를 제공합니다 Logger .

  • LogRecordProcessor: 로그 레코드 내보내기 작업을 후크하는 인터페이스입니다.

  • LoggingHandler: 표준 Python logging 라이브러리에서 OpenTelemetry 형식으로 로깅 레코드를 작성하는 처리기 클래스입니다.

  • AzureMonitorLogExporter: 로깅 관련 원격 분석을 Azure Monitor에 보내도록 초기화된 클래스입니다.

  • 메트릭: Metric 일정 기간 동안 미리 정의된 집계 및 특성 집합을 사용하여 원시 측정값을 기록하는 것을 의미합니다.

  • 측정값: 특정 시점에 기록된 데이터 포인트를 나타냅니다.

  • 계측기: 계측기는 를 보고 Measurement하는 데 사용됩니다.

  • 미터: 는 Meter 를 만드는 Instruments역할을 담당합니다.

  • 미터 공급자: 지정된 계측 라이브러리에 대한 을 제공합니다 Meter .

  • 메트릭 판독기: 컬렉션, 플러시 및 종료와 같은 OpenTelemetry 메트릭 SDK의 일반적인 구성 가능한 측면을 제공하는 SDK 구현 개체입니다.

  • AzureMonitorMetricExporter: 메트릭 관련 원격 분석을 Azure Monitor로 보내도록 초기화된 클래스입니다.

  • 추적: 추적은 분산 추적을 나타냅니다. 분산 추적은 애플리케이션의 다양한 구성 요소에 통합된 단일 논리 작업의 결과로 트리거되는 이벤트 집합입니다. 특히 추적은 범위 간의 가장자리가 부모/자식 관계로 정의되는 Spans의 DAG(지시된 순환 그래프)로 간주될 수 있습니다.

  • 범위: 내 Trace의 단일 작업을 나타냅니다. 중첩되어 추적 트리를 형성할 수 있습니다. 각 추적에는 일반적으로 전체 작업을 설명하고 선택적으로 하위 작업에 대해 하나 이상의 광석 하위 범위를 설명하는 루트 범위가 포함되어 있습니다.

  • Tracer: 만들기 Span를 담당합니다.

  • 추적기 공급자: 지정된 계측 라이브러리에서 사용할 을 제공합니다 Tracer .

  • 범위 프로세서: 범위 프로세서는 SDK의 Span 시작 및 종료 메서드 호출에 대한 후크를 허용합니다. 자세한 내용은 링크를 따르세요.

  • AzureMonitorTraceExporter: 추적 관련 원격 분석을 Azure Monitor로 보내도록 초기화된 클래스입니다.

  • 샘플링: 샘플링은 수집되어 백 엔드로 전송되는 추적 샘플의 수를 줄여 OpenTelemetry에서 도입된 노이즈 및 오버헤드를 제어하는 메커니즘입니다.

  • ApplicationInsightsSampler: Application Insights SDK 및 OpenTelemetry 기반 SDK에서 Application Insights로 데이터를 보내는 일관된 샘플링에 사용되는 Application Insights 특정 샘플러입니다. 이 샘플러는 사용될 때마다 AzureMonitorTraceExporter 사용해야 합니다.

이러한 리소스에 대한 자세한 내용은 Azure Monitor란?을 참조하세요.

구성

모든 구성 옵션은 를 통해 내보내기의 생성자를 통해 kwargs전달할 수 있습니다. 다음은 구성 가능한 옵션 목록입니다.

  • connection_string: Application Insights 리소스에 사용되는 연결 문자열.
  • disable_offline_storage: 재시도에 실패한 원격 분석 레코드 저장을 사용하지 않도록 설정할지 여부를 결정하는 부울 값입니다. 기본값은 False입니다.
  • storage_directory: 재시도 파일을 저장할 스토리지 디렉터리입니다. 기본값은 <tempfile.gettempdir()>/Microsoft/AzureMonitor/opentelemetry-python-<your-instrumentation-key>입니다.
  • credential: AAD(Azure Active Directory) 인증에 사용되는 ManagedIdentityCredential 또는 ClientSecretCredential과 같은 토큰 자격 증명입니다. 기본값은 None입니다. 예제는 샘플을 참조하세요.

예제

로깅(실험적)

참고: 에 대한 AzureMonitorLogExporter 로깅 신호는 현재 실험 상태입니다. 향후 호환성이 손상되는 변경이 발생할 수 있습니다.

다음 섹션에서는 다음을 포함하여 가장 일반적인 작업 중 일부를 다루는 몇 가지 코드 조각을 제공합니다.

OpenTelemetry 로깅 SDK를 검토하여 OpenTelemetry 구성 요소를 사용하여 로그를 수집하는 방법을 알아봅니다.

로그 내보내기 헬로 월드

"""
An example to show an application using Opentelemetry logging sdk. Logging calls to the standard Python
logging library are tracked and telemetry is exported to application insights with the AzureMonitorLogExporter.
"""
import os
import logging

from opentelemetry.sdk._logs import (
    LoggerProvider,
    LoggingHandler,
    set_logger_provider,
)
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor

from azure.monitor.opentelemetry.exporter import AzureMonitorLogExporter

logger_provider = LoggerProvider()
set_logger_provider(logger_provider)

exporter = AzureMonitorLogExporter(
    connection_string=os.environ["APPLICATIONINSIGHTS_CONNECTION_STRING"]
)

logger_provider.add_log_record_processor(BatchLogRecordProcessor(exporter))
handler = LoggingHandler()

# Attach LoggingHandler to root logger
logging.getLogger().addHandler(handler)
logging.getLogger().setLevel(logging.NOTSET)

logger = logging.getLogger(__name__)

logger.warning("Hello World!")

# Telemetry records are flushed automatically upon application exit
# If you would like to flush records manually yourself, you can call force_flush()
logger_provider.force_flush()

상관 관계 로그 내보내기

"""
An example showing how to include context correlation information in logging telemetry.
"""
import os
import logging

from opentelemetry import trace
from opentelemetry.sdk._logs import (
    LoggerProvider,
    LoggingHandler,
    set_logger_provider,
)
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor
from opentelemetry.sdk.trace import TracerProvider

from azure.monitor.opentelemetry.exporter import AzureMonitorLogExporter

trace.set_tracer_provider(TracerProvider())
tracer = trace.get_tracer(__name__)
logger_provider = LoggerProvider()
set_logger_provider(logger_provider)

exporter = AzureMonitorLogExporter(
    connection_string=os.environ["APPLICATIONINSIGHTS_CONNECTION_STRING"]
)

logger_provider.add_log_record_processor(BatchLogRecordProcessor(exporter))
handler = LoggingHandler()

# Attach LoggingHandler to root logger
logging.getLogger().addHandler(handler)
logging.getLogger().setLevel(logging.NOTSET)

logger = logging.getLogger(__name__)

logger.info("INFO: Outside of span")
with tracer.start_as_current_span("foo"):
    logger.warning("WARNING: Inside of span")
logger.error("ERROR: After span")

사용자 지정 속성 로그 내보내기

"""
An example showing how to add custom properties to logging telemetry.
"""
import os
import logging

from opentelemetry.sdk._logs import (
    LoggerProvider,
    LoggingHandler,
    set_logger_provider,
)
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor

from azure.monitor.opentelemetry.exporter import AzureMonitorLogExporter

logger_provider = LoggerProvider()
set_logger_provider(logger_provider)

exporter = AzureMonitorLogExporter(
    connection_string=os.environ["APPLICATIONINSIGHTS_CONNECTION_STRING"]
)

logger_provider.add_log_record_processor(BatchLogRecordProcessor(exporter))
handler = LoggingHandler()

# Attach LoggingHandler to root logger
logging.getLogger().addHandler(handler)
logging.getLogger().setLevel(logging.NOTSET)

logger = logging.getLogger(__name__)

# Custom properties
logger.debug("DEBUG: Debug with properties", extra={"debug": "true"})

예외 로그 내보내기

"""
An example showing how to export exception telemetry using the AzureMonitorLogExporter.
"""
import os
import logging

from opentelemetry._logs import (
    get_logger_provider,
    set_logger_provider,
)
from opentelemetry.sdk._logs import (
    LoggerProvider,
    LoggingHandler,
)
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor

from azure.monitor.opentelemetry.exporter import AzureMonitorLogExporter

set_logger_provider(LoggerProvider())
exporter = AzureMonitorLogExporter(
    connection_string=os.environ["APPLICATIONINSIGHTS_CONNECTION_STRING"]
)
get_logger_provider().add_log_record_processor(BatchLogRecordProcessor(exporter))

# Attach LoggingHandler to namespaced logger
handler = LoggingHandler()
logger = logging.getLogger(__name__)
logger.addHandler(handler)
logger.setLevel(logging.NOTSET)

# The following code will generate two pieces of exception telemetry
# that are identical in nature
try:
    val = 1 / 0
    print(val)
except ZeroDivisionError:
    logger.exception("Error: Division by zero")

try:
    val = 1 / 0
    print(val)
except ZeroDivisionError:
    logger.error("Error: Division by zero", stack_info=True, exc_info=True)

메트릭

다음 섹션에서는 다음을 포함하여 가장 일반적인 작업 중 일부를 다루는 몇 가지 코드 조각을 제공합니다.

OpenTelemetry 메트릭 SDK를 검토하여 OpenTelemetry 구성 요소를 사용하여 메트릭을 수집하는 방법을 알아봅니다.

메트릭 계측 사용량

"""
An example to show an application using all instruments in the OpenTelemetry SDK. Metrics created
and recorded using the sdk are tracked and telemetry is exported to application insights with the
AzureMonitorMetricsExporter.
"""
import os
from typing import Iterable

from opentelemetry import metrics
from opentelemetry.metrics import CallbackOptions, Observation
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader

from azure.monitor.opentelemetry.exporter import AzureMonitorMetricExporter

exporter = AzureMonitorMetricExporter(
    connection_string=os.environ["APPLICATIONINSIGHTS_CONNECTION_STRING"]
)
reader = PeriodicExportingMetricReader(exporter, export_interval_millis=5000)
metrics.set_meter_provider(MeterProvider(metric_readers=[reader]))

# Create a namespaced meter
meter = metrics.get_meter_provider().get_meter("sample")

# Callback functions for observable instruments
def observable_counter_func(options: CallbackOptions) -> Iterable[Observation]:
    yield Observation(1, {})


def observable_up_down_counter_func(
    options: CallbackOptions,
) -> Iterable[Observation]:
    yield Observation(-10, {})


def observable_gauge_func(options: CallbackOptions) -> Iterable[Observation]:
    yield Observation(9, {})

# Counter
counter = meter.create_counter("counter")
counter.add(1)

# Async Counter
observable_counter = meter.create_observable_counter(
    "observable_counter", [observable_counter_func]
)

# UpDownCounter
up_down_counter = meter.create_up_down_counter("up_down_counter")
up_down_counter.add(1)
up_down_counter.add(-5)

# Async UpDownCounter
observable_up_down_counter = meter.create_observable_up_down_counter(
    "observable_up_down_counter", [observable_up_down_counter_func]
)

# Histogram
histogram = meter.create_histogram("histogram")
histogram.record(99.9)

# Async Gauge
gauge = meter.create_observable_gauge("gauge", [observable_gauge_func])

# Upon application exit, one last collection is made and telemetry records are
# flushed automatically. # If you would like to flush records manually yourself,
# you can call force_flush()
meter_provider.force_flush()

메트릭 사용자 지정 보기

"""
This example shows how to customize the metrics that are output by the SDK using Views. Metrics created
and recorded using the sdk are tracked and telemetry is exported to application insights with the
AzureMonitorMetricsExporter.
"""
import os

from opentelemetry import metrics
from opentelemetry.sdk.metrics import Counter, MeterProvider
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
from opentelemetry.sdk.metrics.view import View

from azure.monitor.opentelemetry.exporter import AzureMonitorMetricExporter

exporter = AzureMonitorMetricExporter.from_connection_string(
    os.environ["APPLICATIONINSIGHTS_CONNECTION_STRING"]
)
# Create a view matching the counter instrument `my.counter`
# and configure the new name `my.counter.total` for the result metrics stream
change_metric_name_view = View(
    instrument_type=Counter,
    instrument_name="my.counter",
    name="my.counter.total",
)

reader = PeriodicExportingMetricReader(exporter, export_interval_millis=5000)
provider = MeterProvider(
    metric_readers=[
        reader,
    ],
    views=[
        change_metric_name_view,
    ],
)
metrics.set_meter_provider(provider)

meter = metrics.get_meter_provider().get_meter("view-name-change")
my_counter = meter.create_counter("my.counter")
my_counter.add(100)

메트릭 SDK를 사용하는 더 많은 예제는 Views 여기에서 찾을 수 있습니다.

메트릭 레코드 특성

"""
An example to show an application using different attributes with instruments in the OpenTelemetry SDK.
Metrics created and recorded using the sdk are tracked and telemetry is exported to application insights
with the AzureMonitorMetricsExporter.
"""
import os

from opentelemetry import metrics
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader

from azure.monitor.opentelemetry.exporter import AzureMonitorMetricExporter

exporter = AzureMonitorMetricExporter.from_connection_string(
    os.environ["APPLICATIONINSIGHTS_CONNECTION_STRING"]
)
reader = PeriodicExportingMetricReader(exporter, export_interval_millis=5000)
metrics.set_meter_provider(MeterProvider(metric_readers=[reader]))

attribute_set1 = {
    "key1": "val1"
}
attribute_set2 = {
    "key2": "val2"
}
large_attribute_set = {}
for i in range(20):
    key = "key{}".format(i)
    val = "val{}".format(i)
    large_attribute_set[key] = val

meter = metrics.get_meter_provider().get_meter("sample")

# Counter
counter = meter.create_counter("attr1_counter")
counter.add(1, attribute_set1)

# Counter2
counter2 = meter.create_counter("attr2_counter")
counter2.add(10, attribute_set1)
counter2.add(30, attribute_set2)

# Counter3
counter3 = meter.create_counter("large_attr_counter")
counter3.add(100, attribute_set1)
counter3.add(200, large_attribute_set)

추적

다음 섹션에서는 다음을 포함하여 가장 일반적인 작업 중 일부를 다루는 몇 가지 코드 조각을 제공합니다.

OpenTelemetry 추적 SDK를 검토하여 OpenTelemetry 구성 요소를 사용하여 로그를 수집하는 방법을 알아봅니다.

헬로 월드 추적 내보내기

"""
An example to show an application using Opentelemetry tracing api and sdk. Custom dependencies are
tracked via spans and telemetry is exported to application insights with the AzureMonitorTraceExporter.
"""
import os
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from azure.monitor.opentelemetry.exporter import AzureMonitorTraceExporter

tracer_provider = TracerProvider()
trace.set_tracer_provider(tracer_provider)
tracer = trace.get_tracer(__name__)
# This is the exporter that sends data to Application Insights
exporter = AzureMonitorTraceExporter(
    connection_string=os.environ["APPLICATIONINSIGHTS_CONNECTION_STRING"]
)
span_processor = BatchSpanProcessor(exporter)
trace.get_tracer_provider().add_span_processor(span_processor)

with tracer.start_as_current_span("hello"):
    print("Hello, World!")

# Telemetry records are flushed automatically upon application exit
# If you would like to flush records manually yourself, you can call force_flush()
tracer_provider.force_flush()

요청 라이브러리를 사용하여 계측

OpenTelemetry는 타사 라이브러리를 사용하여 계측할 수 있는 여러 계측도 지원합니다.

OpenTelemetry에서 사용할 수 있는 계측 목록은 contrib 설명서를 참조하세요.

이 예제에서는 요청 라이브러리를 사용하여 계측하는 방법을 보여 줍니다 .

  • pip install opentelemetry-instrumentation-requests를 사용하여 요청 계측 패키지를 설치합니다.
"""
An example to show an application instrumented with the OpenTelemetry requests instrumentation.
Calls made with the requests library will be automatically tracked and telemetry is exported to 
application insights with the AzureMonitorTraceExporter.
See more info on the requests instrumentation here:
https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-requests
"""
import os
import requests
from opentelemetry import trace
from opentelemetry.instrumentation.requests import RequestsInstrumentor
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from azure.monitor.opentelemetry.exporter import AzureMonitorTraceExporter

# This line causes your calls made with the requests library to be tracked.
RequestsInstrumentor().instrument()

trace.set_tracer_provider(TracerProvider())
tracer = trace.get_tracer(__name__)
exporter = AzureMonitorTraceExporter(
    connection_string=os.environ["APPLICATIONINSIGHTS_CONNECTION_STRING"]
)
span_processor = BatchSpanProcessor(exporter)
trace.get_tracer_provider().add_span_processor(span_processor)

# This request will be traced
response = requests.get(url="https://azure.microsoft.com/")

샘플링 사용

샘플링을 사용하도록 설정하여 수신하는 원격 분석 레코드의 양을 제한할 수 있습니다. Application Insights에서 올바른 샘플링을 사용하도록 설정하려면 아래와 같이 을 ApplicationInsightsSampler 사용합니다.

"""
An example to show an application using the ApplicationInsightsSampler to enable sampling for your telemetry.
Specify a sampling rate for the sampler to limit the amount of telemetry records you receive. Custom dependencies
 are tracked via spans and telemetry is exported to application insights with the AzureMonitorTraceExporter.
"""
import os
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from azure.monitor.opentelemetry.exporter import (
    ApplicationInsightsSampler,
    AzureMonitorTraceExporter,
)

# Sampler expects a sample rate of between 0 and 1 inclusive
# A rate of 0.75 means approximately 75% of your telemetry will be sent
sampler = ApplicationInsightsSampler(0.75)
trace.set_tracer_provider(TracerProvider(sampler=sampler))
tracer = trace.get_tracer(__name__)
exporter = AzureMonitorTraceExporter(
    connection_string=os.environ["APPLICATIONINSIGHTS_CONNECTION_STRING"]
)
span_processor = BatchSpanProcessor(exporter)
trace.get_tracer_provider().add_span_processor(span_processor)

for i in range(100):
    # Approximately 25% of these spans should be sampled out
    with tracer.start_as_current_span("hello"):
        print("Hello, World!")

플러시/종료 동작

OpenTelemetry SDK 및 Azure Monitor 내보내기를 사용하여 설정된 모든 애플리케이션의 경우 애플리케이션 종료 시 원격 분석이 자동으로 플러시됩니다. 애플리케이션이 갑자기 종료되거나 catch되지 않은 예외로 인해 충돌하는 경우는 포함되지 않습니다.

문제 해결

내보내기는 Azure Core에 정의된 예외를 발생합니다.

다음 단계

추가 샘플 코드

일반적인 시나리오를 보여주는 샘플 디렉터리에서 추가 예제를 확인하세요.

추가 설명서

Azure Monitor 서비스에 대한 보다 광범위한 설명서는 docs.microsoft.com Azure Monitor 설명서를 참조하세요 .

OpenTelemetry에 대한 자세한 개요는 개요 페이지를 참조하세요.

공식 OpenTelemetry Python 설명서 및 다른 원격 분석 시나리오를 사용하도록 설정하는 방법은 공식 OpenTelemetry 웹 사이트를 방문하세요.

Azure Monitor에서 원격 분석 시나리오를 사용하도록 설정하는 유용한 미리 조립된 구성 요소(현재 패키지 중 하나)의 번들인 Azure Monitor OpenTelemetry Distro에 대한 자세한 내용은 추가 정보를 참조하세요.

참여

이 프로젝트에 대한 기여와 제안을 환영합니다. 대부분의 경우 기여하려면 권한을 부여하며 실제로 기여를 사용할 권한을 당사에 부여한다고 선언하는 CLA(기여자 라이선스 계약)에 동의해야 합니다. 자세한 내용은 https://cla.microsoft.com 을 참조하세요.

끌어오기 요청을 제출하면 CLA-bot은 CLA를 제공하고 PR을 적절하게 데코레이팅해야 하는지 여부를 자동으로 결정합니다(예: 레이블, 설명). 봇에서 제공하는 지침을 따르기만 하면 됩니다. 이 작업은 CLA를 사용하여 모든 리포지토리에서 한 번만 수행하면 됩니다.

이 프로젝트에는 Microsoft Open Source Code of Conduct(Microsoft 오픈 소스 준수 사항)가 적용됩니다. 자세한 내용은 Code of Conduct FAQ(규정 FAQ)를 참조하세요. 또는 추가 질문이나 의견은 opencode@microsoft.com으로 문의하세요.