OpenCensus 측정항목 사용

이 페이지에서는 가용성 및 지연 시간 SLI의 OpenCensus 측정항목을 만드는 기본 사항을 설명합니다. 또한 OpenCensus 측정항목을 사용하여 SLO를 정의하는 방법의 구현 예시를 제공합니다.

OpenCensus 기본 사항

OpenCensusOpenCensus GitHub 페이지에서 제공되는 라이브러리의 단일 오픈소스 배포로, trace와 측정항목을 자동으로 수집하여 백엔드로 전송합니다. OpenCensus를 사용하면 서비스를 계측하여 Cloud Monitoring으로 수집할 수 있는 커스텀 측정항목을 내보낼 수 있습니다. 그런 다음 이 측정항목을 SLI로 사용할 수 있습니다.

OpenCensus를 사용하여 특별히 SLI로 의도하지 않은 Monitoring 측정항목을 만드는 예시는 OpenCensus의 커스텀 측정항목을 참조하세요.

측정항목

OpenCensus를 사용하여 서비스에서 측정항목 데이터를 수집하려면 다음 OpenCensus 구성을 사용해야 합니다.

  • Measure: 기록할 측정항목 유형을 나타내며 측정항목 이름으로 지정됩니다. Measure는 Int64 또는 Float64 값을 기록할 수 있습니다.
  • Measurement: 특정 이벤트에 대해 Measure에서 수집 및 기록한 특정 데이터 포인트를 기록합니다. 예를 들어 Measurement는 특정 응답의 지연 시간을 기록할 수 있습니다.
  • View: Measure에 적용되는 집계를 지정합니다. OpenCensus는 다음 집계 유형을 지원합니다.
    • 개수: 측정 지점 수입니다.
    • 분포: 측정 지점의 히스토그램 분포입니다.
    • 합계: 측정 값의 합계입니다.
    • LastValue: 측정을 통해 기록된 마지막 값입니다.

자세한 내용은 OpenCensus 통계/측정항목을 참조하세요. OpenCensus는 측정항목을 주로 통계라고 지칭합니다.

도구 작동

OpenCensus 라이브러리는 여러 언어로 제공됩니다. 측정항목을 내보내기 위한 서비스 계측에 대한 언어별 정보는 OpenCensus 언어 지원을 참조하세요. 또한 OpenCensus를 사용한 커스텀 측정항목에서는 Monitoring에서 일반적으로 사용되는 언어의 예시를 제공합니다.

기본 사례에서는 다음을 수행해야 합니다.

  • 측정항목을 기록하여 내보내도록 서비스를 계측합니다.
  • 측정항목을 수신할 내보내기를 정의합니다.

측정항목마다 값 유형(Int64 또는 Float64)을 지정하려면 Measure를 정의해야 합니다. 또한 View를 정의하고 등록하여 집계 유형(개수, 분포, 합계 또는 마지막 값)을 지정해야 합니다. 분산 집계 유형을 사용하려면 히스토그램 버킷 경계를 명시적으로 지정해야 합니다. View에 측정항목 이름을 지정할 수도 있습니다.

내보내기 도구

마지막으로 내보내기를 사용하여 측정항목을 수집하고 Cloud Monitoring 또는 다른 백엔드에 기록해야 합니다. Monitoring에 사용할 수 있는 언어별 내보내기는 OpenCensus 내보내기를 참조하세요.

고유한 내보내기를 작성할 수도 있습니다. 자세한 내용은 커스텀 내보내기 작성을 참조하세요.

SLI 측정항목 만들기

애플리케이션은 Cloud Monitoring에서 SLI로 사용할 수 있는 OpenCensus 측정항목을 만들어야 합니다.

  • 요청 개수와 오류 개수에 대한 가용성 SLI의 경우 개수 집계와 함께 Measure를 사용합니다.
  • 지연 시간 SLI의 경우 분포 집계와 함께 Measure를 사용합니다.

가용성 SLI 측정항목

Cloud Monitoring API에서 TimeSeriesRatio 구조를 사용하여 총 요청에 대한 '양호' 또는 '불량' 요청의 비율을 설정해 요청 기반 가용성 SLI를 표현합니다. 이 비율은 RequestBasedSli 구조의 goodTotalRatio 필드에서 사용됩니다.

