메트릭스 계측 가이드

이 가이드에서는 메트릭스 계측을 사용하여 서비스 핑(metrics instrumentation) 개발하는 방법을 설명합니다.

비디오 자습서는 계측 클래스를 통한 서비스 핑 메트릭 추가를 참조하세요.

용어

  • 계측 클래스:
    • 메트릭 클래스 중 하나를 상속합니다: DatabaseMetric, NumbersMetric, 또는 GenericMetric.
    • 서비스 핑 메트릭에 대한 값을 계산하는 논리를 구현합니다.
  • 메트릭 정의 서비스 데이터 메트릭 YAML 정의입니다.

  • 하드닝(Hardening): 하드닝은 메소드가 안전하게 실패하고 -1과 같은 폴백 값이 반환되도록 하는 프로세스입니다.

작동 방식

메트릭 정의에는 계측 클래스 필드가 있으며, 이 필드는 클래스로 설정할 수 있습니다.

지정된 계측 클래스는 기존 메트릭 클래스 중 하나를 상속해야 합니다: DatabaseMetric, NumbersMetric, 또는 GenericMetric.

현재의 규칙은 단일 계측 클래스가 단일 메트릭에 해당한다는 것입니다.

계측 클래스를 사용하면 메트릭이 개별적으로 안전하게 실패하여 서비스 핑 생성 전체 프로세스를 방해하지 않을 수 있습니다.

데이터베이스 메트릭

참고: 가능한 경우 데이터베이스 메트릭 대신 내부 이벤트 추적을 사용하는 것이 좋습니다. 데이터베이스 메트릭은 큰 GitLab 인스턴스의 데이터베이스에 불필요한 부하를 일으키며 잠재적인 최적화가 인스턴스 성능에 영향을 줄 수 있습니다.

데이터베이스 메트릭을 사용하여 데이터베이스에 저장된 데이터를 추적할 수 있습니다. 예를 들어 특정 인스턴스에서 존재하는 이슈 수를 세는 것입니다.

  • operation: 지정된 relation에 대한 작업, count, distinct_count, sum, average 중 하나.
  • relation: 수행할 operation을 위해 ActiveRecord::Relation을 반환하는 람다를 할당합니다. 할당된 람다는 최대 한 개의 매개변수를 허용할 수 있습니다. 매개변수는 해싱되어 메트릭 정의의 options 키 아래에 저장됩니다.
  • start: 배치 카운팅의 시작 값을 지정하며, 기본값은 relation.minimum(:id)입니다.
  • finish: 배치 카운팅의 종료 값을 지정하며, 기본값은 relation.maximum(:id)입니다.
  • cache_start_and_finish_as: startfinish 값의 캐시 키를 지정하고 캐싱을 설정합니다. startfinish가 다른 메트릭 계산 사이에서 재사용되어야 하는 비용이 많이 드는 쿼리일 때 이 호출을 사용합니다.
  • available?: 메트릭이 보고되어야 하는지를 지정합니다. 기본값은 true입니다.
  • timestamp_column: 선택적으로 메트릭에 사용되는 타임스탬프 열을 지정합니다. 레코드 필터링에 사용됩니다. 기본값은 created_at입니다.

데이터베이스 메트릭을 추가하는 병합 요청의 예시.

최적화 권장 및 예시

서비스 핑 메트릭을 위한 단일 쿼리는 1초의 실행 시간을 넘지 않아야 합니다(cold caches 기준).

  • 특수 인덱스 사용. 예시는 다음과 같습니다:
  • 정의 된 startfinish 사용. 이러한 값은 메모이제이션되어 재사용될 수 있습니다. 다음과 같은 예시 병합 요청 참조.
  • 쿼리에서 조인 및 불필요한 복잡성을 피하십시오. 다음 예시 병합 요청을 참고하세요.
  • distinct_count에 대한 사용자 정의 batch_size 설정. 예시 병합 요청을 참조하세요.

데이터베이스 메트릭 예시

Count 예시

module Gitlab
  module Usage
    module Metrics
      module Instrumentations
        class CountIssuesMetric < DatabaseMetric
          operation :count

          relation ->(options) { Issue.where(confidential: options[:confidential]) }
        end
      end
    end
  end
end

Batch counters 예시

module Gitlab
  module Usage
    module Metrics
      module Instrumentations
        class CountIssuesMetric < DatabaseMetric
          operation :count

          start { Issue.minimum(:id) }
          finish { Issue.maximum(:id) }

          relation { Issue }
        end
      end
    end
  end
end

Distinct batch counters 예시

# frozen_string_literal: true

