GitLab 응용 프로그램 서비스 수준 지표 (SLI)

Ruby 코드베이스에서 Service Level Indicators(SLIs)를 직접 정의할 수 있습니다. 이를 통해 작업의 정의를 구현과 가깝게 유지하고 기능을 구축하는 사람들이 이러한 기능을 어떻게 모니터링할지 쉽게 정의할 수 있습니다.

기존 SLIs

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

새 SLI 정의

Gitlab::Metrics::Sli::Apdex 또는 Gitlab::Metrics::Sli::ErrorRate 클래스로 SLI를 정의할 수 있습니다. 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 life-cycle event 중에 발생합니다. 이로 인해 메트릭 초기화가 반환되기 전까지 애플리케이션 준비 상태가 지연되므로, 이로 인한 추가 부담이 이해되고 수용 가능한지 확인하십시오.

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에 대한 메트릭을 발행하는 경우, 이러한 메트릭을 메트릭 카탈로그에서 소비해야하며 단계 그룹의 오류 예산(alert)에 포함되어야합니다.

먼저, Application-SLI library에 새 SLI를 추가하십시오. 그러고 난 후, 다음 정보를 추가하십시오.

  • name: 코드에서 정의된 SLI의 이름. 예: received_email.
  • significantLabels: 메트릭에 속하는 Prometheus 레이블의 배열. 예: ["email_type"]. SLI의 중요 레이블이 feature_category를 포함하는 경우, 메트릭은 또한 단계 그룹의 오류 예산(alert)에 공급됩니다.
  • featureCategory: SLI가 단일 기능 카테고리에 적용되는 경우, 이 필드를 통해 정적으로 지정할 수 있습니다. 이를 통해 SLI를 단계 그룹의 오류 예산(alert)에 공급할 수 있습니다.
  • description: SLI를 설명하는 Markdown 문자열. 대시보드와 알림에 표시됩니다.
  • kind: 지표 종류. 예: sliDefinition.apdexKind.

작업이 완료되면 make generate를 실행하여 새 SLI에 대한 레코딩 규칙을 생성하십시오. 이 명령은 이러한 메트릭을 significantLabels에 집계된 상태로 생성합니다.

이 변경 사항을 반영하는 Merge Request을 열고, Scalability 팀 구성원의 리뷰를 요청하십시오.

이러한 변경 사항이 Merge되고, Thanos에서 집계가 기록된 후, Thanos를 쿼리하여 새로운 집계된 메트릭의 성공 비율을 확인하십시오. 예를 들어:

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에 대한 알림을 받을 수 있습니다. 자세한 정보는 알림 라우팅 문서를 참조하십시오. 이 프로젝트에서는 feature_category 레이블이 소스 메트릭에 있는 SLI에 대한 알림도 라우팅할 수 있도록 확장 중입니다.

다른 점에 대한 질문이 있을 경우, 언제든지 Scalability 이슈 트래커에 이슈를 생성하거나 Slack의 #g_scalability에서 찾아오십시오.