애플리케이션에서 이 비율을 구성하는 데 사용할 수 있는 OpenCensus 측정항목을 만들어야 합니다. 애플리케이션에서 다음 중 최소 두 개 이상을 만들어야 합니다.

  1. 총 이벤트 수를 계산하는 측정항목. 비율의 totalServiceFilter에서 이 측정항목을 사용합니다.

    개수 집계를 사용하는 Int64 유형의 OpenCensus 측정항목을 만들 수 있습니다. 여기서 모든 수신된 요청에 1 값을 기록합니다.

  2. '불량' 이벤트를 계산하는 측정항목. 비율의 badServiceFilter에서 이 측정항목을 사용합니다.

    개수 집계를 사용하는 Int64 유형의 OpenCensus 측정항목을 만들 수 있습니다. 여기서 모든 오류나 실패한 요청에 1 값을 기록합니다.

  3. '양호' 이벤트를 계산하는 측정항목. 비율의 goodServiceFilter에서 이 측정항목을 사용합니다.

    개수 집계를 사용하는 Int64 유형의 OpenCensus 측정항목을 만들 수 있습니다. 여기서 모든 성공한 응답에 1 값을 기록합니다.

지연 시간 SLI 측정항목

Cloud Monitoring API에서 DistributionCut 구조를 사용하여 요청 기반 지연 시간 SLI를 표현합니다. 이 구조는 RequestBasedSli 구조의 distributionCut 필드에서 사용됩니다.

분포 집계 유형을 사용하여 View가 포함된 Int64 또는 Float64 Measure를 만들 수 있습니다. 버킷 경계를 명시적으로 정의해야 합니다. 원하는 기준점 내에 있는 요청 비율을 정확하게 측정할 수 있게 해주는 방식으로 버킷을 정의하는 것이 중요합니다. 이 주제에 대한 자세한 내용은 사이트 안정성 엔지니어링 통합문서SLO 구현을 참조하세요.

구현 예시

이 섹션에서는 Node.js에서 OpenCensus를 사용하여 기본 가용성 및 지연 시간 SLI의 측정항목을 구현하는 예시를 보여줍니다.

도구 작동

