서비스 핑 개발 지침

서비스 핑은 GitLab 프로세스로, 매주 GitLab에 페이로드를 수집하고 보냅니다. 이 페이로드는 GitLab의 사용 방식을 이해하는 데 도움이 되는 중요한 고수준 데이터를 제공합니다. 이 데이터는 다음과 같은 것들을 돕습니다:

  • 전월 대 비교하여(또는 주대 비교) 인스턴스가 다른 제품 기능을 어떻게 사용하는지 대략적으로 파악합니다.
  • GitLab 설치를 분류하고 이해하는 데 도움이 되는 다른 사실들을 수집합니다.
  • 우리의 스테이지 및 특징의 성공을 메트릭하는 데 도움이 되는 월간 활성 사용자(SMAU)를 계산합니다.

서비스 핑 정보는 익명이 아닙니다. 인스턴스의 호스트 이름에 연결되지만 프로젝트 이름, 사용자 이름 또는 다른 특정 데이터는 포함되지 않습니다.

서비스 핑은 기본적으로 활성화되어 있습니다. 그러나 Self-managed 인스턴스에서 특정 메트릭을 비활성화할 수 있습니다. 서비스 핑이 활성화되었을 때, GitLab은 다른 인스턴스에서 데이터를 수집하고 사용자에게 해당 인스턴스의 사용 통계를 표시할 수 있습니다.

서비스 핑 용어

서비스 핑 컴포넌트를 설명하는 데 다음 용어를 사용합니다:

  • Service Ping: JSON 페이로드를 수집하고 생성하는 프로세스입니다.
  • Service Data: Service Ping JSON 페이로드의 내용입니다. 이에는 메트릭이 포함됩니다.
  • Metrics: 기본적으로 인스턴스의 데이터베이스의 다른 테이블에 대한 행 카운트로 구성됩니다. 각 메트릭은 YAML 파일에서 대응하는 메트릭 정의를 갖습니다.
  • MAU: 월간 활성 사용자(Monthly Active Users)
  • WAU: 주간 활성 사용자(Weekly Active Users)

제한 사항

  • 서비스 핑은 개별 이벤트가 아닌 메트릭만 전달합니다.
  • 메트릭은 해당 버전의 GitLab 코드에 존재하고 instrumented되어 있어야만 해당 버전에 대한 서비스 핑에 전달될 수 있습니다.

서비스 핑 요청 흐름

다음 예시는 GitLab 인스턴스, Versions Application, License Application, Salesforce, GitLab S3 Bucket, GitLab Snowflake Data Warehouse 및 Tableau 간의 기본적인 요청/응답 흐름을 보여줍니다:

sequenceDiagram participant GitLab 인스턴스 participant Versions Application participant Licenses Application participant Salesforce participant S3 Bucket participant Snowflake DW participant Tableau 대시보드 GitLab 인스턴스->>Versions Application: 서비스 핑 전송 loop 사용 데이터 처리 Versions Application->>Versions Application: 사용 데이터 파싱 Versions Application->>Versions Application: 데이터베이스에 쓰기 Versions Application->>Versions Application: 라이선스 핑 시간 업데이트 end loop Salesforce용 데이터 처리 Versions Application-xLicenses Application: Zuora 구독 ID 요청 Licenses Application-xVersions Application: Zuora 구독 ID Versions Application-xSalesforce: Zuora 계정 ID 요청 (Zuora 구독 ID로부터) Salesforce-xVersions Application: Zuora 계정 ID Versions Application-xSalesforce: Zuora 계정용 사용 데이터 end Versions Application->>S3 Bucket: Versions 데이터베이스 내보내기 S3 Bucket->>Snowflake DW: 데이터 가져오기 Snowflake DW->>Snowflake DW: dbt를 사용하여 데이터 변환 Snowflake DW->>Tableau 대시보드: 쿼리 가능한 데이터 Versions Application->>GitLab 인스턴스: DevOps 점수(대화식 개발 지수)

