가치 스트림 분석 개발 매뉴얼

가치 스트림 분석(VSA)을 GitLab에서 구성하는 방법에 대한 정보는 분석 문서를 참조하십시오.

가치 스트림 분석이 작동하는 방식은?

가치 스트림 분석은 두 개의 타임스탬프 열 또는 타임스탬프 표현 사이의 기간을 계산하고 데이터에 대해 다양한 집계를 실행합니다.

예를 들면:

  • Merge Request 생성 시간과 Merge Request Merge 시간 간의 기간.
  • 이슈 생성 시간과 이슈 종료 시간 간의 기간.

이 기간은 다양한 방식으로 노출됩니다:

  • 집계: 중앙값, 평균
  • 디렉터리: 개별 Merge Request 및 이슈 레코드의 기간을 나열합니다.

기간 외에, 우리는 단계 내에서 레코드 수를 노출합니다.

기능 가용성

  • 그룹 수준 (라이선스 있음) : Ultimate 또는 Premium 구독이 필요합니다. 이 버전이 가장 많은 기능을 제공합니다.
  • 프로젝트 수준 (라이선스 있음) : 프로젝트 수준 VSA에 기능을 지속적으로 추가하여 그룹 수준 VSA와 일치시킵니다.
  • 프로젝트 수준 (FOSS) : 현재 상태를 유지합니다.
기능 그룹 수준 (라이선스 있음) 프로젝트 수준 (라이선스 있음) 프로젝트 수준 (FOSS)
사용자 정의 가치 스트림 생성 기본 스테이지가 포함된 하나의 가치 스트림만 존재합니다 기본 스테이지가 포함된 하나의 가치 스트림만 존재합니다
사용자 정의 스테이지 생성 아니요 아니요
필터링 (작성자, 레이블, 마일스톤 등)
스테이지 시간 차트 아니요 아니요
총 시간 차트 아니요 아니요
유형별 작업 차트 아니요 아니요
DORA 메트릭 아니요
사이클 타임 및 리드타임 요약 (수명주기 메트릭) 아니요
신규 이슈, 커밋 및 배포 (수명주기 메트릭) 커밋을 제외한 예
집계된 백엔드 사용 아니요 아니요
날짜 필터 동작 항목을 날짜 범위 내에서 완료된으로 필터링합니다 작성 날짜별로 항목을 필터링합니다. 작성 날짜별로 항목을 필터링합니다.
인가 최소한 기자 최소한 기자 공개 될 수 있습니다.

VSA 핵심 도메인 개체

스테이지

스테이지는 시작 및 종료 이벤트 쌍(시작 및 종료 이벤트)을 나타내며 추가 메타데이터(스테이지의 이름 등)를 가지고 있습니다. 스테이지는 백엔드에서 정의된 매칭 규칙 내에서 사용자에 의해 구성 가능합니다.

예시 스테이지: 코드 리뷰

  • 시작 이벤트 식별자: Merge Request 생성 시간.
  • 시작 이벤트 열: merge_requests.created_at 타임스탬프 열을 사용합니다.
  • 종료 이벤트 식별자: Merge Request Merge 시간.
  • 종료 이벤트 열: merge_request_metrics.merged_at 타임스탬프 열을 사용합니다.
  • 스테이지 이벤트 해시 ID: 시작 및 종료 이벤트 식별자 쌍에 대한 계산된 해시입니다.
    • 두 개의 스테이지가 시작 및 종료 이벤트의 구성이 동일하다면, 그들의 스테이지 이벤트 해시 ID는 동일합니다.
    • 스테이지 이벤트 해시 ID는 이후에 분할된 데이터를 저장하는 데 사용됩니다.

과거에는 가치 스트림 분석이 구독 여부와는 무관하게 사용자에게 항상 사용 가능한 여섯 스테이지를 정의했습니다.

가치 스트림

가치 스트림은 스테이지의 컨테이너 개체입니다. DevOps 수명주기의 다른 측면에 중점을 둔 그룹당 여러 가치 스트림이 있을 수 있습니다.

이벤트

이벤트는 가치 스트림 분석 기능의 가장 작은 컴포넌트입니다. 스테이지는 두 가지 이벤트로 구성됩니다:

  • 시작 이벤트
  • 종료 이벤트

이러한 이벤트들은 기간 계산에 중요한 역할을 합니다.

공식: 기간 = 종료 이벤트 시간 - 시작 이벤트 시간

기간 계산을 유연하게 하기 위해 각 이벤트는 별도의 클래스로 구현됩니다. 이들은 계산 쿼리에서 사용되는 타임스탬프 표현을 정의하는 데 책임이 있습니다.

이벤트 클래스 구현

StageEvent 베이스 클래스에서 설명된 몇 가지 메서드를 구현해야 합니다. 가장 중요한 메서드는 다음과 같습니다:

  • object_type
  • timestamp_projection

object_type 메서드는 계산을 위해 어떤 도메인 객체를 쿼리할지 정의합니다. 현재 두 개 모델이 허용됩니다:

  • Issue
  • MergeRequest

기간 계산에는 timestamp_projection 메서드가 사용됩니다.

def timestamp_projection
  # 여기에 타임스탬프 표현을 넣으세요
end

# 이벤트는 기간 계산에 이슈 생성 시간을 사용할 것입니다
def timestamp_projection
  Issue.arel_table[:created_at]
end

더 복잡한 표현도 가능합니다 (예: COALESCE 사용). 예시를 확인하려면 기존 이벤트 클래스를 검토하십시오.

일부 경우에는 timestamp_projection 메서드를 정의하는 것만으로 충분하지 않을 수 있습니다. 계산 쿼리는 타임스탬프 표현이 있는 테이블을 알아야 합니다. 각 이벤트 클래스는 timestamp_projection을 작동하도록 계산 쿼리에 수정을 가집니다. 이는 보통 추가 테이블을 조인하는 것을 의미합니다.

issue_metrics 테이블을 조인하고 first_mentioned_in_commit_at 열을 타임스탬프 표현으로 사용하는 예시입니다.

def object_type
  Issue
end

def timestamp_projection
  IssueMetrics.arel_table[:first_mentioned_in_commit_at]
end

def apply_query_customization(query)
  # 이 경우 쿼리 어트리뷰트는 Issue 모델에 기반하여 생성될 것입니다: `Issue.where(...)`
  query.joins(:metrics)
end

시작 및 종료 이벤트 유효성 검사

일부 시작/종료 이벤트 쌍은 서로 “호환되지” 않을 수 있습니다. 예를 들면:

  • “이슈 생성”에서 “Merge Request 생성”: 이벤트 클래스가 서로 다른 도메인 모델에 정의되어 있어 object_type 메서드가 다릅니다.
  • “이슈 종료”에서 “이슈 생성”: 이슈는 종료되기 전에 생성되어야 합니다.
  • “이슈 종료”에서 “이슈 종료”: 기간은 항상 0입니다.

StageEvents 모듈은 허용되는 start_eventend_event 쌍을 설명합니다 (PAIRING_RULES 상수). 새로운 이벤트를 추가하려면:

  1. Stage 모델에서 enum으로 사용되는 고유 번호로 ENUM_MAPPING에 항목을 추가합니다.
  2. PAIRING_RULES 해시에 이 이벤트와 호환되는 이벤트를 정의합니다.

지원되는 시작/종료 이벤트 쌍:

