콘텐츠로 이동

OpenTelemetry Python

설정

OTEL을 사용해 Trace를 DataKit으로 보내기 전에, 먼저 수집기가 올바르게 구성되어 있는지 확인하세요.

이 페이지에서는 OpenTelemetry에서 Python 자동 계측을 사용하는 방법을 보여줍니다. 예시는 OpenTracing 예제를 기반으로 합니다. opentelemetry-python 저장소에서 이 페이지에서 사용하는 소스 파일을 다운로드하거나 확인할 수 있습니다.

이 예제는 서로 다른 세 개의 스크립트를 사용합니다. 주요 차이는 계측 방식입니다:

  • server_manual.py: 수동 계측.
  • server_automatic.py: 자동 계측.
  • server_programmatic.py: 프로그래밍 방식 계측.

프로그래밍 방식 계측은 애플리케이션에 적은 양의 계측 코드만 추가하면 되는 방식입니다. 일부 계측 라이브러리는 프로그래밍 방식으로 사용할 때 추가 기능을 제공하여, 계측 과정에 대한 제어를 더 많이 할 수 있게 해줍니다.

첫 번째 스크립트(자동 계측 에이전트 미사용)와 두 번째 스크립트(에이전트 사용)를 각각 실행해 보세요. 두 방식은 같은 결과를 내야 하며, 이는 자동 계측 에이전트가 수동 계측과 같은 작업을 수행함을 보여줍니다.

자동 계측은 계측 라이브러리를 통해 런타임에 monkey-patching으로 메서드와 클래스를 동적으로 다시 작성하여, OpenTelemetry를 애플리케이션 코드에 통합하는 작업을 줄여줍니다. 아래에서 Flask 라우트에서 수동, 자동, 프로그래밍 방식 계측의 차이를 볼 수 있습니다.

의존성 설치

아래 demo를 실행하기 전에 먼저 현재 의존성을 설치해야 합니다

pip install opentelemetry-api opentelemetry-instrumentation

자동 계측됨

  • 의존성 설치

pip install opentelemetry-instrumentation-flask

  • server_automatic.py
from flask import Flask, request

app = Flask(__name__)


@app.route("/server_request")
def server_request():
    print(request.args.get("param"))
    return "served"


if __name__ == "__main__":
    app.run(port=8082)
  • 시작

opentelemetry-instrument --service_name auto-instrument-service --traces_exporter console,otlp --metrics_exporter none --exporter_otlp_endpoint http://0.0.0.0:4317 python server_automatic.py

  • 접근

curl http://localhost:8082/server_request?param=automatic

수동 계측됨

  • 의존성 설치

pip install opentelemetry-exporter-otlp-proto-grpc

  • server_manual.py
from flask import Flask, request

from opentelemetry.instrumentation.wsgi import collect_request_attributes
from opentelemetry.propagate import extract
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import (
    BatchSpanProcessor,
    ConsoleSpanExporter,
)
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter

from opentelemetry.trace import (
    SpanKind,
    get_tracer_provider,
    set_tracer_provider,
)

app = Flask(__name__)

set_tracer_provider(TracerProvider())
tracer = get_tracer_provider().get_tracer(__name__)


# ConsoleSpanExporter와 OTLPSpanExporter를 TracerProvider에 추가
get_tracer_provider().add_span_processor(
    BatchSpanProcessor(ConsoleSpanExporter())
)
get_tracer_provider().add_span_processor(
    BatchSpanProcessor(OTLPSpanExporter())
)


@app.route("/server_request")
def server_request():
    with tracer.start_as_current_span(
        "server_request",
        context=extract(request.headers),
        kind=SpanKind.SERVER,
        attributes=collect_request_attributes(request.environ),
    ):
        print(request.args.get("param"))
        return "served"


if __name__ == "__main__":
    app.run(port=8082)
  • 실행

export OTEL_SERVICE_NAME="manual-instrument-service"

python server_manual.py

  • 접근

curl http://localhost:8082/server_request?param=manual

프로그래밍 방식 계측됨

계측 라이브러리(opentelemetry-instrumentation-flask 등)를 개별적으로 사용할 수 있으며, 이 방식은 사용자 정의 옵션을 활용할 수 있다는 장점이 있습니다. 그러나 이 방식을 선택하면 opentelemetry-instrument로 애플리케이션을 시작할 때의 자동 계측은 사용할 수 없습니다. 두 방식은 서로 배타적이기 때문입니다.

  • 의존성 설치

pip install opentelemetry-exporter-otlp-proto-grpc

  • server_programmatic.py
from flask import Flask, request

from opentelemetry.instrumentation.flask import FlaskInstrumentor
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import (
    BatchSpanProcessor,
    ConsoleSpanExporter,
)
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.trace import get_tracer_provider, set_tracer_provider

set_tracer_provider(TracerProvider())
get_tracer_provider().add_span_processor(
    BatchSpanProcessor(ConsoleSpanExporter())
)
get_tracer_provider().add_span_processor(
    BatchSpanProcessor(OTLPSpanExporter())
)

instrumentor = FlaskInstrumentor()

app = Flask(__name__)

instrumentor.instrument_app(app)
# instrumentor.instrument_app(app, excluded_urls="/server_request")


@app.route("/server_request")
def server_request():
    print(request.args.get("param"))
    return "served"


if __name__ == "__main__":
    app.run(port=8082)
  • 실행

export OTEL_SERVICE_NAME="programmatic-instrument-service"

python server_programmatic.py

  • 접근

curl http://localhost:8082/server_request?param=programmatic

문서 평가

이 페이지가 도움이 되었나요?