GitLab 애플리케이션 서비스 레벨 지표(SLIs)

서비스 레벨 지표(SLIs)를 Ruby 코드베이스에 직접 정의할 수 있습니다. 이는 운영 및 성공 정의를 구현에 가깝게 유지하고 기능을 구축하는 사람들이 이러한 기능이 모니터링되어야 하는 방법을 쉽게 정의할 수 있도록 합니다.

기존 SLIs

  1. rails_request
  2. global_search_apdex
  3. global_search_error_rate
  4. global_search_indexing_apdex
  5. sidekiq_execution

새로운 SLI 정의하기

SLI는 Gitlab::Metrics::Sli::Apdex 또는 Gitlab::Metrics::Sli::ErrorRate 클래스를 사용하여 정의할 수 있습니다. SLI를 정의하면 Rails 애플리케이션에서 두 개의 Prometheus 카운터가 방출됩니다. 두 카운터는 대체로 같은 방식으로 작동하며 총 작업 수를 포함합니다. Apdex는 성공 비율을 사용하여 성공 비율을 계산하고, ErrorRate는 오류 비율을 사용하여 오류 비율을 계산합니다.

다음 메트릭이 정의됩니다:

  • Gitlab::Metrics::Sli::Apdex.new('foo')는 다음을 정의합니다:
    • gitlab_sli_foo_apdex_total는 측정값의 총 수를 나타냅니다.
    • gitlab_sli_foo_apdex_success_total는 성공적인 측정값의 수를 나타냅니다.
  • Gitlab::Metrics::Sli::ErrorRate.new('foo')는 다음을 정의합니다:
    • gitlab_sli_foo_total는 측정값의 총 수를 나타냅니다.
    • gitlab_sli_foo_error_total는 오류 측정값의 수를 나타냅니다. 이 메트릭은 오류 비율이기 때문에, 오류는 총 수로 나누어집니다.

이 예에서 보듯이, 그들은 기본 이름(foo 이 예제에서)을 공유할 수 있습니다. 이는 동일한 작업을 참조할 때 권장됩니다.

성공적인 작업의 성능을 측정하기 위해 Apdex를 사용해야 합니다. 실패한 요청의 성능을 측정할 필요는 없습니다. 해당 성능은 ErrorRate로 추적되어야 하기 때문입니다. 예를 들어, 요청이 특정 대기 시간 임계값 내에서 수행되는지 측정할 수 있습니다.

불행한 작업의 비율을 측정하기 위해 ErrorRate를 사용해야 합니다. 예를 들어, 실패한 요청이 500 이상인 HTTP 상태를 반환하는지 측정할 수 있습니다.

첫 번째 스크랩 전에는 모든 가능한 라벨 조합으로 SLI를 초기화하는 것이 중요합니다. 이는 이러한 카운터를 계산에 사용할 때 혼란스러운 결과를 피하는 데 도움이 됩니다.

SLI를 초기화하려면 클래스 메서드 .initialize_sli를 사용합니다. 예를 들어:

Gitlab::Metrics::Sli::Apdex.initialize_sli(:received_email, [
  {
    feature_category: :team_planning,
    email_type: :create_issue
  },
  {
    feature_category: :service_desk,
    email_type: :service_desk
  },
  {
    feature_category: :code_review_workflow,
    email_type: :create_merge_request
  }
])

메트릭은 최초로 스크랩되기 전에 초기화되어야 합니다. 이는 현재 on_master_start 생명 주기 이벤트 중에 발생합니다. 이러한 메트릭 초기화가 완료될 때까지 애플리케이션 준비 상태가 지연되므로, 이로 인한 오버헤드가 이해되고 수용 가능한지 확인하세요.

SLI에 대한 작업 추적

새롭게 정의된 SLI에서 작업을 추적하는 방법은 다음과 같습니다:

Gitlab::Metrics::Sli::Apdex[:received_email].increment(
  labels: {
    feature_category: :service_desk,
    email_type: :service_desk
  },
  success: issue_created?
)

이 SLI에서 #increment를 호출하면 전체 Prometheus 카운터가 증가합니다.

gitlab_sli:received_email_apdex:total{ feature_category='service_desk', email_type='service_desk' }

전달된 success: 인수가 참이면 성공 카운터도 증가합니다:

gitlab_sli:received_email_apdex:success_total{ feature_category='service_desk', email_type='service_desk' }

오류율 SLI의 경우, 해당 인수는 error:라고 불립니다:

Gitlab::Metrics::Sli::ErrorRate[:merge].increment(
  labels: {
    merge_type: :fast_forward
  },
  error: !merge_success?
)

서비스 모니터링 및 경고에서 SLI 사용하기

응용 프로그램이 새로운 SLI에 대한 메트릭을 방출할 때, 이들은 메트릭 카탈로그에서 소비되어 경고로 이어지고, 스테이지 그룹 및 GitLab.com의 전반적인 가용성을 위한 오류 예산에 포함되어야 합니다.

새로운 SLI를 Application-SLI 라이브러리에 추가하여 시작하세요.

그 후, 다음 정보를 추가합니다:

  • name: 코드에서 정의된 SLI의 이름. 예를 들어 received_email.

  • significantLabels: 메트릭에 속하는 Prometheus 라벨의 배열. 예: ["email_type"]. SLI의 중요한 라벨에 feature_category가 포함된다면, 메트릭은 스테이지 그룹의 오류 예산에도 입력됩니다.

  • featureCategory: SLI가 단일 기능 카테고리에 적용된다면, 이 필드를 통해 정적으로 지정하여 스테이지 그룹의 오류 예산에 SLI를 입력할 수 있습니다.

  • description: SLI를 설명하는 Markdown 문자열. 대시보드와 경고에 표시됩니다.

  • kind: 지표의 종류. 예: sliDefinition.apdexKind.

작업이 완료되면 make generate를 실행하여 새로운 SLI에 대한 기록 규칙을 생성합니다. 이 명령은 이러한 메트릭을 방출하는 모든 서비스에 대해 significantLabels를 기준으로 집계된 기록을 생성합니다.

이 변경 사항으로 병합 요청을 열고 Scalability 팀 구성원에게 검토를 요청합니다.

이 변경 사항이 병합되고 Mimir에서 기록된 집계 메트릭의 성공 비율을 확인하기 위해 Mimir에 쿼리하세요. 예를 들어:

sum by (environment, stage, type)(application_sli_aggregation:rails_request:apdex:success:rate_1h)
/
sum by (environment, stage, type)(application_sli_aggregation:rails_request:apdex:weight:score_1h)

이는 성공 비율을 나타내며, 이 SLI를 서비스에 추가할 때 적절한 SLO를 설정하는 데 도움이 됩니다.

그런 다음, 해당 서비스 카탈로그 파일에 SLI를 추가합니다. 예를 들어, web 서비스:

rails_requests:
  sliLibrary.get('rails_request_apdex')
    .generateServiceLevelIndicator({ job: 'gitlab-rails' })

추가 선택기를 전달하고 SLI의 속성을 덮어쓰려면 서비스 모니터링 문서를 참조하세요.

정적으로 정의된 기능 카테고리를 가진 SLI는 이미 지정된 Slack 채널에서 SLI에 대한 경고를 받을 수 있습니다. 자세한 내용은 경고 라우팅 문서를 참고하세요.

우리는 이 프로젝트에서 SLI의 feature_category 라벨을 가진 소스 메트릭의 경고도 라우팅할 수 있도록 이 기능을 확장하고 있습니다.

질문이 있으시면 Scalability 이슈 트래커에 이슈를 생성하거나 Slack에서 #g_scalability에서 찾아주세요.