- 명명법
- 작동 방식
- 데이터베이스 메트릭
- 집계된 메트릭
- 숫자 메트릭
- 일반 메트릭
- Prometheus 메트릭
- 새로운 메트릭 instrumentation 클래스 생성
- Service Ping 메트릭을 instrumentation 클래스로 마이그레이션
- 메트릭 해결 방법
메트릭 인스트루먼테이션 가이드
이 가이드는 메트릭 인스트루먼테이션을 사용하여 서비스 핑 메트릭을 개발하는 방법에 대해 설명합니다.
비디오 자습서는 Instrumentation 클래스를 통한 서비스 핑 메트릭 추가를 참조하세요.
명명법
-
Instrumentation class:
-
DatabaseMetric
,NumbersMetric
또는GenericMetric
중 하나를 상속합니다. - 서비스 피익 메트릭의 값을 계산하는 논리를 구현합니다.
-
-
메트릭 정의 서비스 데이터 메트릭 YAML 정의.
- Hardening: 메서드의 하드닝은 메서드가 안전하게 실패하여 -1과 같은 대체 값을 반환하도록 하는 과정입니다.
작동 방식
메트릭 정의에는 instrumentation_class
필드가 있으며, 이는 클래스로 설정할 수 있습니다.
정의된 instrumentation 클래스는 기존의 메트릭 클래스 중 하나를 상속해야 합니다: DatabaseMetric
, NumbersMetric
또는 GenericMetric
.
Instrumentation 클래스를 사용하면 서비스 핑 생성 전체 프로세스를 파괴하지 않고 각각의 메트릭이 개별적으로 안전하게 실패할 수 있도록 합니다.
데이터베이스 메트릭
참고: 가능한 경우 데이터베이스 메트릭 대신 내부 이벤트 추적을 사용하는 것이 좋습니다. 데이터베이스 메트릭은 큰 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
:start
와finish
값을 캐시 키로 지정하고 캐싱을 설정합니다.start
와finish
가 비용이 많이 드는 쿼리이며 서로 다른 메트릭 계산 사이에 재사용되어야 할 때 이 호출을 사용하세요. -
available?
: 메트릭을 보고해야 하는지 여부를 지정합니다. 기본값은true
입니다. -
timestamp_column
: 선택적으로 메트릭에 사용되는 시간 제약 메트릭을 위한 타임스탬프 열을 지정합니다. 기본값은created_at
입니다.
최적화 권고 및 예시
서비스 핑 메트릭에 대한 단일 쿼리는 캐시가 차가운 상태일 때 1초 미만의 실행 시간을 유지해야 합니다.
- 전문적인 인덱스를 사용하세요. 예시로 다음 병합 요청을 참조하세요:
- 정의된
start
와finish
를 사용하세요. 이러한 값을 메모이제이션하고 재사용할 수 있습니다. 예시로 다음 병합 요청을 참조하세요. - 쿼리에서 조인 및 불필요한 복잡성을 피하세요. 예시로 다음 병합 요청을 참조하세요.
-
distinct_count
에 대한 사용자 정의batch_size
를 설정하세요. 이를 예시 병합 요청에서 확인할 수 있습니다.
데이터베이스 메트릭 예시
계수 예시
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
배치 카운터 예시
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
고유 배치 카운터 예시
# 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
합계 예시
# 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
평균 예시
# 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
예상 배치 카운터
- GitLab 13.7에 소개되었습니다.
예상 배치 카운터 기능은 ActiveRecord::StatementInvalid
오류를 처리합니다.
제공된 estimate_batch_distinct_count
메소드를 통해 사용될 때 발생하는 오류는 -1의 값을 반환합니다.
경고: 이 기능은 주어진 열의 고유한 값을 추정하기 때문에 항상 에러가 포함됩니다.
가장 높게 나타난 오류율은 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
는 조인된 relation을 처리할 수 있습니다. 고유하지 않은 열을 계산하기 위해has_many :boards
와 같이 일대다 관계가 있는 조인된 relation은 반드시 가지고 있으면 안됩니다. -
start
와finish
인수는 항상 다른 열을 참조할지라도 기본 키 관계 값을 나타내야 합니다. 예를 들어:estimate_batch_distinct_count(::Note, :author_id, start: ::Note.minimum(:id), finish: ::Note.maximum(:id))
예시:
-
단순한 예상 배치 카운터의 실행으로
relation
만 제공되며, 반환된 값은Project
relation의id
(기본 키) 열에 있는 유일한 값의 추정치를 나타냅니다:estimate_batch_distinct_count(::Project)
-
예상 배치 카운터의 실행으로, 제공된
relation
에 추가 필터 (.where(time_period)
)가 적용된 경우, 추정된 고유 값의 개수는 사용자 정의 열 (:author_id
)에 추정되며,start
와finish
인수는 제공된 relation의 범위를 분석하는 경계를 적용합니다:estimate_batch_distinct_count(::Note.with_suggestions.where(time_period), :author_id, start: ::Note.minimum(:id), finish: ::Note.maximum(:id))
집계된 메트릭
집계된 메트릭 기능은 예를 들어 가명화된 사용자 ID
와 같은 데이터 속성의 수를 제공하여 이벤트 모음에서 발생한 수를 제공합니다. 예를 들어, 새 이슈를 생성하고 새 병합 요청을 열었는지와 같이 여러 작업을 수행하는 사용자의 수를 집계할 수 있습니다.
집계된 메트릭을 정의하는 데 YAML 파일을 사용할 수 있습니다. 다음 인수들이 필요합니다:
-
options.events
: 메트릭 데이터에 집계할 이벤트 이름 목록입니다. 이 목록의 모든 이벤트는 동일한 데이터 소스를 사용해야 합니다. 추가 데이터 소스 요구 사항에 대해서는 Database sourced aggregated metrics 및 Event sourced aggregated metrics를 참조하세요. -
options.aggregate.attribute
: 이벤트 간에 집계되는 속성을 가리키는 정보입니다. -
time_frame
: 하나 이상의 유효한 시간 프레임입니다. 집계된 메트릭에 포함된 데이터를 특정 날짜 범위의 이벤트로 제한하는 데 사용합니다. 유효한 시간 프레임은 다음과 같습니다:-
7d
: 데이터의 마지막 7일. -
28d
: 데이터의 마지막 28일. -
all
: 모든 과거 데이터,database
소스된 집계된 메트릭에만 해당됩니다.
-
-
data_source
: 집계된 메트릭에 포함된 모든 이벤트 데이터를 수집하는 데 사용되는 데이터 소스입니다. 유효한 데이터 소스는 다음과 같습니다:database
internal_events
-
redis_hll
: RedisHLL을 직접 사용하는 폐기된 메트릭
예시로는 incident_management_alert_status_changed
, incident_management_alert_assigned
, incident_management_alert_todo
, incident_management_alert_create_incident
이벤트 중에 최소한 하나에서 발생한 user.id
의 고유한 수를 세어요.
time_frame: 28d
instrumentation_class: AggregatedMetric
data_source: internal_events
options:
aggregate:
attribute: user.id
events:
- `incident_management_alert_status_changed`
- `incident_management_alert_assigned`
- `incident_management_alert_todo`
- `incident_management_alert_create_incident`
이벤트 소스 별 집계된 메트릭
내부 이벤트로 수집된 이벤트의 집계를 선언할 때, time_frame
에 all
값을 포함하지 않도록하십시오. 이 값은 Redis 소스의 집계된 메트릭에 대해 사용할 수 없습니다.
EE 전용 이벤트를 모든 GitLab 에디션에서 발생하는 이벤트와 함께 집계하는 것은 가능하지만, EE 및 CE GitLab 인스턴스에서 수집된 데이터 사이의 높은 변동을 야기할 수 있음을 기억하는 것이 중요합니다.
데이터베이스 소스 별 집계된 메트릭
데이터베이스에서 수집된 이벤트를 기반으로 한 메트릭의 집계를 선언하려면, 다음 단계를 따르십시오:
메트릭 유지
데이터베이스 소스의 집계된 메트릭을 위해 계산된 메트릭은 예상 배치 카운터로만 계산될 수 있습니다. 메트릭을 유지하려면 estimate_batch_distinct_count
메서드에 루비 블록을 삽입하십시오. 이 블록은 Gitlab::Usage::Metrics::Aggregates::Sources::PostgresHll.save_aggregated_metrics
메서드를 호출해야 합니다. 이 메서드는 미래에 사용될 집계된 메트릭을 저장합니다.
Gitlab::Usage::Metrics::Aggregates::Sources::PostgresHll.save_aggregated_metrics
메서드는 다음 인수를 받습니다:
-
metric_name
: 집계에 사용할 메트릭 이름. 해당 메트릭이 서비스 핑에 추가된 키와 동일해야 합니다. -
recorded_at_timestamp
: 특정 서비스 핑 페이로드가 수집된 순간을 나타내는 타임스탬프.recorded_at
과 같은 편리한 메서드를 사용하여recorded_at_timestamp
인수를 채우셔야 합니다. 예:recorded_at_timestamp: recorded_at
-
time_period
:estimate_batch_distinct_count
에 전달되는relation
인수를 작성하는 데 사용되는 시간 기간. 사용 가능한 모든 이력 데이터로 메트릭을 수집하려면 시간 기간으로nil
값을 설정하십시오. 예:time_period: nil
-
data
:relation
의 고유한 항목을 나타내는 HyperLogLog 버킷 구조.estimate_batch_distinct_count
메서드는 항상 올바른 인수를 블록에 전달하므로,data
인수는 항상 블록 인수와 동일한 값을 가져야 합니다. 예:data: result
메트릭 유지의 예:
class UsageData
def count_secure_pipelines(time_period)
...
relation = ::Security::Scan.by_scan_types(scan_type).where(time_period)
pipelines_with_secure_jobs['dependency_scanning_pipeline'] = estimate_batch_distinct_count(relation, :pipeline_id, batch_size: 1000, start: start_id, finish: finish_id) do |result|
::Gitlab::Usage::Metrics::Aggregates::Sources::PostgresHll
.save_aggregated_metrics(metric_name: 'dependency_scanning_pipeline', recorded_at_timestamp: recorded_at, time_period: time_period, data: result)
end
end
end
새로운 집계된 메트릭 정의 추가
모든 메트릭이 유지된 후, 새로운 집계된 메트릭 정의를 추가할 수 있습니다. 예상 배치 카운터로 수집된 메트릭을 선언하려면 다음 요구 사항을 충족해야 합니다:
-
events:
속성에 나열된 메트릭 이름은 이전 단계에서 메트릭을 유지할 때 사용한 이름과 동일해야 합니다. -
events:
속성에 나열된 각 메트릭은 모든 선택된time_frame:
값에 대해 유지되어야 합니다.
가용성 제한된 집계된 메트릭
집계된 메트릭이 특정 조건 하에 보고서에만 사용 가능해야 하는 경우, 이러한 조건을 AggregatedMetric
클래스의 하위 클래스인 새 클래스에 지정해야 합니다.
# frozen_string_literal: true
module Gitlab
module Usage
module Metrics
module Instrumentations
class MergeUsageCountAggregatedMetric < AggregatedMetric
available? { Feature.enabled?(:merge_usage_data_missing_key_paths) }
end
end
end
end
end
또한 YAML 설정에서 해당 클래스의 이름을 사용해야 합니다.
time_frame: 28d
instrumentation_class: MergeUsageCountAggregatedMetric
data_source: redis_hll
options:
aggregate:
attribute: user.id
events:
- `incident_management_alert_status_changed`
- `incident_management_alert_assigned`
- `incident_management_alert_todo`
- `incident_management_alert_create_incident`
숫자 메트릭
-
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
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 클래스를 사용하면 value
블록에 Prometheus 클라이언트 개체를 전달하여 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
database
및numbers
유형에 필수 사항입니다.-
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
Service Ping 메트릭을 instrumentation 클래스로 마이그레이션
이 안내서에서는 lib/gitlab/usage_data.rb
또는 ee/lib/ee/gitlab/usage_data.rb
에서 Service Ping 메트릭을 instrumentation 클래스로 마이그레이션하는 방법에 대해 설명합니다.
- 메트릭 유형 선택:
-
instrumentation 클래스의 위치 결정:
ee
아래에 있는지 또는ee
바깥에 있는지를 결정합니다. -
instrumentation 클래스 본문 채우기:
- 메트릭에 대한 코드 논리 추가. 이는
usage_data.rb
에서의 메트릭 구현과 유사할 수 있습니다. - 개별 메트릭에 대한 테스트 추가
spec/lib/gitlab/usage/metrics/instrumentations/
. - Service Ping에 대한 테스트 추가.
- 메트릭에 대한 코드 논리 추가. 이는
-
lib/gitlab/usage_data.rb
또는ee/lib/ee/gitlab/usage_data.rb
에서 코드 제거. -
spec/lib/gitlab/usage_data.rb
또는ee/spec/lib/ee/gitlab/usage_data.rb
에서 테스트 제거.
메트릭 해결 방법
가끔은 메트릭이 즉시 명확하지 않은 이유로 실패할 때가 있습니다. 이러한 실패는 성능 문제나 기타 문제와 관련이 있을 수 있습니다. 다음의 페어링 세션 비디오는 실제로 실패한 메트릭에 대한 조사 사례를 제공합니다.