Python으로 trace 및 측정항목 생성

이 문서에서는 오픈소스 OpenTelemetry 프레임워크를 사용하여 trace 및 측정항목 데이터를 수집하도록 Python 앱을 수정하는 방법과 구조화된 JSON 로그를 표준 출력에 작성하는 방법을 설명합니다. 설치 및 실행할 수 있는 샘플 Python 앱에 대한 정보도 제공합니다. 이 앱은 Flask 웹 프레임워크를 사용하며 측정항목, trace, 로그를 생성하도록 구성됩니다.

계측에 대한 자세한 내용은 다음 문서를 참조하세요.

수동 계측 및 자동 계측 안내

이 언어의 경우 OpenTelemetry는 자동 계측을 코드를 변경하지 않고 라이브러리 및 프레임워크에서 원격 분석을 수집하는 방법으로 정의합니다. 그러나 설치 모듈이 있고 환경 변수를 설정해야 합니다.

이 문서에서는 자동 계측에 대해 설명하지 않습니다. 해당 주제에 대해서는 Python용 자동 계측을 참조하세요.

일반적인 정보는 Python용 OpenTelemetry 계측을 참조하세요.

시작하기 전에

Enable the Cloud Logging, Cloud Monitoring, and Cloud Trace APIs.

Enable the APIs

앱을 계측하여 trace, 측정항목, 로그 수집

trace 및 측정항목 데이터를 수집하고 구조화된 JSON을 표준 출력에 작성하도록 앱을 계측하려면 이 문서의 이어지는 섹션에 설명된 대로 다음 단계를 수행합니다.

  1. OpenTelemetry 구성
  2. 구조화된 로깅 구성

OpenTelemetry 구성

이 예시 앱은 OpenTelemetry Python SDK를 사용하여 OTLP 프로토콜로 trace 및 측정항목을 내보내도록 구성됩니다. 기본적으로 OpenTelemetry Python SDK는 W3C Trace Context 형식을 trace 컨텍스트 전파에 사용하므로 trace 내에서 스팬의 상하위 관계가 올바르게 유지됩니다.

다음 코드 샘플은 OpenTelemetry를 설정하는 Python 모듈을 보여줍니다. 전체 샘플을 보려면 더보기를 클릭한 다음 GitHub에서 보기를 선택합니다.

resource = Resource.create(attributes={
    # Use the PID as the service.instance.id to avoid duplicate timeseries
    # from different Gunicorn worker processes.
    SERVICE_INSTANCE_ID: f"worker-{os.getpid()}",
})

traceProvider = TracerProvider(resource=resource)
processor = BatchSpanProcessor(OTLPSpanExporter())
traceProvider.add_span_processor(processor)
trace.set_tracer_provider(traceProvider)

reader = PeriodicExportingMetricReader(
    OTLPMetricExporter()
)
meterProvider = MeterProvider(metric_readers=[reader], resource=resource)
metrics.set_meter_provider(meterProvider)

Flask 앱은 Flask의 프로덕션에 배포하기 가이드에 있는 권장사항에 따라 Gunicorn을 사용하여 HTTP 요청을 처리합니다. Gunicorn은 처리량을 늘리기 위해 독립 작업자 프로세스에서 실행되는 앱의 여러 사본을 시작합니다. 여러 작업자 프로세스의 측정항목이 서로 충돌하지 않도록 작업자 프로세스마다 service.instance.id 리소스 속성에 고유한 값을 설정하는 것이 좋습니다. 이렇게 하는 방법 중 하나는 service.instance.id에 프로세스 ID를 포함하는 것입니다. 자세한 내용은 시계열 충돌을 참조하세요.

자세한 내용 및 구성 옵션은 OpenTelemetry Python 계측을 참조하세요.

구조화된 로깅 구성

trace에 연결된 구조화된 로그를 작성하려면 trace 정보가 포함된 키와 함께 JSON 형식의 로그를 표준 출력으로 내보내도록 앱을 구성합니다. 다음 코드 샘플은 python-json-logger 라이브러리를 사용하여 구조화된 JSON 로그를 출력하도록 표준 logging 라이브러리를 구성하는 방법 및 opentelemetry-instrumentation-logging 패키지를 사용하여 trace 정보를 포함하는 방법을 보여줍니다.

LoggingInstrumentor().instrument()