graph LR; 이슈_생성 --> 이슈_종료; 이슈_생성 --> 이슈_게시판에_최초_추가; 이슈_생성 --> 이슈_마일스톤과_최초_연관_생성; 이슈_생성 --> 커밋에_최초_언급된_이슈_생성; 이슈_생성 --> 이슈_최종_수정; 이슈_생성 --> 이슈_레이블_추가; 이슈_생성 --> 이슈_레이블_제거; 이슈_생성 --> 이슈_최초_할당_시간; Merge_요청_생성 --> Merge_요청_Merge; Merge_요청_생성 --> Merge_요청_종료; Merge_요청_생성 --> Merge_요청_최초_프로덕션_배포; Merge_요청_생성 --> Merge_요청_최종_빌드_시작; Merge_요청_생성 --> Merge_요청_최종_빌드_완료; Merge_요청_생성 --> Merge_요청_최종_수정; Merge_요청_생성 --> Merge_요청_레이블_추가; Merge_요청_생성 --> Merge_요청_레이블_제거; Merge_요청_생성 --> Merge_요청_최초_할당_시간; Merge_요청_최초_할당_시간 --> Merge_요청_종료; Merge_요청_최초_할당_시간 --> Merge_요청_최종_빌드_시작; Merge_요청_최초_할당_시간 --> Merge_요청_최종_수정; Merge_요청_최초_할당_시간 --> Merge_요청_Merge; Merge_요청_최초_할당_시간 --> Merge_요청_레이블_추가; Merge_요청_최초_할당_시간 --> Merge_요청_레이블_제거; Merge_요청_최종_빌드_시작 --> Merge_요청_최종_빌드_완료; Merge_요청_최종_빌드_시작 --> Merge_요청_종료; Merge_요청_최종_빌드_시작 --> Merge_요청_최초_프로덕션_배포; Merge_요청_최종_빌드_시작 --> Merge_요청_최종_수정; Merge_요청_최종_빌드_시작 --> Merge_요청_Merge; Merge_요청_최종_빌드_시작 --> Merge_요청_레이블_추가; Merge_요청_최종_빌드_시작 --> Merge_요청_레이블_제거; Merge_요청_Merge --> Merge_요청_최초_프로덕션_배포; Merge_요청_Merge --> Merge_요청_종료; Merge_요청_Merge --> Merge_요청_최초_프로덕션_배포; Merge_요청_Merge --> Merge_요청_최종_수정; Merge_요청_Merge --> Merge_요청_레이블_추가; Merge_요청_Merge --> Merge_요청_레이블_제거; 이슈_레이블_추가 --> 이슈_레이블_추가; 이슈_레이블_추가 --> 이슈_레이블_제거; 이슈_레이블_추가 --> 이슈_종료; 이슈_레이블_추가 --> 이슈_최초_할당_시간; 이슈_레이블_제거 --> 이슈_종료; 이슈_레이블_제거 --> 이슈_최초_할당_시간; 이슈_게시판에_최초_추가 --> 이슈_종료; 이슈_게시판에_최초_추가 --> 이슈_마일스톤과_최초_연관_생성; 이슈_게시판에_최초_추가 --> 커밋에_최초_언급된_이슈_생성; 이슈_게시판에_최초_추가 --> 이슈_최종_수정; 이슈_게시판에_최초_추가 --> 이슈_레이블_추가 ## 기본 스테이지 가치 스트림 분석의 [초기 구현](https://gitlab.com/gitlab-org/gitlab/-/issues/847)에서는 7개의 스테이지가 정의되었습니다. 이러한 스테이지는 항상 각 부모에 대해 사용할 수 있지만, 이러한 스테이지를 변경하는 것은 불가능합니다. 작업을 효율적으로 만들고 생성된 레코드의 수를 줄이기 위해 기본 스테이지는 메모리 내부 객체(지속되지 않음)로 표현됩니다. 사용자가 처음으로 사용자 정의 스테이지를 생성할 때, 모든 스테이지가 지속됩니다. 이 동작은 가치 스트림 분석 서비스 객체에 구현되어 있습니다. 이러한 이유는 나중에 스테이지를 숨기고 정렬할 수 있는 기능을 추가하고자 했기 때문입니다. ## 데이터 수집기 `DataCollector`는 데이터가 데이터베이스에서 쿼리될 중심 지점입니다. 이 클래스는 항상 단일 스테이지에서 작동하며 다음 컴포넌트로 구성되어 있습니다. - `BaseQueryBuilder`: - 초기 쿼리를 구성하는 데 책임을 집니다. - `Stage`별 구성: 이벤트 및 이들의 쿼리 사용자 정의를 다룸. - UI에서 오는 매개변수: 날짜 범위. - `Median`: `BaseQueryBuilder`에서의 쿼리를 사용하여 스테이지의 중위수 기간을 계산합니다. - `RecordsFetcher`: `BaseQueryBuilder`에서의 쿼리 및 가시성 규칙을 적용하기 위해 특정 `Finder` 클래스를 사용하여 스테이지에 대한 관련 레코드를 로드합니다. - `DataForDurationChart`: 산점도 차트를 위해 완료된 기간과 그 끝 이벤트 타임스탬프로 계산된 기간을 로드합니다. 새로운 계산 또는 쿼리를 지원하려면 `DataCollector` 클래스에서 새로운 메서드 호출로 구현하십시오. 집계된 가치 스트림 분석 백엔드를 지원하기 위해 이러한 클래스들은 [`Aggregated`](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/analytics/cycle_analytics/aggregated) 네임스페이스 내에서 다시 구현되었습니다. ### 데이터베이스 쿼리 백엔드 VSA는 두 가지 백엔드를 지원합니다: 집계된(`aggregated`) 및 "실시간". 실시간 쿼리 백엔드는 어느 순간에는 점진적으로 단계적으로 중단될 수 있습니다. - "실시간": 표준 `IssuableFinders`를 사용합니다. - 집계된: 사전에 집계된 데이터베이스 테이블에서 데이터를 쿼리합니다. ## 고수준 개요 - Rails Controller (`Analytics::CycleAnalytics` 모듈): 가치 스트림 분석은 `analytics` 작업 영역 내에서 구현된 JSON 엔드포인트를 통해 데이터를 노출시킵니다. 또한 스테이지 설정은 JSON 엔드포인트 (CRUD) 내에서 구현됩니다. - Services (`Analytics::CycleAnalytics` 모듈): 모든 `Stage` 관련 작업은 해당 서비스 객체에 위임됩니다. - Models (`Analytics::CycleAnalytics` 모듈): 모델은 `Stage` 객체를 지속시키는 데 사용됩니다. - Feature 클래스 (`Gitlab::Analytics::CycleAnalytics` 모듈): - 쿼리를 구성하고 기능별 비즈니스 로직을 정의하는 책임을 집니다. - `DataCollector`, `Event`, `StageEvents` 등. ## 프런트엔드 [프로젝트 VSA](../user/group/value_stream_analytics/index.md)는 모든 사용자를 대상으로 하며 다음을 포함합니다: - 티어에 따라 키 및 DORA 지표가 혼합되어 있음. - [기본 스테이지](#default-stages)들을 사용합니다. [그룹 VSA](../user/group/value_stream_analytics/index.md)는 라이선스가 있는 사용자만 사용할 수 있으며 다음을 포함합니다: - [개요 스테이지](https://gitlab.com/gitlab-org/gitlab/-/issues/321438). - 사용자 정의 가치 스트림을 만들 수 있는 기능. 그룹 및 프로젝트 수준 VSA 프런트엔드는 모두 Vue와 Vuex로 작성되었으며 유사한 패턴을 따릅니다: - `index.js` 파일은 모든 URL 쿼리 매개변수를 추출하고 Vue 앱과 Vuex 스토어를 생성하고 `initialize` Vuex 액션을 디스패치합니다. - `base.vue` 파일은 각 페이지, 메트릭, 필터, 차트 및 스테이지 테이블을 렌더링하는 데 사용됩니다. 그룹 VSA Vuex 스토어는 [Vuex 모듈](https://vuex.vuejs.org/guide/modules.html)을 사용하여 일부 차트 렌더링에 사용되는 일부 상태와 로직을 분리합니다. ### 공유 컴포넌트 프로젝트 VSA 및 그룹 VSA 간의 일부 UI가 공유될 수 있으며 스테이지 테이블 및 경로와 같은 공유 컴포넌트는 프로젝트 VSA 디렉터리 `app/assets/javascripts/cycle_analytics/components`에 있으며 필요한 경우 그룹 수준 VSA에 포함됩니다. 그룹 수준 기능의 모든 프런트엔드 코드는 `ee/app/assets/javascripts/analytics/cycle_analytics/components`에 있습니다. ## 테스트 많은 이벤트와 가능한 페어링이 있기 때문에 각 페어링을 테스트하는 것은 불가능합니다. 규칙은 `Event` 클래스를 사용한 적어도 하나의 테스트 케이스를 갖는 것입니다. 새로운 `Event`를 사용하여 스테이지에 대한 테스트 케이스를 작성하는 것은 데이터를 두 가지 이벤트로 생성해야 하기 때문에 어려울 수 있습니다. 이를 약간 단순화하기 위해 각 테스트 케이스는 스테이지가 `DataCollector`를 통해 테스트되는 `data_collector_spec.rb`에 구현되어야 합니다. 각 테스트 케이스는 다음 사례를 다루는 여러 테스트로 전환됩니다: - 다른 부모: `그룹` 또는 `프로젝트` - 다른 계산: `중위수`, `RecordsFetcher` 또는 `DataForDurationChart` VSA 프런트엔드는 두 가지 다른 수준(통합, 단위)에서 철저하게 테스트됩니다: - Capybara 및 RSpec를 통해 실제 백엔드를 사용한 end-to-end 통합 테스트. - pre-generated 데이터 fixtures를 사용한 Jest 프런트엔드 테스트. ## 개발 설정 및 테스트 가치 스트림 분석을 실행하는 방법은 [GDK](https://gitlab.com/gitlab-org/gitlab-development-kit)를 통해 수행할 수 있습니다. 기본적으로 프로젝트 수준(FOSS) 버전의 기능을 볼 수 있습니다. GDK가 실행 중이면 시드 스크립트를 실행하여 데이터를 생성할 수 있습니다: ```shell SEED_CYCLE_ANALYTICS=true SEED_VSA=true FILTER=cycle_analytics rake db:seed_fu

데이터 생성 스크립트는 이슈 및 머지 요청 데이터를 가진 새로운 그룹과 새 프로젝트를 만듭니다(스크립트의 출력 참조). 기능의 그룹 수준 버전을 보려면 GDK 인스턴스에 대한 라이선스를 요청해야 합니다.

이 단계 이후에는 그룹 수준 가치 스트림 분석 페이지에 액세스할 수 있으며 가치 스트림과 스테이지를 만들 수 있습니다. 데이터 집계는 지연될 수 있으므로 스테이지 생성 후 바로 데이터를 볼 수 없을 수 있습니다. 이 프로세스를 가속화하기 위해 Rails 콘솔(rails c)에서 다음 명령을 실행할 수 있습니다:

Analytics::CycleAnalytics::ReaggregationWorker.new.perform

시드 데이터

가치 스트림 분석

가치 스트림 분석 데이터를 위한 시드 파일에 대한 지침은 개발 시드 파일을 참조하세요.