From 63639224ce880c2ac8d5a8b0301f474665c6fd16 Mon Sep 17 00:00:00 2001 From: Kai Armstrong Date: Tue, 22 Mar 2022 15:03:08 -0500 Subject: [PATCH] Track api usage of the gitlab cli This implements RedisHLL tracking for api requests made from the GitLab CLI. Changelog: added --- app/controllers/graphql_controller.rb | 6 ++++ ...ode_review_user_gitlab_cli_api_request.yml | 8 ++++++ .../004_zeitwerk.rb | 1 + config/metrics/aggregates/code_review.yml | 2 ++ ...1_users_gitlab_cli_api_request_monthly.yml | 26 +++++++++++++++++ ...22_users_gitlab_cli_api_request_weekly.yml | 26 +++++++++++++++++ lib/api/api.rb | 4 +++ .../gitlab_cli_activity_unique_counter.rb | 28 +++++++++++++++++++ .../known_events/code_review_events.yml | 5 ++++ spec/controllers/graphql_controller_spec.rb | 20 +++++++++++++ ...gitlab_cli_activity_unique_counter_spec.rb | 15 ++++++++++ 11 files changed, 141 insertions(+) create mode 100644 config/feature_flags/development/usage_data_i_code_review_user_gitlab_cli_api_request.yml create mode 100644 config/metrics/counts_28d/20220322194931_users_gitlab_cli_api_request_monthly.yml create mode 100644 config/metrics/counts_7d/20220322194922_users_gitlab_cli_api_request_weekly.yml create mode 100644 lib/gitlab/usage_data_counters/gitlab_cli_activity_unique_counter.rb create mode 100644 spec/lib/gitlab/usage_data_counters/gitlab_cli_activity_unique_counter_spec.rb diff --git a/app/controllers/graphql_controller.rb b/app/controllers/graphql_controller.rb index ef229a2abec5a4..8e2c471a19a4dd 100644 --- a/app/controllers/graphql_controller.rb +++ b/app/controllers/graphql_controller.rb @@ -32,6 +32,7 @@ class GraphqlController < ApplicationController before_action :set_user_last_activity before_action :track_vs_code_usage before_action :track_jetbrains_usage + before_action :track_gitlab_cli_usage before_action :disable_query_limiting before_action :limit_query_size @@ -143,6 +144,11 @@ def track_jetbrains_usage .track_api_request_when_trackable(user_agent: request.user_agent, user: current_user) end + def track_gitlab_cli_usage + Gitlab::UsageDataCounters::GitLabCliActivityUniqueCounter + .track_api_request_when_trackable(user_agent: request.user_agent, user: current_user) + end + def execute_multiplex GitlabSchema.multiplex(multiplex_queries, context: context) end diff --git a/config/feature_flags/development/usage_data_i_code_review_user_gitlab_cli_api_request.yml b/config/feature_flags/development/usage_data_i_code_review_user_gitlab_cli_api_request.yml new file mode 100644 index 00000000000000..898c19a34a9321 --- /dev/null +++ b/config/feature_flags/development/usage_data_i_code_review_user_gitlab_cli_api_request.yml @@ -0,0 +1,8 @@ +--- +name: usage_data_i_code_review_user_gitlab_cli_api_request +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/83464 +rollout_issue_url: +milestone: '14.10' +type: development +group: group::code review +default_enabled: true diff --git a/config/initializers_before_autoloader/004_zeitwerk.rb b/config/initializers_before_autoloader/004_zeitwerk.rb index 60cc57c3282ab7..ff96a84166a12e 100644 --- a/config/initializers_before_autoloader/004_zeitwerk.rb +++ b/config/initializers_before_autoloader/004_zeitwerk.rb @@ -25,6 +25,7 @@ 'cidr' => 'CIDR', 'cli' => 'CLI', 'dn' => 'DN', + 'gitlab_cli_activity_unique_counter' => 'GitLabCliActivityUniqueCounter', 'global_id_type' => 'GlobalIDType', 'global_id_compatibility' => 'GlobalIDCompatibility', 'hll' => 'HLL', diff --git a/config/metrics/aggregates/code_review.yml b/config/metrics/aggregates/code_review.yml index aee0e602e7b2f0..004f155864e7bb 100644 --- a/config/metrics/aggregates/code_review.yml +++ b/config/metrics/aggregates/code_review.yml @@ -74,6 +74,7 @@ - 'i_code_review_post_merge_submit_revert_modal' - 'i_code_review_post_merge_submit_cherry_pick_modal' - 'i_code_review_user_jetbrains_api_request' + - 'i_code_review_user_gitlab_cli_api_request' - name: code_review_category_monthly_active_users operator: OR source: redis @@ -146,3 +147,4 @@ events: - 'i_code_review_user_vs_code_api_request' - 'i_code_review_user_jetbrains_api_request' + - 'i_code_review_user_gitlab_cli_api_request' diff --git a/config/metrics/counts_28d/20220322194931_users_gitlab_cli_api_request_monthly.yml b/config/metrics/counts_28d/20220322194931_users_gitlab_cli_api_request_monthly.yml new file mode 100644 index 00000000000000..2d534efba1c540 --- /dev/null +++ b/config/metrics/counts_28d/20220322194931_users_gitlab_cli_api_request_monthly.yml @@ -0,0 +1,26 @@ +--- +key_path: redis_hll_counters.code_review.i_code_review_user_gitlab_cli_api_request_monthly +description: Count of unique users per month who use the GitLab CLI +product_section: dev +product_stage: create +product_group: group::code review +product_category: editor_extension +value_type: number +status: active +milestone: "14.10" +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/83464 +time_frame: 28d +data_source: redis_hll +data_category: optional +instrumentation_class: RedisHLLMetric +options: + events: + - i_code_review_user_gitlab_cli_api_request +performance_indicator_type: [] +distribution: +- ce +- ee +tier: +- free +- premium +- ultimate diff --git a/config/metrics/counts_7d/20220322194922_users_gitlab_cli_api_request_weekly.yml b/config/metrics/counts_7d/20220322194922_users_gitlab_cli_api_request_weekly.yml new file mode 100644 index 00000000000000..333e84873b4d3d --- /dev/null +++ b/config/metrics/counts_7d/20220322194922_users_gitlab_cli_api_request_weekly.yml @@ -0,0 +1,26 @@ +--- +key_path: redis_hll_counters.code_review.i_code_review_user_gitlab_cli_api_request_weekly +description: Count of unique users per week who use the GitLab CLI +product_section: dev +product_stage: create +product_group: group::code review +product_category: editor_extension +value_type: number +status: active +milestone: "14.10" +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/83464 +time_frame: 7d +data_source: redis_hll +data_category: optional +instrumentation_class: RedisHLLMetric +options: + events: + - i_code_review_user_gitlab_cli_api_request +performance_indicator_type: [] +distribution: +- ce +- ee +tier: +- free +- premium +- ultimate diff --git a/lib/api/api.rb b/lib/api/api.rb index 5100ec9ec9dbee..af0e0a12ae9371 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -80,6 +80,10 @@ class API < ::API::Base Gitlab::UsageDataCounters::JetBrainsPluginActivityUniqueCounter.track_api_request_when_trackable(user_agent: request&.user_agent, user: @current_user) end + after do + Gitlab::UsageDataCounters::GitLabCliActivityUniqueCounter.track_api_request_when_trackable(user_agent: request&.user_agent, user: @current_user) + end + # The locale is set to the current user's locale when `current_user` is loaded after { Gitlab::I18n.use_default_locale } diff --git a/lib/gitlab/usage_data_counters/gitlab_cli_activity_unique_counter.rb b/lib/gitlab/usage_data_counters/gitlab_cli_activity_unique_counter.rb new file mode 100644 index 00000000000000..8a57a0331b85dd --- /dev/null +++ b/lib/gitlab/usage_data_counters/gitlab_cli_activity_unique_counter.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module Gitlab + module UsageDataCounters + module GitLabCliActivityUniqueCounter + GITLAB_CLI_API_REQUEST_ACTION = 'i_code_review_user_gitlab_cli_api_request' + GITLAB_CLI_USER_AGENT_REGEX = /GitLab\sCLI$/.freeze + + class << self + def track_api_request_when_trackable(user_agent:, user:) + user_agent&.match?(GITLAB_CLI_USER_AGENT_REGEX) && track_unique_action_by_user(GITLAB_CLI_API_REQUEST_ACTION, user) + end + + private + + def track_unique_action_by_user(action, user) + return unless user + + track_unique_action(action, user.id) + end + + def track_unique_action(action, value) + Gitlab::UsageDataCounters::HLLRedisCounter.track_usage_event(action, value) + end + end + end + end +end diff --git a/lib/gitlab/usage_data_counters/known_events/code_review_events.yml b/lib/gitlab/usage_data_counters/known_events/code_review_events.yml index 42c51ec3921261..94801ec0ed61f7 100644 --- a/lib/gitlab/usage_data_counters/known_events/code_review_events.yml +++ b/lib/gitlab/usage_data_counters/known_events/code_review_events.yml @@ -132,6 +132,11 @@ category: code_review aggregation: weekly feature_flag: usage_data_i_code_review_user_jetbrains_api_request +- name: i_code_review_user_gitlab_cli_api_request + redis_slot: code_review + category: code_review + aggregation: weekly + feature_flag: usage_data_i_code_review_user_gitlab_cli_api_request - name: i_code_review_user_create_mr_from_issue redis_slot: code_review category: code_review diff --git a/spec/controllers/graphql_controller_spec.rb b/spec/controllers/graphql_controller_spec.rb index a9ceb695ba4047..07fb568e512a0e 100644 --- a/spec/controllers/graphql_controller_spec.rb +++ b/spec/controllers/graphql_controller_spec.rb @@ -135,6 +135,16 @@ post :execute end + it 'calls the track gitlab cli when trackable method' do + agent = 'GLab - GitLab CLI' + request.env['HTTP_USER_AGENT'] = agent + + expect(Gitlab::UsageDataCounters::GitLabCliActivityUniqueCounter) + .to receive(:track_api_request_when_trackable).with(user_agent: agent, user: user) + + post :execute + end + it "assigns username in ApplicationContext" do post :execute @@ -220,6 +230,16 @@ subject end + + it 'calls the track gitlab cli when trackable method' do + agent = 'GLab - GitLab CLI' + request.env['HTTP_USER_AGENT'] = agent + + expect(Gitlab::UsageDataCounters::GitLabCliActivityUniqueCounter) + .to receive(:track_api_request_when_trackable).with(user_agent: agent, user: user) + + subject + end end context 'when user is not logged in' do diff --git a/spec/lib/gitlab/usage_data_counters/gitlab_cli_activity_unique_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/gitlab_cli_activity_unique_counter_spec.rb new file mode 100644 index 00000000000000..d6eb67e5c3574a --- /dev/null +++ b/spec/lib/gitlab/usage_data_counters/gitlab_cli_activity_unique_counter_spec.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::UsageDataCounters::GitLabCliActivityUniqueCounter, :clean_gitlab_redis_shared_state do # rubocop:disable RSpec/FilePath + let(:user1) { build(:user, id: 1) } + let(:user2) { build(:user, id: 2) } + let(:time) { Time.current } + let(:action) { described_class::GITLAB_CLI_API_REQUEST_ACTION } + let(:user_agent) { { user_agent: 'GLab - GitLab CLI' } } + + context 'when tracking a gitlab cli request' do + it_behaves_like 'a request from an extension' + end +end -- GitLab