logHandler = logging.StreamHandler()
formatter = jsonlogger.JsonFormatter(
    "%(asctime)s %(levelname)s %(message)s %(otelTraceID)s %(otelSpanID)s %(otelTraceSampled)s",
    rename_fields={
        "levelname": "severity",
        "asctime": "timestamp",
        "otelTraceID": "logging.googleapis.com/trace",
        "otelSpanID": "logging.googleapis.com/spanId",
        "otelTraceSampled": "logging.googleapis.com/trace_sampled",
        },
    datefmt="%Y-%m-%dT%H:%M:%SZ",
)
logHandler.setFormatter(formatter)
logging.basicConfig(
    level=logging.INFO,
    handlers=[logHandler],
)

이전 구성은 로그 메시지에서 활성 스팬에 대한 정보를 추출한 후 해당 정보를 구조화된 JSON 로그에 속성으로 추가합니다. 그런 다음, 다음 속성을 사용하여 로그와 trace의 상관관계를 보여줄 수 있습니다.

  • logging.googleapis.com/trace: 로그 항목과 연결된 trace의 리소스 이름입니다.
  • logging.googleapis.com/spanId: 로그 항목과 연결된 trace가 있는 스팬 ID입니다.
  • logging.googleapis.com/trace_sampled: 이 필드의 값은 true 또는 false여야 합니다.

이러한 필드에 대한 자세한 내용은 LogEntry 구조를 참조하세요.

원격 분석을 수집하도록 구성된 샘플 앱 실행

예시 앱은 로그용 JSON, 측정항목 및 trace용 OTLP를 포함하여 공급업체 중립적인 형식을 사용합니다. 앱의 원격 분석은 Google 내보내기 도구로 구성된 OpenTelemetry Collector를 사용하여 Google Cloud로 라우팅됩니다. Flask를 사용하여 HTTP 요청을 처리하고 요청 라이브러리를 사용하여 HTTP 요청을 수행합니다. 예시 앱은 HTTP 클라이언트 및 서버에 대한 측정항목과 trace를 생성하기 위해 예제 앱은 opentelemetry-instrumentation-flaskopentelemetry-instrumentation-requests 계측 라이브러리를 설치합니다.

logger = logging.getLogger(__name__)

app = Flask(__name__)
FlaskInstrumentor().instrument_app(app)
RequestsInstrumentor().instrument()

이 앱에는 2개의 엔드포인트가 있습니다.

  • /multi 엔드포인트는 multi 함수로 처리됩니다. 앱의 부하 생성기는 /multi 엔드포인트로 요청을 보냅니다. 이 엔드포인트가 요청을 수신하면 로컬 서버의 /single 엔드포인트로 3~7개의 요청을 보냅니다.

    @app.route('/multi')
    def multi():
        """Handle an http request by making 3-7 http requests to the /single endpoint."""
        subRequests = randint(3, 7)
        logger.info("handle /multi request", extra={'subRequests': subRequests})
        for _ in range(subRequests):
            requests.get(url_for('single', _external=True))
        return 'ok'
  • /single 엔드포인트는 single 함수로 처리됩니다. 이 엔드포인트가 요청을 수신하면 짧은 지연 동안 절전 모드로 전환된 후 문자열로 응답합니다.

    @app.route('/single')
    def single():
        """Handle an http request by sleeping for 100-200 ms, and write the number of seconds slept as the response."""
        duration = uniform(0.1, 0.2)
        time.sleep(duration)
        return f'slept {duration} seconds'

앱 다운로드 및 배포

샘플을 실행하려면 다음을 수행합니다.

  1. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  2. 저장소를 복제합니다.

    git clone https://github.com/GoogleCloudPlatform/opentelemetry-operations-python
    
  3. 샘플 디렉터리로 이동합니다.

    cd opentelemetry-operations-python/samples/instrumentation-quickstart
    
  4. 샘플을 빌드하고 실행합니다.

    docker compose up --abort-on-container-exit
    

    Cloud Shell에서 실행하지 않는 경우 사용자 인증 정보 파일을 가리키는 GOOGLE_APPLICATION_CREDENTIALS 환경 변수를 사용하여 애플리케이션을 실행합니다. 애플리케이션 기본 사용자 인증 정보$HOME/.config/gcloud/application_default_credentials.json에서 사용자 인증 정보 파일을 제공합니다.

    # Set environment variables
    export GOOGLE_CLOUD_PROJECT="PROJECT_ID"
    export GOOGLE_APPLICATION_CREDENTIALS="$HOME/.config/gcloud/application_default_credentials.json"
    export USERID="$(id -u)"
    
    # Run
    docker compose -f docker-compose.yaml -f docker-compose.creds.yaml up --abort-on-container-exit
    

측정항목 보기

샘플 앱의 OpenTelemetry 계측은 측정항목 탐색기를 사용하여 볼 수 있는 Prometheus 측정항목을 생성합니다.

  • Prometheus/http_server_duration_milliseconds/histogram은 서버 요청 기간을 기록하고 결과를 히스토그램에 저장합니다.

  • Prometheus/http_client_duration_milliseconds/histogram은 클라이언트 요청 기간을 기록하고 결과를 히스토그램에 저장합니다.

샘플 앱에서 생성된 측정항목을 보려면 다음을 실행합니다.
  1. Google Cloud 콘솔에서  측정항목 탐색기 페이지로 이동합니다.

    측정항목 탐색기로 이동

    검색창을 사용하여 이 페이지를 찾은 경우 부제목이 Monitoring인 결과를 선택합니다.

  2. 측정항목 요소에서 측정항목 선택 메뉴를 펼치고 필터 표시줄에 http_server을 입력한 후 하위 메뉴를 사용하여 특정 리소스 유형과 측정항목을 선택합니다.
    1. 활성 리소스 메뉴에서 Prometheus 대상을 선택합니다.
    2. 활성 측정항목 카테고리 메뉴에서 Http를 선택합니다.
    3. 활성 측정항목 메뉴에서 측정항목을 선택합니다.
    4. 적용을 클릭합니다.
  3. 데이터를 보는 방법을 구성합니다.

    측정항목의 측정값이 누적되면 측정항목 탐색기는 측정된 데이터를 정렬 기간에 따라 자동으로 정규화하므로 차트에 비율이 표시됩니다. 자세한 내용은 종류, 유형, 변환을 참조하세요.

    두 개의 counter 측정항목과 같이 정수 값 또는 Double 값이 측정되면 측정항목 탐색기가 모든 시계열을 자동으로 합산합니다. /multi/single HTTP 경로의 데이터를 보려면 집계 항목의 첫 번째 메뉴를 없음으로 설정합니다.

    차트 구성에 대한 자세한 내용은 측정항목 탐색기 사용 시 측정항목 선택을 참조하세요.

trace 보기

trace 데이터를 보려면 다음을 수행합니다.

  1. Google Cloud 콘솔에서 Trace 탐색기 페이지로 이동합니다.

    Trace 탐색기로 이동

    검색창을 사용하여 이 페이지를 찾을 수도 있습니다.

  2. 분산형 차트에서 URI가 /multi인 trace를 선택합니다.
  3. trace 세부정보 패널의 Gantt 차트에서 /multi 라벨이 지정된 스팬을 선택합니다.

    HTTP 요청에 대한 정보가 표시된 패널이 열립니다. 이러한 세부정보에는 메서드, 상태 코드, 바이트 수, 호출자의 사용자 에이전트가 포함됩니다.

  4. 이 trace와 연결된 로그를 보려면 로그 및 이벤트 탭을 선택합니다.

    탭에는 개별 로그가 표시됩니다. 로그 항목의 세부정보를 보려면 로그 항목을 펼칩니다. 로그 보기를 클릭하고 로그 탐색기를 사용하여 로그를 볼 수도 있습니다.

Cloud Trace 탐색기 사용에 대한 자세한 내용은 trace 찾기 및 탐색을 참조하세요.

로그 보기

로그 탐색기에서 로그를 검사할 수 있으며 연결된 trace가 있는 경우 이를 볼 수도 있습니다.

  1. Google Cloud 콘솔에서 로그 탐색기 페이지로 이동합니다.

    로그 탐색기로 이동

    검색창을 사용하여 이 페이지를 찾은 경우 부제목이 Logging인 결과를 선택합니다.

  2. handle /multi request라는 설명이 포함된 로그를 찾습니다.

    로그 세부정보를 보려면 로그 항목을 확장합니다.

  3. 'handle /multi request' 메시지가 있는 로그 항목에서 trace를 클릭한 후 trace 세부정보 보기를 선택합니다.

    trace 세부정보 패널이 열리고 선택한 trace가 표시됩니다.

로그 탐색기 사용에 대한 자세한 내용은 로그 탐색기를 사용하여 로그 보기를 참조하세요.

다음 단계