Commit f5d8a930 authored by Tetiana Chupryna's avatar Tetiana Chupryna Committed by Douglas Barbosa Alexandre

Add usage counter for DependencyList

Make DependencyListUsageCounter similar as PodLogsUsageCounter.
Extract similar tests to shared examples.
parent 61220afa
...@@ -15,7 +15,7 @@ module EE ...@@ -15,7 +15,7 @@ module EE
respond_to do |format| respond_to do |format|
format.html format.html
format.json do format.json do
::Gitlab::PodLogsUsageCounter.increment(project.id) ::Gitlab::UsageCounters::PodLogs.increment(project.id)
::Gitlab::PollingInterval.set_header(response, interval: 3_000) ::Gitlab::PollingInterval.set_header(response, interval: 3_000)
render json: { render json: {
......
...@@ -8,6 +8,8 @@ module Projects ...@@ -8,6 +8,8 @@ module Projects
def index def index
respond_to do |format| respond_to do |format|
format.json do format.json do
::Gitlab::UsageCounters::DependencyList.increment(project.id)
render json: ::DependencyListSerializer.new(project: project) render json: ::DependencyListSerializer.new(project: project)
.represent(paginated_dependencies, build: build) .represent(paginated_dependencies, build: build)
end end
...@@ -17,7 +19,10 @@ module Projects ...@@ -17,7 +19,10 @@ module Projects
private private
def build def build
@build ||= pipeline.builds.latest return unless pipeline
return @build if @build
@build = pipeline.builds.latest
.with_reports(::Ci::JobArtifact.dependency_list_reports) .with_reports(::Ci::JobArtifact.dependency_list_reports)
.last .last
end end
......
---
title: Count usage of DependencyList endpoint
merge_request: 13962
author:
type: added
...@@ -132,7 +132,8 @@ module EE ...@@ -132,7 +132,8 @@ module EE
projects_with_packages: count(::Packages::Package.select('distinct project_id')), projects_with_packages: count(::Packages::Package.select('distinct project_id')),
projects_with_tracing_enabled: count(ProjectTracingSetting), projects_with_tracing_enabled: count(ProjectTracingSetting),
projects_enforcing_code_owner_approval: count(::Project.without_deleted.non_archived.requiring_code_owner_approval), projects_enforcing_code_owner_approval: count(::Project.without_deleted.non_archived.requiring_code_owner_approval),
operations_dashboard: operations_dashboard_usage operations_dashboard: operations_dashboard_usage,
dependency_list_usages_total: ::Gitlab::UsageCounters::DependencyList.usage_totals[:total]
}).merge(service_desk_counts).merge(security_products_usage) }).merge(service_desk_counts).merge(security_products_usage)
# MySql does not support recursive queries so we can't retrieve epics relationship depth # MySql does not support recursive queries so we can't retrieve epics relationship depth
...@@ -145,9 +146,9 @@ module EE ...@@ -145,9 +146,9 @@ module EE
override :usage_counters override :usage_counters
def usage_counters def usage_counters
super.merge( super.merge({
pod_logs_usages: ::Gitlab::PodLogsUsageCounter.usage_totals pod_logs_usages: ::Gitlab::UsageCounters::PodLogs.usage_totals
) })
end end
override :jira_usage override :jira_usage
......
# frozen_string_literal: true
module Gitlab
module PodLogsUsageCounter
BASE_KEY = "POD_LOGS_USAGE_COUNTS"
class << self
def increment(project_id)
Gitlab::Redis::SharedState.with { |redis| redis.hincrby(BASE_KEY, project_id, 1) }
end
def usage_totals
Gitlab::Redis::SharedState.with do |redis|
total_sum = 0
totals = redis.hgetall(BASE_KEY).each_with_object({}) do |(project_id, count), result|
total_sum += result[project_id.to_i] = count.to_i
end
totals[:total] = total_sum
totals
end
end
end
end
end
# frozen_string_literal: true
module Gitlab
module UsageCounters
class Common
class << self
def increment(project_id)
Gitlab::Redis::SharedState.with { |redis| redis.hincrby(base_key, project_id, 1) }
end
def usage_totals
Gitlab::Redis::SharedState.with do |redis|
total_sum = 0
totals = redis.hgetall(base_key).each_with_object({}) do |(project_id, count), result|
total_sum += result[project_id.to_i] = count.to_i
end
totals[:total] = total_sum
totals
end
end
def base_key
raise NotImplementedError
end
end
end
end
end
# frozen_string_literal: true
module Gitlab
module UsageCounters
class DependencyList < Common
def self.base_key
'DEPENDENCY_LIST_USAGE_COUNTER'
end
end
end
end
# frozen_string_literal: true
module Gitlab
module UsageCounters
class PodLogs < Common
def self.base_key
'POD_LOGS_USAGE_COUNTS'
end
end
end
end
...@@ -119,7 +119,7 @@ describe Projects::EnvironmentsController do ...@@ -119,7 +119,7 @@ describe Projects::EnvironmentsController do
end end
it 'registers a usage of the endpoint' do it 'registers a usage of the endpoint' do
expect(::Gitlab::PodLogsUsageCounter).to receive(:increment).with(project.id) expect(::Gitlab::UsageCounters::PodLogs).to receive(:increment).with(project.id)
get :logs, params: environment_params(pod_name: pod_name, format: :json) get :logs, params: environment_params(pod_name: pod_name, format: :json)
end end
......
...@@ -22,6 +22,12 @@ describe Projects::Security::DependenciesController do ...@@ -22,6 +22,12 @@ describe Projects::Security::DependenciesController do
stub_licensed_features(dependency_list: true) stub_licensed_features(dependency_list: true)
end end
it 'counts usage of the feature' do
expect(::Gitlab::UsageCounters::DependencyList).to receive(:increment).with(project.id)
get :index, params: params, format: :json
end
context 'with existing report' do context 'with existing report' do
let!(:pipeline) { create(:ee_ci_pipeline, :with_dependency_list_report, project: project) } let!(:pipeline) { create(:ee_ci_pipeline, :with_dependency_list_report, project: project) }
......
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::UsageCounters::DependencyList, :clean_gitlab_redis_shared_state do
it_behaves_like 'a usage counter'
end
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::UsageCounters::PodLogs, :clean_gitlab_redis_shared_state do
it_behaves_like 'a usage counter'
end
...@@ -82,6 +82,7 @@ describe Gitlab::UsageData do ...@@ -82,6 +82,7 @@ describe Gitlab::UsageData do
projects_jira_dvcs_server_active projects_jira_dvcs_server_active
feature_flags feature_flags
operations_dashboard operations_dashboard
dependency_list_usages_total
)) ))
expect(count_data[:projects_with_prometheus_alerts]).to eq(2) expect(count_data[:projects_with_prometheus_alerts]).to eq(2)
......
# frozen_string_literal: true # frozen_string_literal: true
require 'spec_helper' RSpec.shared_examples 'a usage counter' do
describe Gitlab::PodLogsUsageCounter, :clean_gitlab_redis_shared_state do
describe '.increment' do describe '.increment' do
let(:project_id) { 12 }
it 'intializes and increments the counter for the project by 1' do it 'intializes and increments the counter for the project by 1' do
expect do expect do
described_class.increment(12) described_class.increment(project_id)
end.to change { described_class.usage_totals[12] }.from(nil).to(1) end.to change { described_class.usage_totals[project_id] }.from(nil).to(1)
end end
end end
describe '.usage_totals' do describe '.usage_totals' do
let(:usage_totals) { described_class.usage_totals }
context 'when the feature has not been used' do context 'when the feature has not been used' do
it 'returns the total counts and counts per project' do it 'returns the total counts and counts per project' do
expect(described_class.usage_totals.keys).to eq([:total]) expect(usage_totals.keys).to eq([:total])
expect(described_class.usage_totals[:total]).to eq(0) expect(usage_totals[:total]).to eq(0)
end end
end end
context 'when the feature has been used in multiple projects' do context 'when the feature has been used in multiple projects' do
let(:project1_id) { 12 }
let(:project2_id) { 16 }
before do before do
described_class.increment(12) described_class.increment(project1_id)
described_class.increment(16) described_class.increment(project2_id)
end end
it 'returns the total counts and counts per project' do it 'returns the total counts and counts per project' do
expect(described_class.usage_totals[12]).to eq(1) expect(usage_totals[project1_id]).to eq(1)
expect(described_class.usage_totals[16]).to eq(1) expect(usage_totals[project2_id]).to eq(1)
expect(described_class.usage_totals[:total]).to eq(2) expect(usage_totals[:total]).to eq(2)
end end
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