module Gitlab
  module Usage
    module Metrics
      module Instrumentations
        class CountUsersAssociatingMilestonesToReleasesMetric < DatabaseMetric
          operation :distinct_count, column: :author_id

          relation { Release.with_milestones }

          start { Release.minimum(:author_id) }
          finish { Release.maximum(:author_id) }
        end
      end
    end
  end
end

Sum 예시

# frozen_string_literal: true

module Gitlab
  module Usage
    module Metrics
      module Instrumentations
        class JiraImportsTotalImportedIssuesCountMetric < DatabaseMetric
          operation :sum, column: :imported_issues_count

          relation { JiraImportState.finished }
        end
      end
    end
  end
end

Average 예시

# frozen_string_literal: true

module Gitlab
  module Usage
    module Metrics
      module Instrumentations
        class CountIssuesWeightAverageMetric < DatabaseMetric
          operation :average, column: :weight

          relation { Issue }
        end
      end
    end
  end
end

예상 배치 카운터

제공된 estimate_batch_distinct_count 메소드를 통해 사용되는 경우 ActiveRecord::StatementInvalid 오류를 처리합니다. 오류는 -1의 값을 반환합니다.

경고: 이 기능은 HyperLogLog 알고리즘을 사용하는 특정 ActiveRecord_Relation의 고유한 값들의 추정된 distinct count를 처리합니다. HyperLogLog 알고리즘은 확률적이므로 결과에 항상 오류가 포함됩니다. 최대 오류율은 4.9%입니다.

올바르게 사용되면 estimate_batch_distinct_count 메소드는 다른 카운터로는 보장할 수 없는 고유하지 않은 값을 포함하는 열에 대한 효율적인 카운팅을 가능하게 합니다.

estimate_batch_distinct_count 메소드

메소드:

estimate_batch_distinct_count(relation, column = nil, batch_size: nil, start: nil, finish: nil)

메소드는 다음과 같은 인수를 포함합니다:

  • relation: 카운트를 수행할 ActiveRecord_Relation입니다.
  • column: 고유한 카운트를 수행할 열입니다. 기본값은 기본 키입니다.
  • batch_size: Gitlab::Database::PostgresHll::BatchDistinctCounter::DEFAULT_BATCH_SIZE에서부터. 기본값: 10,000.
  • start: 복잡한 최소 계산을 피하기 위해 배치 카운트의 사용자 정의 시작 부분입니다.
  • finish: 복잡한 최대 계산을 피하기 위해 배치 카운트의 사용자 정의 끝 부분입니다.

이 메소드에는 다음과 같은 전제조건이 포함됩니다:

  • 제공된 relation은 숫자 열로 정의된 기본 키를 포함해야 합니다. 예: id bigint NOT NULL.
  • estimate_batch_distinct_count는 결합된 관계를 처리할 수 있습니다. 그것의 능력을 사용하려면 고유하지 않은 열을 계산하려는 결합된 관계에는 has_many :boards와 같은 일대다 관계가 없어야 합니다.
  • startfinish 인수는 항상 다른 열을 참조하는 추정 카운트든, 다음과 같이 기본 키 관계 값을 나타내어야 합니다.

      estimate_batch_distinct_count(::Note, :author_id, start: ::Note.minimum(:id), finish: ::Note.maximum(:id))
    

예시:

  1. 관계만 제공하여 추정 배치 카운터를 간단히 실행할 경우, 반환된 값은 Project 관계의 id 열(기본 키)에 있는 고유한 값의 추정 수를 나타냅니다:

      estimate_batch_distinct_count(::Project)
    
  2. 고유한 값 개수가 사용자 지정 열(:author_id)에서 추정되고, startfinish 매개 변수가 함께 제공된 관계의 범위를 정의하는 경계를 적용한 경우, 추가 필터(.where(time_period))를 적용한 제공된 관계에서 추정된 고유한 값의 수입니다:

      estimate_batch_distinct_count(::Note.with_suggestions.where(time_period), :author_id, start: ::Note.minimum(:id), finish: ::Note.maximum(:id))
    

숫자 메트릭

  • operation: 주어진 data 블록에 대한 작업입니다. 현재는 add 작업만 지원됩니다.
  • data: 숫자 배열을 포함하는 block입니다.
  • available?: 메트릭을 보고해야 하는지 여부를 지정합니다. 기본값은 true입니다.
# frozen_string_literal: true

module Gitlab
  module Usage
    module Metrics
      module Instrumentations
        class IssuesBoardsCountMetric < NumbersMetric
          operation :add

          data do |time_frame|
            [
              CountIssuesMetric.new(time_frame: time_frame).value,
              CountBoardsMetric.new(time_frame: time_frame).value
            ]
          end
        end
      end
    end
  end