서비스 핑 작동 방식

  1. 서비스 핑 크론 작업은 매주 Sidekiq에서 설정됩니다.
  2. 크론 작업이 실행되면, Gitlab::Usage::ServicePingReport.for(output: :all_metrics_values)을 호출합니다.
  3. Gitlab::Usage::ServicePingReport.for(output: :all_metrics_values)~400여 가지의 다른 카운터 메서드 호출로 자세히 내려갑니다.
  4. 모든 메서드 호출의 응답은 단일 JSON 페이로드로 Merge됩니다.
  5. JSON 페이로드는 다음으로 Versions 애플리케이션에 전송됩니다. 방화벽 예외가 필요한 경우, 필요한 URL은 여러 가지에 따라 달라집니다. 호스트 이름이 version.gitlab.com이고 프로토콜이 TCP이며 포트 번호가 443인 경우, 필요한 URL은 https://version.gitlab.com/입니다.
  6. 오류가 발생하는 경우, 다음 정보와 함께 버전 애플리케이션에 보고됩니다:

    • uuid - GitLab 인스턴스 고유 식별자
    • hostname - GitLab 인스턴스 호스트 이름
    • version - GitLab 인스턴스 현재 버전
    • elapsed - 서비스 핑 보고 프로세스가 시작된 후 발생한 오류가 발생한 시간
    • message - 오류 메시지
    
    {
      "uuid"=>"02333324-1cd7-4c3b-a45b-a4993f05fb1d",
      "hostname"=>"127.0.0.1",
      "version"=>"14.7.0-pre",
      "elapsed"=>0.006946,
      "message"=>'PG::UndefinedColumn: ERROR:  column \"non_existent_attribute\" does not exist\nLINE 1: SELECT COUNT(non_existent_attribute) FROM \"issues\" /*applica...'
    }
    
    
  7. 마지막으로, 진단 목적으로 사용되는 타이밍 메타데이터 정보가 Versions 애플리케이션에 제출됩니다. 이는 메트릭 식별자 디렉터리과 메트릭을 계산하는 데 걸린 시간으로 구성되어 있습니다:

    {
      "metadata"=>
      {
        "uuid"=>"0000000-0000-0000-0000-000000000000",
        "metrics"=>
        [{"name"=>"version", "time_elapsed"=>1.1811964213848114e-05},
         {"name"=>"installation_type", "time_elapsed"=>0.00017242692410945892},
         {"name"=>"license_billable_users", "time_elapsed"=>0.009520471096038818},
         ....
         {"name"=>"counts.clusters_platforms_eks",
          "time_elapsed"=>0.05638605775311589},
         {"name"=>"counts.clusters_platforms_gke",
          "time_elapsed"=>0.40995341585949063},
         {"name"=>"counts.clusters_platforms_user",
          "time_elapsed"=>0.06410990096628666},
         {"name"=>"counts.clusters_management_project",
          "time_elapsed"=>0.24020783510059118}
        ]
      }
    }

Geo 보조 사이트에서

또한 Geo 보조 사이트에 특화된 메트릭을 수집하여 서비스 핑과 함께 보냅니다.

  1. Geo 보조 서비스 핑 크론 작업은 Sidekiq에 매주 실행되도록 설정되어 있습니다.
  2. 크론 작업이 실행되면 SecondaryUsageData.update_metrics!를 호출합니다. 이는 Prometheus에서 관련 메트릭을 수집하고 해당 데이터를 Geo 보조 추적 데이터베이스에 저장하여 Geo 노드 상태 업데이트 중 주 사이트로 전송합니다.
  3. Geo 노드 상태 데이터는 위에서 설명한 과정에서 JSON 페이로드와 함께 전송됩니다. 아래는 각 객체가 Geo 노드를 나타내는 배열 페이로드의 예시입니다:

    [
      {
        "git_fetch_event_count_weekly"=>nil,
        "git_push_event_count_weekly"=>nil,
        ...기타 geo 노드 상태 필드
      }
    ]
    

서비스 핑 페이로드 예시

다음은 서비스 핑 페이로드의 예시 내용입니다.

