- インストルメンテーション・クラス
- カウンターの種類
- Railsコンソールを使って手動でカウンタをテストします。
- SQLクエリを生成します。
- データベースラボでクエリを最適化
- メトリクス定義を追加します。
- マージリクエストの作成
- メトリクスを確認
- ローカルでのサービスPingの設定とテスト
- PrometheusベースのサービスPingのテスト
- 集約されたメトリクス
サービスPingの実装
Service Pingは2種類のデータから構成されています:
- カウンタ:カウンタ:CI/CDパイプラインが何回実行されたかなど、あるイベントがどのくらいの頻度で発生したかを追跡します。これらは単調で、通常は上昇傾向にあります。
- オブザベーション:1つ以上のGitLabインスタンスから収集された事実で、任意のデータを運ぶことができます。データの性質上、収集方法に関する一般的なガイドラインはありません。
Service Pingに新しいメトリクスを実装するには、以下の手順に従ってください:
- 必要なカウンターの実装
- メトリクスに名前を付けて配置します。
- Railsコンソールを使って手動でカウンタをテストします。
- SQLクエリを生成します。
- Database Labでクエリを最適化
- メトリクス辞書にメトリクスの定義を追加します。
- マージリクエストを作成します。
- メトリックの検証
- Service Pingのローカル設定とテスト
インストルメンテーション・クラス
usage_data.rb
で直接メトリクスを実装することは非推奨です。Service Ping メトリックを追加または変更する場合は、メトリックをインスツルメンテーション・クラスにマイグレーションする必要があります。Service Ping メトリクスのマイグレーションの進捗については、このエピックを参照してください。例えば、次のインスツルメンテーション・クラスがあります:lib/gitlab/usage/metrics/instrumentations/count_boards_metric.rb
.
これをusage_data.rb
に次のように追加します:
boards: add_metric('CountBoardsMetric', time_frame: 'all'),
カウンターの種類
メトリクスには、いくつかの種類のカウンターがあります:
- バッチ・カウンター:カウント、合計、平均に使用されます。
- Redisカウンター:メモリ内のカウントに使用します。
- 代替カウンター:設定や構成に使用します。
バッチカウンタ
大きなテーブルの場合、PostgreSQLはMVCC(複数バージョン同時実行制御)のために行のカウントに時間がかかることがあります。バッチカウンタは、1つの大きなクエリを複数の小さなクエリに分割してカウントする方法です。例えば、1,000,000レコードのクエリを1回実行する代わりに、バッチカウントでは10,000レコードずつのクエリを100回実行することができます。バッチカウンティングはデータベースのタイムアウトを回避するのに便利です。
GitLab.com では、15 秒のクエリタイムアウトが発生するような非常に大きなテーブルがあります。以下に GitLab.com のテーブルのサイズを示します:
テーブル | 行数(単位:百万 |
---|---|
merge_request_diff_commits | 2280 |
ci_build_trace_sections | 1764 |
merge_request_diff_files | 1082 |
events | 514 |
バッチカウンティングでは、最大、最小、範囲クエリを計算するためにカラムにインデックスが必要です。場合によっては、カウンターに関係するカラムに専用のインデックスを追加する必要があります。
通常のバッチカウンタ
count
オペレーションを持つ新しいデータベース・メトリクス・インスツルメンテーション・クラスを作成します。ActiveRecord_Relation
メソッドを使用します:
add_metric('CountIssuesMetric', time_frame: 'all')
例:
usage_data.rb
を使用した例は非推奨となりました。インストルメンテーション・クラスの使用を推奨します。
個別のバッチ・カウンタ
与えられたActiveRecord_Relation
に対して、distinct_count
オペレーションを持つ新しいデータベース・メトリクス・インスツルメンテーション・クラスを作成します。
メソッドを使用します:
add_metric('CountUsersAssociatingMilestonesToReleasesMetric', time_frame: 'all')
例:
usage_data.rb
を使用した例は非推奨となりました。インストルメンテーション・クラスの使用を推奨します。
一括オペレーション
与えられたカラムの与えられたActiveRecord_Relationの値を合計し、エラーを処理します。ActiveRecord::StatementInvalid
エラーを処理します。
メソッドを使用します:
add_metric('JiraImportsTotalImportedIssuesCountMetric')
平均バッチオペレーション
指定された列の指定されたActiveRecord_Relation
の値を平均し、エラーを処理します。
メソッドを使用します:
add_metric('CountIssuesWeightAverageMetric')
例:
usage_data.rb
を使用した例は非推奨となりました。インストルメンテーション・クラスの使用を推奨します。
グループ化とバッチオペレーション
count
,distinct_count
およびsum
バッチカウンタは、指定したカラムでグループ化するActiveRecord::Relation
オブジェクトを受け取ることができます。グループ化された関係で、メソッドはバッチカウントを行い、エラーを処理し、キーと値のペアのハッシュテーブルを返します。
例:
count(Namespace.group(:type))
# returns => {nil=>179, "Group"=>54}
distinct_count(Project.group(:visibility_level), :creator_id)
# returns => {0=>1, 10=>1, 20=>11}
sum(Issue.group(:state_id), :weight))
# returns => {1=>3542, 2=>6820}
オペレーション追加
パラメータとして与えられた値を合計します。StandardError
を処理します。-1
引数のいずれかが . -1
メソッドを使用します:
add(*args)
例:
project_imports = distinct_count(::Project.where.not(import_type: nil), :creator_id)
bulk_imports = distinct_count(::BulkImport, :user_id)
add(project_imports, bulk_imports)
推定バッチカウンター
GitLab 13.7 で導入されました。
推定バッチカウンタ機能は、提供されたestimate_batch_distinct_count
メソッドで使用された場合にActiveRecord::StatementInvalid
エラーを処理します。エラーは-1
の値を返します。
estimate_batch_distinct_count
メソッドを正しく使用すると、他のカウンタでは保証できない、一意でない値を含むカラムを効率的にカウントすることができます。
estimate_batch_distinct_count
メソッド
メソッドを使用します:
estimate_batch_distinct_count(relation, column = nil, batch_size: nil, start: nil, finish: nil)
メソッドには以下の引数があります:
-
relation
:カウントを実行する ActiveRecord_Relation。 -
column
:個別カウントを行うカラム。デフォルトは主キー。 -
batch_size
:Gitlab::Database::PostgresHll::BatchDistinctCounter::DEFAULT_BATCH_SIZE
から。デフォルト値:10,000。 -
start
:バッチカウントのカスタム開始値。 -
finish
:複雑な最大値の計算を避けるための、バッチカウントのカスタム終了値。
このメソッドには以下の前提条件があります:
- 提供される
relation
には、数値カラムとして定義された主キーが含まれていなければなりません。例:id bigint NOT NULL
。 -
estimate_batch_distinct_count
は結合されたリレーションを扱うことができます。一意でない列をカウントする機能を使用するには、has_many :boards
のように、結合されたリレーションが一対多のリレーションであってはなりません。 -
start
とfinish
の両引数は、推定カウントが別の列を参照する場合などであっても、常に主キー関係の値を表す必要があります:estimate_batch_distinct_count(::Note, :author_id, start: ::Note.minimum(:id), finish: ::Note.maximum(:id))
例:
-
推定バッチカウンタの単純な実行で、リレーションのみが提供され、返される値は
Project
リレーションのid
カラム (これはプライマリキーです) の一意な値の推定数を表します:estimate_batch_distinct_count(::Project)
-
推定バッチカウンタの実行。提供されたリレーションに追加フィルタ(
.where(time_period)
)が適用され、カスタムカラム(:author_id
)の一意な値の推定数が返されます。パラメータ:start
とfinish
は、提供されたリレーションの分析範囲を定義する境界を適用します:estimate_batch_distinct_count(::Note.with_suggestions.where(time_period), :author_id, start: ::Note.minimum(:id), finish: ::Note.maximum(:id))
推定バッチカウンタの使用量でメトリクスを計測する場合、その名前に_estimated
というサフィックスをつけてください:
"counts": {
"ci_builds_estimated": estimate_batch_distinct_count(Ci::Build),
...
Redis カウンター
::Redis::CommandError
とGitlab::UsageDataCounters::BaseCounter::UnknownEvent
を扱います。ブロックが送信された場合は -1、すべての値を含むハッシュが送信された場合は -1、counter(Gitlab::UsageDataCounters)
が送信された場合は -1 を返します。挙動が異なるのは、Redisカウンタの実装が2つ異なるためです。
メソッドを使用します:
redis_usage_data(counter, &block)
引数:
-
counter
fallback_totals
メソッドを実装したGitlab::UsageDataCounters
のカウンタ。 - または
block
: 評価されます。
通常のRedisカウンター
実装例:Gitlab::UsageDataCounters::WikiPageCounter
Redis のメソッドINCR
およびGET
を使用します。
イベントは、BaseCounter
を継承したGitlab::UsageDataCounters
名前空間のカウンター・クラスによって処理されます:
-
Gitlab::UsageDataCounters::COUNTERS
にリストされ、Gitlab::UsageData
に含まれます。 -
prefix
オプションによってRedisMetric
インストルメンテーション・クラスを使用してメトリック定義で指定され、メトリック・インストルメンテーション・フレームワークを使用してピックアップされます。実装例については、Redisメトリクスのドキュメントを参照してください。
継承するクラスは、イベント名と関連するメトリクスを構築するために、KNOWN_EVENTS
とPREFIX
定数をオーバーライドすることが期待されます。例えば、プレフィックスissues
とイベント配列%w[create, update, delete]
の場合、3 つのメトリクスが Service Ping ペイロードに追加されます:counts.issues_create
counts.issues_update
およびcounts.issues_delete
。
UsageData
API
UsageData
API を使用してイベントを追跡できます。イベントを追跡するには、usage_data_api
機能フラグが有効(default_enabled: true
に設定)になっている必要があります。GitLab 13.7以降ではデフォルトで有効になっています。
UsageData APIのトラッキング
-
UsageData
API を使用してイベントをトラッキングします。指定されたイベント名に対して、通常の Redis カウンタを使用してイベントカウントをインクリメントします。
APIリクエストは、有効なCSRFトークンをチェックすることで保護されます。
POST /usage_data/increment_counter
属性 種類 必須 説明 event
文字列です。 yes 追跡するイベント名。 レスポンス
-
200
イベントが追跡された場合。 -
400 Bad request
イベントパラメータがない場合。 -
401 Unauthorized
ユーザーが認証されていない場合。 -
403 Forbidden
無効な CSRF トークンが提供された場合。
-
-
UsageData
APIを呼び出す JavaScript/Vue API ヘルパーを使用してイベントを追跡します。イベントを追跡するには、
usage_data_api
とusage_data_#{event_name}
を有効にする必要があります。import api from '~/api'; api.trackRedisCounterEvent('my_already_defined_event_name'),
Redis HLLカウンター
usage_stats
(User.single_user&.requires_usage_stats_consent?
) に対するユーザーの同意は、データ追跡ステージではチェックされません。これらのカウンターに対応するキーは、usage_stats_consent
必要 usage_stats_consent
であってもRedisに存在します。usage_stats_consent
しかし、必要とされる限り、Redisからメトリクスが収集され、GitLabにレポートバックさ usage_stats_consent
れることはありません。Gitlab::UsageDataCounters::HLLRedisCounter
、ユニークな値をカウントするためのデータ構造が利用できます。
RedisのメソッドPFADDと PFCOUNTを使って実装されています。
新しいイベントを追加
-
必要なメトリクスにイベントを追加するか(例を参照)、メトリクスを作成します。
-
イベントを追跡するには、次のいずれかの方法を使用します:
-
ProductAnalyticsTracking
モジュールと以下のフォーマットを使用します:track_event(*controller_actions, name:, action:, label:, conditions: nil, destinations: [:redis_hll], &block)
引数:
-
controller_actions
追跡するコントローラのアクション。 -
name
イベント名。 -
action
: destination が `:snowplow’ の場合は必須。トリガーされたイベントのアクション名。詳細はイベントスキーマを参照してください。 -
label
destination が `:snowplow’ の場合は必須。トリガーされたイベントのラベル。詳細はイベントスキーマを参照してください。 -
conditions
オプションのカスタム条件。Railsコールバックと同じ形式を使用します。 -
destinations
オプションの宛先リスト。現在は:redis_hll
と:snowplow
をサポートしています。デフォルト::redis_hll
. -
&block
: 追跡したいcustom_id
を計算して返すオプションのブロック。これはvisitor_id
を上書きします。
使用例:
# controller class ProjectsController < Projects::ApplicationController include ProductAnalyticsTracking skip_before_action :authenticate_user!, only: :show track_event :index, :show, name: 'users_visiting_projects', action: 'user_perform_visit', label: 'redis_hll_counters.users_visiting_project_monthly', destinations: %i[redis_hll snowplow] def index render html: 'index' end def new render html: 'new' end def show render html: 'show' end end
-
-
API 内で
increment_unique_values(event_name, values)
ヘルパーメソッドを使用します。引数:
-
event_name
イベント名。 -
values
カウントされる値。1つの値または値の配列。
使用例:
get ':id/registry/repositories' do repositories = ContainerRepositoriesFinder.new( user: current_user, subject: user_group ).execute increment_unique_values('users_listing_repositories', current_user.id) present paginate(repositories), with: Entities::ContainerRegistry::Repository, tags: params[:tags], tags_count: params[:tags_count] end
-
-
サービスとGraphQLで
track_usage_event(event_name, values)
。Redis HLLを使用して、指定されたイベント名に対して一意な値のカウントを増やします。
例:
track_usage_event(:incident_management_incident_created, current_user.id)
-
UsageData
APIを使用します。Redis HLL を使用して、指定されたイベント名のユニークユーザーカウントをインクリメントします。
APIリクエストは、有効なCSRFトークンをチェックすることで保護されます。
POST /usage_data/increment_unique_users
属性 種類 必須 説明 event
文字列です。 yes 追跡するイベント名 レスポンス
-
200
イベントが追跡された場合、または何らかの理由で追跡が失敗した場合。 -
400 Bad request
イベントパラメータが見つからない場合。 -
401 Unauthorized
ユーザーが認証されていない場合。 -
403 Forbidden
無効な CSRF トークンが提供された場合。
-
-
UsageData
APIを呼び出す JavaScript/Vue API ヘルパーを使用します。すでにメトリクスフィールドで定義されている既存のイベントの例:
import api from '~/api'; api.trackRedisHllUserEvent('my_already_defined_event_name'),
-
-
Gitlab::UsageDataCounters::HLLRedisCounter.unique_events(event_names:, start_date:, end_date:, context: '')
を使用してイベントデータを取得します。引数:
-
event_names
イベント名のリスト。 -
start_date
イベントデータを取得したい期間の開始日。 -
end_date
イベントデータを取得したい期間の終了日。 -
context
イベントのコンテキスト。指定できる値はdefault
,free
,bronze
,silver
,gold
,starter
,premium
,ultimate
です。
-
-
トラッキングのテストとユニークイベントの取得
track_event
メソッドを使用して、Rails コンソールでイベントをトリガーします。
Gitlab::UsageDataCounters::HLLRedisCounter.track_event('users_viewing_compliance_audit_events', values: 1)
Gitlab::UsageDataCounters::HLLRedisCounter.track_event('users_viewing_compliance_audit_events', values: [2, 3])
次に、現在の週のユニークなイベントを取得します。
# Get unique events for metric for current_week
Gitlab::UsageDataCounters::HLLRedisCounter.unique_events(event_names: 'users_viewing_compliance_audit_events',
start_date: Date.current.beginning_of_week, end_date: Date.current.next_week)
推奨
新しいイベントを追加するために、以下のことをお勧めします:
- 新しいメトリクスを追加する場合は、機能フラグを使用して影響を制御します。デフォルトでは、新機能フラグを無効にすることをお勧めします(
default_enabled: false
に設定)。 - イベントは、
UsageData
API を使用してトリガすることができます。
Redis HLLトラッキングの有効化または無効化
グローバルフラグを使うことで、トラッキングを完全に無効にすることができます:
/chatops run feature set redis_hll_tracking true
/chatops run feature set redis_hll_tracking false
既知のイベントは自動的にサービスデータのペイロードに追加されます。
Service PingはすべてのイベントをService Data生成にredis_hll_counters
キーで追加します。このカラムはJSONとしてversion-appに保存されます。各イベントに対して、週単位と月単位のメトリクスを追加し、該当する場合はそれぞれの合計を追加します:
-
#{event_name}_weekly
:日次集計イベントの場合は7日分のデータ、週次集計イベントの場合は直近1週間分のデータ。 -
#{event_name}_monthly
:日次集計イベントの場合は28日分のデータ、週次集計イベントの場合は直近4週間分のデータ。
redis_hll_counters
データの例:
{:redis_hll_counters=>
{"compliance"=>
{"users_viewing_compliance_dashboard_weekly"=>0,
"users_viewing_compliance_dashboard_monthly"=>0,
"users_viewing_compliance_audit_events_weekly"=>0,
"users_viewing_audit_events_monthly"=>0,
"compliance_total_unique_counts_weekly"=>0,
"compliance_total_unique_counts_monthly"=>0},
"analytics"=>
{"users_viewing_analytics_group_devops_adoption_weekly"=>0,
"users_viewing_analytics_group_devops_adoption_monthly"=>0,
"analytics_total_unique_counts_weekly"=>0,
"analytics_total_unique_counts_monthly"=>0},
"ide_edit"=>
{"users_editing_by_web_ide_weekly"=>0,
"users_editing_by_web_ide_monthly"=>0,
"users_editing_by_sfe_weekly"=>0,
"users_editing_by_sfe_monthly"=>0,
"ide_edit_total_unique_counts_weekly"=>0,
"ide_edit_total_unique_counts_monthly"=>0}
}
}
使用例:
# Redis Counters
redis_usage_data(Gitlab::UsageDataCounters::WikiPageCounter)
# Tracking events
Gitlab::UsageDataCounters::HLLRedisCounter.track_event('users_expanding_vulnerabilities', values: visitor_id)
# Get unique events for metric
redis_usage_data { Gitlab::UsageDataCounters::HLLRedisCounter.unique_events(event_names: 'users_expanding_vulnerabilities', start_date: 28.days.ago, end_date: Date.current) }
代替カウンター
StandardError
と -1 へのフォールバックを処理します。これにより、1 つの例外が発生しても、すべてのメジャーが失敗することはありません。主に設定と構成に使用されます。
メソッドを使用します:
alt_usage_data(value = nil, fallback: -1, &block)
引数:
-
value
この場合、値が返されます。 - または
block
: 評価されます。 -
fallback: -1
: 失敗しているメトリクスに使用される共通の値。
使用例:
alt_usage_data { Gitlab::VERSION }
alt_usage_data { Gitlab::CurrentSettings.uuid }
alt_usage_data(999)
新しいメトリクスを構築するためのカウンターの追加
2 つのカウンターの結果を追加する場合は、フォールバック値と例外を処理するadd
Service Data メソッドを使用します。また、有効なSQL エクスポートも生成します。
使用例:
add(User.active, User.bot)
クエリ
オペレーション・メトリクスをService Pingの一部とする場合、データベースやRedisクエリでは有用なデータは得られないでしょう。なぜなら、ほとんどのGitLabアーキテクチャ・コンポーネントはPrometheusにメトリクスを公開しており、それをクエリバックして集計し、サービス・データとして含めることができるからです。
yield
Prometheus にメトリクスをクエリするには、ヘルパー・メソッドを使用してPrometheusClient
を完全に設定します:
with_prometheus_client do |client|
response = client.query('<your query>')
...
end
データをクエリするための API の使用方法については、 PrometheusClient
定義 を参照してください。
サービスPingのフォールバック値
これらの場合、フォールバック値を返します:
ケース | 値 |
---|---|
非推奨メトリクス(バージョン14.3で削除) | -1000 |
タイムアウト、一般的な障害 | -1 |
カウンターの標準エラー | -2 |
ヒストグラム・メトリクスの失敗 | { ‘-1’ => -1 } |
Railsコンソールを使って手動でカウンタをテストします。
# count
Gitlab::UsageData.count(User.active)
Gitlab::UsageData.count(::Clusters::Cluster.aws_installed.enabled, :cluster_id)
# count distinct
Gitlab::UsageData.distinct_count(::Project, :creator_id)
Gitlab::UsageData.distinct_count(::Note.with_suggestions.where(time_period), :author_id, start: ::User.minimum(:id), finish: ::User.maximum(:id))
SQLクエリを生成します。
Railsコンソールは生成されたSQLクエリを返します。たとえば
pry(main)> Gitlab::UsageData.count(User.active)
(2.6ms) SELECT "features"."key" FROM "features"
(15.3ms) SELECT MIN("users"."id") FROM "users" WHERE ("users"."state" IN ('active')) AND ("users"."user_type" IS NULL OR "users"."user_type" IN (6, 4))
(2.4ms) SELECT MAX("users"."id") FROM "users" WHERE ("users"."state" IN ('active')) AND ("users"."user_type" IS NULL OR "users"."user_type" IN (6, 4))
(1.9ms) SELECT COUNT("users"."id") FROM "users" WHERE ("users"."state" IN ('active')) AND ("users"."user_type" IS NULL OR "users"."user_type" IN (6, 4)) AND "users"."id" BETWEEN 1 AND 100000
データベースラボでクエリを最適化
Database Labは、本番クローンを使ってクエリをテストするサービスです。
- GitLab.comの本番データベースには15秒のタイムアウトがあります。
- コールドキャッシュを使う場合は、クエリの実行時間を1秒以内に抑えなければなりません。
- 実行時間を短縮するために、関係するカラムに特化したインデックスを追加します。
クエリの実行を理解するために、マージリクエストの記述に以下の情報を追加します:
-
time_period
テストを持つカウンターの場合、両方の情報を追加します:-
time_period = {}
の両方の情報を追加します。 -
time_period = { created_at: 28.days.ago..Time.current }
過去28日間
-
- 最適化前後の実行プランとクエリ時間。
- インデックスと時間に対して生成されたクエリ。
- 上下実行のマイグレーション出力。
詳細については、データベースレビューガイドを参照してください。
最適化の推奨事項と例
- 特殊なインデックスを使用してください。例については、これらのマージリクエストを参照してください:
- 定義された
start
とfinish
を使用してください。これらの値は、このマージリクエスト例のように、メモして再利用することができます。 - クエリの結合や不必要な複雑さは避けてください。例としてこのマージリクエスト例を参照してください。
- このマージリクエスト例のように、
distinct_count
にカスタムbatch_size
を設定します。
メトリクス定義を追加します。
詳細については、『メトリクス辞書』ガイドを参照してください。
マージリクエストの作成
新しい Service Ping メトリクスのマージ・リクエストを作成し、以下を実行します:
- マージリクエストに
feature
ラベルを追加します。メトリクスはユーザー向けの変更であり、Service Ping 機能の拡張の一部です。 - 変更ログエントリガイドに準拠した変更ログエントリを追加します。
- Analytics Instrumentation のレビューを依頼してください。GitLab.com では、Analytics Instrumentation 関連のファイルを監視し、Analytics Instrumentation のレビューを推奨するために DangerBot を設定しています。
メトリクスを確認
GitLab.comでは、プロダクトインテリジェンスチームが定期的にService Pingを監視しています。あなたのメトリクスをより速く、より成功させるためにさらなる最適化が必要であることを警告してくれるかもしれません。
GitLab.com の Service Ping JSON ペイロードは、毎週#g_product_intelligenceSlack チャンネルで共有されます。
ServicePing QAダッシュボードを使って、メトリクスがどの程度機能しているかをチェックすることもできます。このダッシュボードでは、GitLabのバージョン、”Self-managed “と “SaaS “によるフィルタリングが可能で、各メトリクスの障害発生件数が表示されます。失敗率が高いことに気づいたら、いつでもメトリックを再最適化することができます。
メトリクスディクショナリの クリップボードへのクエリのコピー機能を使用すると、特定のメトリクスに対してSisenseで実行できるクエリを取得できます。
ローカルでのサービスPingの設定とテスト
Service Pingをローカルで設定するには、以下の手順が必要です:
- ローカルリポジトリを設定します。
- ローカルのセットアップをテストします。
- オプションPrometheus ベースのサービス Ping をテストします。
ローカルリポジトリの設定
- GitLabをクローンして起動します。
-
Versions Applicationをクローンして起動します。PostgreSQLとRedisのインスタンスを起動するために
docker-compose up
。 - GitLab をデフォルトのエンドポイントではなく、Versions Application のエンドポイントに指定します:
- ローカルでservice_ping/submit_service.rbを開き、
STAGING_BASE_URL
を修正します。 - ローカルのVersions Application URLに設定します:
http://localhost:3000
.
- ローカルでservice_ping/submit_service.rbを開き、
ローカルセットアップのテスト
-
gitlab
Railsコンソールを使って、手動でService Pingをトリガーします:GitlabServicePingWorker.new.perform('triggered_from_cron' => false)
-
versions
Rails コンソールを使用して、Service Ping が正常に受信、解析され、Versions データベースに保存されたことを確認します:UsageData.last
PrometheusベースのサービスPingのテスト
送信されたデータに、検査および検証したいPrometheusからクエリされたメトリクスが含まれている場合は、以下の手順が必要です:
- Prometheus サーバーがローカルで実行されていることを確認します。
- それぞれのGitLabコンポーネントがPrometheusサーバーにメトリクスをエクスポートしていることを確認します。
Prometheusからのデータをテストする必要がない場合は、これ以上のアクションは必要ありません。Prometheusサーバーが稼働していない場合、サービスPingは優雅に低下するはずです。
3種類のコンポーネントがPrometheusにデータをエクスポートし、Service Pingに含まれます:
-
node_exporter
:ホスト・マシンからノードのメトリクスをエクスポートします。 -
gitlab-exporter
:GitLabの様々なコンポーネントからプロセスのメトリクスをエクスポートします。 - SidekiqやRailsサーバなど、独自のメトリクスをエクスポートする他の様々なGitLabサービス。
Omnibus コンテナでのテスト
Prometheus ベースの Service Ping をテストするには、この方法をお勧めします。
変更を検証するには、CI/CDを使用してコードブランチから新しいOmnibusイメージをビルドし、イメージをダウンロードしてローカルコンテナインスタンスを実行します:
- マージリクエストから
qa
ステージを選択し、e2e:package-and-test
ジョブをトリガーします。このジョブは、omnibus-gitlab-mirror
プロジェクト](https://gitlab.com/gitlab-org/build/omnibus-gitlab-mirror/-/pipelines)の[ダウンストリームパイプラインで Omnibus ビルドをトリガーします。 - ダウンストリームパイプラインでは、
gitlab-docker
ジョブの終了を待ちます。 - ジョブログを開き、バージョンを含む完全なコンテナ名を確認します。それは次の形式をとります:
registry.gitlab.com/gitlab-org/build/omnibus-gitlab-mirror/gitlab-ee:<VERSION>
. - ローカルマシンで、GitLab Dockerレジストリにサインインしていることを確認します。この手順は、Authenticate to the GitLab Container Registryに記載されています。
- サインインしたら、新しいイメージをダウンロードします。
docker pull registry.gitlab.com/gitlab-org/build/omnibus-gitlab-mirror/gitlab-ee:<VERSION>
- DockerでのOmnibus GitLabコンテナの操作と実行についての詳細は、GitLab Docker imagesdocumentationを参照してください。
GitLab開発ツールキットでのテスト
実際のGitLabのデプロイをエミュレートするときに多くの困難が伴うので、これはあまり推奨されないアプローチです。
GDKはPrometheusサーバーやnode_exporter
、他のGitLabコンポーネントと一緒に実行するようには設定されていません。もしそうしたいのであれば、Prometheusを使ってGDKをモニタリングするのが良いスタートです。
GCKはPrometheusベースのService Pingをテストするための限られたサポートしか持っていません。デフォルトでは、多くのコンポーネントをスクレイピングするように設定されたPrometheusサービスが付属しています。しかし、これには以下の制限があります:
- それは
gitlab-exporter
インスタンスを実行しないので、Gitalyのようなサービスからのいくつかのprocess_*
メトリクスが欠落している可能性があります。 -
node_exporter
を実行する一方で、docker-compose
サービスはホストをエミュレートします。つまり、通常、それ自身は実行中の他のどのサービスとも関連していないとレポーターします。これは、本番環境ではノードのメトリクスがどのようにレポートされるかということではありませんnode_exporter
。Service Pingでは、どのノード・データも、実行中のどのサービスにも関連していないように見えます。この問題を軽減node_exporter
するために、GCKの内部はweb
サービスに任意に “割り当て “られ、このサービスnode_*
メトリクスだけがService Pingに表示されるようになりました。
集約されたメトリクス
GitLab 13.6で導入されました。
集約メトリクス機能は、Service Ping メトリクスのコレクション内のデータ属性に関するインサイトを提供します。この集約により、複数のイベントで同じデータ属性が発生するたびにカウントすることなく、イベント内のデータ属性をカウントできます。例えば、新しいイシューの作成や新しいマージ・リクエストのオープンなど、複数のアクションを実行したユーザー数を集計できます。そして、これらのアクションの任意の組み合わせを実行した各ユーザをカウントできます。
メトリックYAML定義による集約メトリックの定義
サービスPingペイロードに集約メトリクスのデータを追加するには、Aggregated metric instrumentationガイドに従ってメトリクスYAML定義ファイルを作成します。
Redisソース集約メトリクス
GitLab 13.6で導入されました。
Redis HLL Countersで収集したイベントの集約を宣言するには、time_frame
にall
の値が含まれていないことを確認してください。これはRedisソースの集約メトリクスでは利用できません。
EEだけのイベントをすべてのGitLabエディションで発生したイベントと一緒に集計することは可能ですが、そうすることでEEとCEのGitLabインスタンスから収集したデータの間に大きなばらつきが生じる可能性があることを覚えておくことが重要です。
データベースソースで集計されたメトリクス
GitLab 13.9 で導入されました。
データベースから収集したイベントに基づくメトリクスの集計を宣言するには、以下の手順に従ってください:
- 集約するメトリクスを永続化します。
- 新しい集約メトリクス定義を追加します。
集約のためのメトリクスの永続化
推定バッチ・カウンターを使用して計算されたメトリクスのみを、データベースから取得した集約メトリクスのために永続化できます。メトリックを永続化するには、estimate_batch_distinct_count
メソッドに Ruby ブロックを注入します。このブロックは、Gitlab::Usage::Metrics::Aggregates::Sources::PostgresHll.save_aggregated_metrics
メソッドを呼び出す必要があります。 メソッドは、estimate_batch_distinct_count
の結果を保存して、将来的に集約メトリクスで使用できるようにします。
Gitlab::Usage::Metrics::Aggregates::Sources::PostgresHll.save_aggregated_metrics
メソッドには以下の引数を指定します:
-
metric_name
:集約に使用するメトリックの名前。Service Ping に追加されるメトリックのキーと同じでなければなりません。 -
recorded_at_timestamp
:指定された Service Ping ペイロードが収集された瞬間を表すタイムスタンプ。recorded_at_timestamp
引数を埋めるには、次のような便利なメソッドrecorded_at
を使用する必要があります:recorded_at_timestamp: recorded_at
-
time_period
:estimate_batch_distinct_count
に渡されるrelation
引数を構築するために使用される期間。利用可能なすべての履歴データでメトリクスを収集するには、nil
の値を期間として設定します:time_period: nil
。 -
data
:relation
の一意のエントリを表す HyperLogLog バケツ構造。estimate_batch_distinct_count
メソッドは常に正しい引数をブロックに渡すので、data
引数は常にブロックの引数と同じ値でなければなりません:data: result
メトリクスの永続化の例:
class UsageData
def count_secure_pipelines(time_period)
...
relation = ::Security::Scan.by_scan_types(scan_type).where(time_period)
pipelines_with_secure_jobs['dependency_scanning_pipeline'] = estimate_batch_distinct_count(relation, :pipeline_id, batch_size: 1000, start: start_id, finish: finish_id) do |result|
::Gitlab::Usage::Metrics::Aggregates::Sources::PostgresHll
.save_aggregated_metrics(metric_name: 'dependency_scanning_pipeline', recorded_at_timestamp: recorded_at, time_period: time_period, data: result)
end
end
end
新しい集約メトリクス定義の追加
すべてのメトリクスが永続化された後、Aggregated metric instrumentation ガイドに従って集約メトリクス定義を追加できます。Estimated Batch Countersで収集したメトリクスの集約を宣言するには、以下の要件を満たす必要があります:
-
events:
属性にリストされているメトリクス名は、前のステップでメトリクスを永続化する際にmetric_name
引数に渡したものと同じ名前を使用する必要があります。 -
events:
属性にリストされているすべてのメトリクスは、選択したtime_frame:
値ごとに永続化する必要があります。