end

또한 YAML 설정에 instrumentation 클래스 이름을 포함해야 합니다.

time_frame: 28d
instrumentation_class: IssuesBoardsCountMetric

일반적인 메트릭

일반적인 메트릭을 사용하여 다른 메트릭을위한 일반적인 메트릭을 사용할 수 있습니다. 예를 들어 인스턴스의 데이터베이스 버전입니다.

  • value: 메트릭의 값을 지정합니다.
  • available?: 메트릭을 보고해야 하는지 여부를 지정합니다. 기본값은 true입니다.

일반적인 메트릭을 추가하는 병합 요청의 예시.

module Gitlab
  module Usage
    module Metrics
      module Instrumentations
        class UuidMetric < GenericMetric
          value do
            Gitlab::CurrentSettings.uuid
          end
        end
      end
    end
  end
end

Prometheus 메트릭

이 instrumentation 클래스를 사용하여 Prometheus 쿼리를 처리할 수 있으며, value 블록에 첫 번째 인수로 Prometheus 클라이언트 객체를 전달합니다. Prometheus 오류 처리는 블록 자체에서 수행해야 합니다.

  • value: 메트릭의 값을 지정합니다. Prometheus 클라이언트 객체가 첫 번째 인수로 전달됩니다.
  • available?: 메트릭을 보고해야 하는지 여부를 지정합니다. 기본값은 true입니다.

Prometheus 메트릭을 추가하는 병합 요청의 예시.

module Gitlab
  module Usage
    module Metrics
      module Instrumentations
        class GitalyApdexMetric < PrometheusMetric
          value do |client|
            result = client.query('avg_over_time(gitlab_usage_ping:gitaly_apdex:ratio_avg_over_time_5m[1w])').first

            break FALLBACK unless result

            result['value'].last.to_f
          end
        end
      end
    end
  end
end

새로운 메트릭 instrumentation 클래스 생성

제네레이터는 클래스 이름을 전달하고 다음 옵션을 사용합니다:

  • --type=TYPE 필수입니다. 메트릭 유형을 지정합니다. database, generic, redis, numbers 중 하나여야 합니다.
  • --operation databasenumbers 유형에 필수입니다.
    • database의 경우 다음 중 하나여야 합니다: count, distinct_count, estimate_batch_distinct_count, sum, average.
    • numbers의 경우에는 다음이어야 합니다: add.
  • --ee 메트릭이 EE용인 경우 지정합니다.
rails generate gitlab:usage_metric CountIssues --type database --operation distinct_count
        create lib/gitlab/usage/metrics/instrumentations/count_issues_metric.rb
        create spec/lib/gitlab/usage/metrics/instrumentations/count_issues_metric_spec.rb

서비스 핑 메트릭을 instrumentation 클래스로 마이그레이션

이 가이드는 서비스 핑 메트릭을 lib/gitlab/usage_data.rb 또는 ee/lib/ee/gitlab/usage_data.rb에서 instrumentation 클래스로 마이그레이션하는 방법을 설명합니다.

  1. 메트릭 유형을 선택합니다:
  1. instrumentation 클래스의 위치를 결정합니다: ee 아래 또는 ee 외부.

  2. instrumentation 클래스 파일을 생성.

  3. instrumentation 클래스 본문을 작성합니다.

    • 메트릭을위한 코드 로직을 추가합니다. 이는 usage_data.rb에서의 메트릭 구현과 유사할 수 있습니다.
    • 개별 메트릭에 대한 테스트를 추가합니다. spec/lib/gitlab/usage/metrics/instrumentations/를 참조하세요.
    • Service Ping에 대한 테스트를 추가하세요.
  4. 메트릭 정의 파일을 생성.

  5. lib/gitlab/usage_data.rb 또는 ee/lib/ee/gitlab/usage_data.rb에서 코드를 제거합니다.

  6. spec/lib/gitlab/usage_data.rb 또는 ee/spec/lib/ee/gitlab/usage_data.rb에서 테스트를 제거합니다.

메트릭 문제 해결

가끔씩 메트릭이 즉시 명확하지 않은 이유로 인해 실패할 수 있습니다. 이러한 실패는 성능 문제나 다른 문제와 관련이 있을 수 있습니다. 다음 쌍으로 이루어진 세션 비디오는 실제로 실패한 메트릭에 대한 조사 예시를 제공합니다.

비디오 보기: Product Intelligence Office Hours Oct 27th에서 메트릭 문제 해결 프로세스에 대해 자세히 알아보세요.