{
  "uuid": "0000000-0000-0000-0000-000000000000",
  "hostname": "example.com",
  "version": "12.10.0-pre",
  "installation_type": "omnibus-gitlab",
  "active_user_count": 999,
  "recorded_at": "2020-04-17T07:43:54.162+00:00",
  "edition": "EEU",
  "license_md5": "00000000000000000000000000000000",
  "license_sha256": "0000000000000000000000000000000000000000000000000000000000000000",
  "license_id": null,
  "historical_max_users": 999,
  "licensee": {
    "Name": "ABC, Inc.",
    "Email": "email@example.com",
    "Company": "ABC, Inc."
  },
  "license_user_count": 999,
  "license_starts_at": "2020-01-01",
  "license_expires_at": "2021-01-01",
  "license_plan": "ultimate",
  "license_add_ons": {
  },
  "license_trial": false,
  "counts": {
    "assignee_lists": 999,
    "boards": 999,
    "ci_builds": 999,
    ...
  },
  "container_registry_enabled": true,
  "dependency_proxy_enabled": false,
  "gitlab_shared_runners_enabled": true,
  "gravatar_enabled": true,
  "influxdb_metrics_enabled": true,
  "ldap_enabled": false,
  "mattermost_enabled": false,
  "omniauth_enabled": true,
  "prometheus_enabled": false,
  "prometheus_metrics_enabled": false,
  "reply_by_email_enabled": "incoming+%{key}@incoming.gitlab.com",
  "signup_enabled": true,
  "projects_with_expiration_policy_disabled": 999,
  "projects_with_expiration_policy_enabled": 999,
  ...
  "elasticsearch_enabled": true,
  "license_trial_ends_on": null,
  "geo_enabled": false,
  "git": {
    "version": {
      "major": 2,
      "minor": 26,
      "patch": 1
    }
  },
  "gitaly": {
    "version": "12.10.0-rc1-93-g40980d40",
    "servers": 56,
    "clusters": 14,
    "filesystems": [
      "EXT_2_3_4"
    ]
  },
  "gitlab_pages": {
    "enabled": true,
    "version": "1.17.0"
  },
  "container_registry_server": {
    "vendor": "gitlab",
    "version": "2.9.1-gitlab",
    "db_enabled": false
  },
  "database": {
    "adapter": "postgresql",
    "version": "9.6.15",
    "pg_system_id": 6842684531675334351,
    "flavor": "Cloud SQL for PostgreSQL"
  },
  "analytics_unique_visits": {
    "g_analytics_contribution": 999,
    ...
  },
  "usage_activity_by_stage": {
    "configure": {
      "project_clusters_enabled": 999,
      ...
    },
    "create": {
      "merge_requests": 999,
      ...
    },
    "manage": {
      "events": 999,
      ...
    },
    "monitor": {
      "clusters": 999,
      ...
    },
    "package": {
      "projects_with_packages": 999
    },
    "plan": {
      "issues": 999,
      ...
    },
    "release": {
      "deployments": 999,
      ...
    },
    "secure": {
      "user_container_scanning_jobs": 999,
      ...
    },
    "verify": {
      "ci_builds": 999,
      ...
    }
  },
  "usage_activity_by_stage_monthly": {
    "configure": {
      "project_clusters_enabled": 999,
      ...
    },
    "create": {
      "merge_requests": 999,
      ...
    },
    "manage": {
      "events": 999,
      ...
    },
    "monitor": {
      "clusters": 999,
      ...
    },
    "package": {
      "projects_with_packages": 999
    },
    "plan": {
      "issues": 999,
      ...
    },
    "release": {
      "deployments": 999,
      ...
    },
    "secure": {
      "user_container_scanning_jobs": 999,
      ...
    },
    "verify": {
      "ci_builds": 999,
      ...
    }
  },
  "topology": {
    "duration_s": 0.013836685999194742,
    "application_requests_per_hour": 4224,
    "query_apdex_weekly_average": 0.996,
    "failures": [],
    "nodes": [
      {
        "node_memory_total_bytes": 33269903360,
        "node_memory_utilization": 0.35,
        "node_cpus": 16,
        "node_cpu_utilization": 0.2,
        "node_uname_info": {
          "machine": "x86_64",
          "sysname": "Linux",
          "release": "4.19.76-linuxkit"
        },
        "node_services": [
          {
            "name": "web",
            "process_count": 16,
            "process_memory_pss": 233349888,
            "process_memory_rss": 788220927,
            "process_memory_uss": 195295487,
            "server": "puma"
          },
          {
            "name": "sidekiq",
            "process_count": 1,
            "process_memory_pss": 734080000,
            "process_memory_rss": 750051328,
            "process_memory_uss": 731533312
          },
          ...
        ],
        ...
      },
      ...
    ]
  }
}

서비스 핑 데이터 내보내기

다양한 형식으로 서비스 핑 데이터를 내보내기 위한 Rake 작업이 준비되어 있습니다.

  • Rake 작업은 count, distinct_count, sum에 대한 raw SQL 쿼리를 내보냅니다.
  • Rake 작업은 redis_usage_data에 대한 Redis 카운터 클래스 또는 Redis 블록의 라인을 내보냅니다.
  • Rake 작업은 alt_usage_data 메트릭을 계산합니다.

로컬 GitLab 설치의 홈 디렉터리에서 다음의 Rake 작업을 실행하여 YAML 또는 JSON 버전을 선택하세요:

# SQL 쿼리의 YAML 내보내기
bin/rake gitlab:usage_data:dump_sql_in_yaml

# SQL 쿼리의 JSON 내보내기
bin/rake gitlab:usage_data:dump_sql_in_json

# Non-SQL 데이터의 JSON 내보내기
bin/rake gitlab:usage_data:dump_non_sql_in_json

# 결과를 파일로 출력할 수 있습니다
bin/rake gitlab:usage_data:dump_sql_in_yaml > ~/Desktop/usage-metrics-2020-09-02.yaml

서비스 핑에 대한 대체 값

다음과 같은 경우에는 대체 값이 반환됩니다:

경우
Deprecated Metric (Removed with version 14.3) -1000
타임아웃, 일반적인 실패 -1
카운터의 표준 오류 -2
히스토그램 메트릭 실패 { ‘-1’ => -1 }

모니터링

내부 SiSense 대시보드를 사용하여 서비스 핑 보고 프로세스 상태를 모니터링합니다: internal SiSense dashboard.

관련 주제