OpenCensus를 사용하여 측정항목을 내보내도록 서비스를 계측하려면 다음 단계를 따르세요.

  1. 필요한 라이브러리를 포함합니다.

    Go

    Monitoring에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

    import (
    	"flag"
    	"fmt"
    	"log"
    	"math/rand"
    	"net/http"
    	"time"
    
    	"contrib.go.opencensus.io/exporter/stackdriver"
    	"go.opencensus.io/stats"
    	"go.opencensus.io/stats/view"
    	"go.opencensus.io/tag"
    )
    

    Node.js

    Monitoring에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

    // opencensus setup
    const {globalStats, MeasureUnit, AggregationType} = require('@opencensus/core');
    const {StackdriverStatsExporter} = require('@opencensus/exporter-stackdriver');

    Python

    Monitoring에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

    from flask import Flask
    from opencensus.ext.prometheus import stats_exporter as prometheus
    from opencensus.stats import aggregation as aggregation_module
    from opencensus.stats import measure as measure_module
    from opencensus.stats import stats as stats_module
    from opencensus.stats import view as view_module
    from opencensus.tags import tag_map as tag_map_module
    
    from prometheus_flask_exporter import PrometheusMetrics
    
  2. 내보내기를 정의하고 등록합니다.

    Go

    Monitoring에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

    // Sets up Cloud Monitoring exporter.
    sd, err := stackdriver.NewExporter(stackdriver.Options{
    	ProjectID:         *projectID,
    	MetricPrefix:      "opencensus-demo",
    	ReportingInterval: 60 * time.Second,
    })
    if err != nil {
    	log.Fatalf("Failed to create the Cloud Monitoring exporter: %v", err)
    }
    defer sd.Flush()
    
    sd.StartMetricsExporter()
    defer sd.StopMetricsExporter()

    Node.js

    Monitoring에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

    // Stackdriver export interval is 60 seconds
    const EXPORT_INTERVAL = 60;
    const exporter = new StackdriverStatsExporter({
      projectId: projectId,
      period: EXPORT_INTERVAL * 1000,
    });
    globalStats.registerExporter(exporter);

    Python

    Monitoring에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

    def setup_openCensus_and_prometheus_exporter() -> None:
        stats = stats_module.stats
        view_manager = stats.view_manager
        exporter = prometheus.new_stats_exporter(prometheus.Options(namespace="oc_python"))
        view_manager.register_exporter(exporter)
        register_all_views(view_manager)
  3. 측정항목마다 Measure를 정의합니다.

    Go

    Monitoring에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

    // Sets up metrics.
    var (
    	requestCount       = stats.Int64("oc_request_count", "total request count", "requests")
    	failedRequestCount = stats.Int64("oc_failed_request_count", "count of failed requests", "requests")
    	responseLatency    = stats.Float64("oc_latency_distribution", "distribution of response latencies", "s")
    )
    

    Node.js

    Monitoring에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

    const REQUEST_COUNT = globalStats.createMeasureInt64(
      'request_count',
      MeasureUnit.UNIT,
      'Number of requests to the server'
    );
    const ERROR_COUNT = globalStats.createMeasureInt64(
      'error_count',
      MeasureUnit.UNIT,
      'Number of failed requests to the server'
    );
    const RESPONSE_LATENCY = globalStats.createMeasureInt64(
      'response_latency',
      MeasureUnit.MS,
      'The server response latency in milliseconds'
    );

    Python

    Monitoring에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

    m_request_count = measure_module.MeasureInt(
        "python_request_count", "total requests", "requests"
    )
    m_failed_request_count = measure_module.MeasureInt(
        "python_failed_request_count", "failed requests", "requests"
    )
    m_response_latency = measure_module.MeasureFloat(
        "python_response_latency", "response latency", "s"
    )
  4. 적절한 집계 유형이 있는 각 Measure에 그리고 응답 지연 시간, 버킷 경계에 View를 정의하고 등록합니다.

    Go

    Monitoring에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

    // Sets up views.
    var (
    	requestCountView = &view.View{
    		Name:        "oc_request_count",
    		Measure:     requestCount,
    		Description: "total request count",
    		Aggregation: view.Count(),
    	}
    	failedRequestCountView = &view.View{
    		Name:        "oc_failed_request_count",
    		Measure:     failedRequestCount,
    		Description: "count of failed requests",
    		Aggregation: view.Count(),
    	}
    	responseLatencyView = &view.View{
    		Name:        "oc_response_latency",
    		Measure:     responseLatency,
    		Description: "The distribution of the latencies",
    		// Bucket definitions must be explicitly specified.
    		Aggregation: view.Distribution(0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000),
    	}
    )
    
    	// Register the views.
    	if err := view.Register(requestCountView, failedRequestCountView, responseLatencyView); err != nil {
    		log.Fatalf("Failed to register the views: %v", err)
    	}

    Node.js

    Monitoring에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

    const request_count_metric = globalStats.createView(
      'request_count_metric',
      REQUEST_COUNT,
      AggregationType.COUNT
    );
    globalStats.registerView(request_count_metric);
    const error_count_metric = globalStats.createView(
      'error_count_metric',
      ERROR_COUNT,
      AggregationType.COUNT
    );
    globalStats.registerView(error_count_metric);
    const latency_metric = globalStats.createView(
      'response_latency_metric',
      RESPONSE_LATENCY,
      AggregationType.DISTRIBUTION,
      [],
      'Server response latency distribution',
      // Latency in buckets:
      [0, 1000, 2000, 3000, 4000, 5000, 10000]
    );
    globalStats.registerView(latency_metric);

    Python

    Monitoring에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

    # set up views
    latency_view = view_module.View(
        "python_response_latency",
        "The distribution of the latencies",
        [],
        m_response_latency,
        aggregation_module.DistributionAggregation(
            [0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000]
        ),
    )
    
    request_count_view = view_module.View(
        "python_request_count",
        "total requests",
        [],
        m_request_count,
        aggregation_module.CountAggregation(),
    )
    
    failed_request_count_view = view_module.View(
        "python_failed_request_count",
        "failed requests",
        [],
        m_failed_request_count,
        aggregation_module.CountAggregation(),
    )
    
    # register views
    def register_all_views(view_manager: stats_module.stats.view_manager) -> None:
        view_manager.register_view(latency_view)
        view_manager.register_view(request_count_view)
        view_manager.register_view(failed_request_count_view)
  5. 요청 개수 및 오류 개수 측정항목의 값을 기록합니다.

    Go

    Monitoring에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

    // Counts the request.
    stats.Record(ctx, requestCount.M(1))
    
    // Randomly fails 10% of the time.
    if rand.Intn(100) >= 90 {
    	// Counts the error.
    	stats.Record(ctx, failedRequestCount.M(1))

    Node.js

    Monitoring에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

    // record a request count for every request
    globalStats.record([
      {
        measure: REQUEST_COUNT,
        value: 1,
      },
    ]);
    
    // randomly throw an error 10% of the time
    const randomValue = Math.floor(Math.random() * 9 + 1);
    if (randomValue === 1) {
      // Record a failed request.
      globalStats.record([
        {
          measure: ERROR_COUNT,
          value: 1,
        },
      ]);

    Python

    Monitoring에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

    mmap = stats_recorder.new_measurement_map()
    # count request
    mmap.measure_int_put(m_request_count, 1)
    # fail 10% of the time
    if random.randint(0, 100) > 90:
        mmap.measure_int_put(m_failed_request_count, 1)
        tmap = tag_map_module.TagMap()
        mmap.record(tmap)
        return ("error!", 500)
  6. 지연 시간 값을 기록합니다.

    Go

    Monitoring에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

    requestReceived := time.Now()
    // Records latency for failure OR success.
    defer func() {
    	stats.Record(ctx, responseLatency.M(time.Since(requestReceived).Seconds()))
    }()

    Node.js

    Monitoring에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

    globalStats.record([
      {
        measure: RESPONSE_LATENCY,
        value: stopwatch.elapsedMilliseconds,
      },
    ]);

    Python

    Monitoring에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

    start_time = time.perf_counter()
    mmap = stats_recorder.new_measurement_map()
    if random.randint(0, 100) > 90:
        response_latency = time.perf_counter() - start_time
        mmap.measure_float_put(m_response_latency, response_latency)
        tmap = tag_map_module.TagMap()
        mmap.record(tmap)

수집된 측정항목

측정항목을 Cloud Monitoring으로 내보내면 측정항목이 OpenCensus에서 시작했음을 나타내는 프리픽스가 포함된 측정항목 유형으로 표시됩니다. 예를 들어 Node.js 구현에서 각 OpenCensus View의 이름은 다음과 같이 매핑됩니다.

  • request_count_slicustom.googleapis.com/opencensus/request_count_sli가 됩니다.
  • error_count_slicustom.googleapis.com/opencensus/error_count_sli가 됩니다.
  • response_latency_slicustom.googleapis.com/opencensus/response_latency_sli가 됩니다.

서비스가 실행된 후 측정항목 탐색기에서 측정항목을 검색하여 측정항목이 Monitoring으로 수집되고 있는지 확인할 수 있습니다.

가용성 SLI

Cloud Monitoring에서 TimeSeriesRatio 구조를 사용하여 요청 기반 가용성 SLI를 표현합니다. 다음 예시에서는 수집된 OpenCensus 측정항목을 사용하고 28일 동안 request_count_sli에 대한 error_count_sli 비율을 계산하여 서비스가 98% 가용성이라고 예상하는 SLO를 보여줍니다.

{
  "serviceLevelIndicator": {
    "requestBased": {
      "goodTotalRatio": {
        "totalServiceFilter":
          "metric.type=\"custom.googleapis.com/opencensus/request_count_sli\",
       "badServiceFilter":
          "metric.type=\"custom.googleapis.com/opencensus/error_count_sli\"
      }
    }
  },
  "goal": 0.98,
  "rollingPeriod": "2419200s",
  "displayName": "98% Availability, rolling 28 days"
}

지연 시간 SLI

Cloud Monitoring에서 DistributionCut 구조를 사용하여 요청 기반 지연 시간 SLI를 표현합니다. 다음 예시에서는 수집된 OpenCensus 지연 시간 측정항목을 사용하고 요청의 98%가 1일 동안 1000ms 이내로 완료된다고 예상하는 SLO를 보여줍니다.

{
  "serviceLevelIndicator": {
    "requestBased": {
      "distributionCut": {
        "distributionFilter":
          "metric.type=\"custom.googleapis.com/opencensus/response_latency_sli\",
        "range": {
          "min": 0,
          "max": 1000
        }
      }
    }
  },
  "goal": 0.98,
  "rollingPeriod": "86400s",
  "displayName": "98% requests under 1000 ms"
}