Commit 073e8c76 authored by Pavel Shutsin's avatar Pavel Shutsin

Merge branch '350661-collecting-mau-for-gitlab-intellij-plugin' into 'master'

Track API requests for jetbrains plugin

See merge request gitlab-org/gitlab!78713
parents f97bd34f abf7ea97
......@@ -168,6 +168,7 @@ Naming/FileName:
- GitLab
- JavaScript
- VSCode
- JetBrains
# default ones:
- CLI
- DSL
......
......@@ -31,6 +31,7 @@ class GraphqlController < ApplicationController
before_action :authorize_access_api!
before_action :set_user_last_activity
before_action :track_vs_code_usage
before_action :track_jetbrains_usage
before_action :disable_query_limiting
before_action :limit_query_size
......@@ -137,6 +138,11 @@ class GraphqlController < ApplicationController
.track_api_request_when_trackable(user_agent: request.user_agent, user: current_user)
end
def track_jetbrains_usage
Gitlab::UsageDataCounters::JetBrainsPluginActivityUniqueCounter
.track_api_request_when_trackable(user_agent: request.user_agent, user: current_user)
end
def execute_multiplex
GitlabSchema.multiplex(multiplex_queries, context: context)
end
......
---
name: usage_data_i_code_review_user_jetbrains_api_request
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78713
rollout_issue_url:
milestone: '14.8'
type: development
group: group::code review
default_enabled: true
......@@ -39,6 +39,7 @@ Rails.autoloaders.each do |autoloader|
'hangouts_chat_http_override' => 'HangoutsChatHTTPOverride',
'chunked_io' => 'ChunkedIO',
'http_io' => 'HttpIO',
'jetbrains_plugin_activity_unique_counter' => 'JetBrainsPluginActivityUniqueCounter',
'json_formatter' => 'JSONFormatter',
'json_web_token' => 'JSONWebToken',
'as_json' => 'AsJSON',
......
......@@ -73,6 +73,7 @@
- 'i_code_review_post_merge_click_cherry_pick'
- 'i_code_review_post_merge_submit_revert_modal'
- 'i_code_review_post_merge_submit_cherry_pick_modal'
- 'i_code_review_user_jetbrains_api_request'
- name: code_review_category_monthly_active_users
operator: OR
source: redis
......@@ -144,3 +145,4 @@
time_frame: [7d, 28d]
events:
- 'i_code_review_user_vs_code_api_request'
- 'i_code_review_user_jetbrains_api_request'
---
key_path: redis_hll_counters.code_review.i_code_review_user_jetbrains_api_request_monthly
description: Count of unique users per month who use GitLab plugin for JetBrains
product_section: dev
product_stage: create
product_group: group::code review
product_category: editor_extension
value_type: number
status: active
milestone: "14.8"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78713
time_frame: 28d
data_source: redis_hll
data_category: optional
instrumentation_class: RedisHLLMetric
options:
events:
- i_code_review_user_jetbrains_api_request
performance_indicator_type: []
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
---
key_path: redis_hll_counters.code_review.i_code_review_user_jetbrains_api_request_weekly
description: Count of unique users per month who use GitLab plugin for JetBrains
product_section: dev
product_stage: create
product_group: group::code review
product_category: editor_extension
value_type: number
status: active
milestone: "14.8"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78713
time_frame: 7d
data_source: redis_hll
data_category: optional
instrumentation_class: RedisHLLMetric
options:
events:
- i_code_review_user_jetbrains_api_request
performance_indicator_type: []
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
......@@ -76,6 +76,10 @@ module API
Gitlab::UsageDataCounters::VSCodeExtensionActivityUniqueCounter.track_api_request_when_trackable(user_agent: request&.user_agent, user: @current_user)
end
after do
Gitlab::UsageDataCounters::JetBrainsPluginActivityUniqueCounter.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 }
......
# frozen_string_literal: true
module Gitlab
module UsageDataCounters
module JetBrainsPluginActivityUniqueCounter
JETBRAINS_API_REQUEST_ACTION = 'i_code_review_user_jetbrains_api_request'
JETBRAINS_USER_AGENT_REGEX = /\Agitlab-jetbrains-plugin/.freeze
class << self
def track_api_request_when_trackable(user_agent:, user:)
user_agent&.match?(JETBRAINS_USER_AGENT_REGEX) && track_unique_action_by_user(JETBRAINS_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
......@@ -127,6 +127,11 @@
redis_slot: code_review
category: code_review
aggregation: weekly
- name: i_code_review_user_jetbrains_api_request
redis_slot: code_review
category: code_review
aggregation: weekly
feature_flag: usage_data_i_code_review_user_jetbrains_api_request
- name: i_code_review_user_create_mr_from_issue
redis_slot: code_review
category: code_review
......
......@@ -51,7 +51,8 @@ module QA
"smtp" => "SMTP",
"otp" => "OTP",
"jira_api" => "JiraAPI",
"registry_tls" => "RegistryTLS"
"registry_tls" => "RegistryTLS",
"jetbrains" => "JetBrains"
)
loader.setup
......
......@@ -124,6 +124,16 @@ RSpec.describe GraphqlController do
post :execute
end
it 'calls the track jetbrains api when trackable method' do
agent = 'gitlab-jetbrains-plugin/0.0.1 intellij-idea/2021.2.4 java/11.0.13 mac-os-x/aarch64/12.1'
request.env['HTTP_USER_AGENT'] = agent
expect(Gitlab::UsageDataCounters::JetBrainsPluginActivityUniqueCounter)
.to receive(:track_api_request_when_trackable).with(user_agent: agent, user: user)
post :execute
end
end
context 'when user uses an API token' do
......@@ -151,6 +161,16 @@ RSpec.describe GraphqlController do
subject
end
it 'calls the track jetbrains api when trackable method' do
agent = 'gitlab-jetbrains-plugin/0.0.1 intellij-idea/2021.2.4 java/11.0.13 mac-os-x/aarch64/12.1'
request.env['HTTP_USER_AGENT'] = agent
expect(Gitlab::UsageDataCounters::JetBrainsPluginActivityUniqueCounter)
.to receive(:track_api_request_when_trackable).with(user_agent: agent, user: user)
subject
end
end
context 'when user is not logged in' do
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.shared_examples 'a tracked jetbrains unique action' do |event|
before do
stub_application_setting(usage_ping_enabled: true)
end
def count_unique(date_from:, date_to:)
Gitlab::UsageDataCounters::HLLRedisCounter.unique_events(event_names: action, start_date: date_from, end_date: date_to)
end
it 'tracks when the user agent is from jetbrains' do
aggregate_failures do
user_agent = { user_agent: 'gitlab-jetbrains-plugin/0.0.1 intellij-idea/2021.2.4 java/11.0.13 mac-os-x/aarch64/12.1' }
expect(track_action(user: user1, **user_agent)).to be_truthy
expect(track_action(user: user1, **user_agent)).to be_truthy
expect(track_action(user: user2, **user_agent)).to be_truthy
expect(count_unique(date_from: time - 1.week, date_to: time + 1.week)).to eq(2)
end
end
it 'does not track when the user agent is not from jetbrains' do
aggregate_failures do
user_agent = { user_agent: 'normal_user_agent' }
expect(track_action(user: user1, **user_agent)).to be_falsey
expect(track_action(user: user1, **user_agent)).to be_falsey
expect(track_action(user: user2, **user_agent)).to be_falsey
expect(count_unique(date_from: time - 1.week, date_to: time + 1.week)).to eq(0)
end
end
it 'does not track if user agent is not present' do
expect(track_action(user: nil, user_agent: nil)).to be_nil
end
it 'does not track if user is not present' do
user_agent = { user_agent: 'gitlab-jetbrains-plugin/0.0.1 intellij-idea/2021.2.4 java/11.0.13 mac-os-x/aarch64/12.1' }
expect(track_action(user: nil, **user_agent)).to be_nil
end
end
RSpec.describe Gitlab::UsageDataCounters::JetBrainsPluginActivityUniqueCounter, :clean_gitlab_redis_shared_state do
let(:user1) { build(:user, id: 1) }
let(:user2) { build(:user, id: 2) }
let(:time) { Time.current }
context 'when tracking a jetbrains api request' do
it_behaves_like 'a tracked jetbrains unique action' do
let(:action) { described_class::JETBRAINS_API_REQUEST_ACTION }
def track_action(params)
described_class.track_api_request_when_trackable(**params)
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment