가치 스트림 분석 개발 매뉴얼
가치 스트림 분석(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
메서드는 계산을 위해 어떤 도메인 객체를 쿼리할지 정의합니다. 현재 두 개 모델이 허용됩니다:
기간 계산에는 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_event
및 end_event
쌍을 설명합니다 (PAIRING_RULES
상수).
새로운 이벤트를 추가하려면:
-
Stage
모델에서 enum
으로 사용되는 고유 번호로 ENUM_MAPPING
에 항목을 추가합니다.
-
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
시드 데이터
가치 스트림 분석
가치 스트림 분석 데이터를 위한 시드 파일에 대한 지침은 개발 시드 파일을 참조하세요.