diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-06-20 14:10:13 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-06-20 14:10:13 +0300 |
commit | 0ea3fcec397b69815975647f5e2aa5fe944a8486 (patch) | |
tree | 7979381b89d26011bcf9bdc989a40fcc2f1ed4ff /lib/gitlab/usage/metrics | |
parent | 72123183a20411a36d607d70b12d57c484394c8e (diff) |
Add latest changes from gitlab-org/gitlab@15-1-stable-eev15.1.0-rc42
Diffstat (limited to 'lib/gitlab/usage/metrics')
12 files changed, 280 insertions, 8 deletions
diff --git a/lib/gitlab/usage/metrics/instrumentations/count_imported_projects_total_metric.rb b/lib/gitlab/usage/metrics/instrumentations/count_imported_projects_total_metric.rb new file mode 100644 index 00000000000..109d2245635 --- /dev/null +++ b/lib/gitlab/usage/metrics/instrumentations/count_imported_projects_total_metric.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +module Gitlab + module Usage + module Metrics + module Instrumentations + class CountImportedProjectsTotalMetric < DatabaseMetric + # Relation and operation are not used, but are included to satisfy expectations + # of other metric generation logic. + relation { Project } + operation :count + + IMPORT_TYPES = %w(gitlab_project gitlab github bitbucket bitbucket_server gitea git manifest + gitlab_migration).freeze + + def value + count(project_relation) + count(entity_relation) + end + + def to_sql + project_relation_sql = Gitlab::Usage::Metrics::Query.for(:count, project_relation) + entity_relation_sql = Gitlab::Usage::Metrics::Query.for(:count, entity_relation) + + "SELECT (#{project_relation_sql}) + (#{entity_relation_sql})" + end + + private + + def project_relation + Project.imported_from(IMPORT_TYPES).where(time_constraints) + end + + def entity_relation + BulkImports::Entity.where(source_type: :project_entity).where(time_constraints) + end + end + end + end + end +end diff --git a/lib/gitlab/usage/metrics/instrumentations/count_issues_metric.rb b/lib/gitlab/usage/metrics/instrumentations/count_issues_metric.rb index 34247f4f6dd..07dfba70d92 100644 --- a/lib/gitlab/usage/metrics/instrumentations/count_issues_metric.rb +++ b/lib/gitlab/usage/metrics/instrumentations/count_issues_metric.rb @@ -11,6 +11,8 @@ module Gitlab finish { Issue.maximum(:id) } relation { Issue } + + cache_start_and_finish_as :issue end end end diff --git a/lib/gitlab/usage/metrics/instrumentations/database_metric.rb b/lib/gitlab/usage/metrics/instrumentations/database_metric.rb index a000b4509c6..3b09100f3ff 100644 --- a/lib/gitlab/usage/metrics/instrumentations/database_metric.rb +++ b/lib/gitlab/usage/metrics/instrumentations/database_metric.rb @@ -18,7 +18,7 @@ module Gitlab UnimplementedOperationError = Class.new(StandardError) # rubocop:disable UsageData/InstrumentationSuperclass class << self - IMPLEMENTED_OPERATIONS = %i(count distinct_count estimate_batch_distinct_count).freeze + IMPLEMENTED_OPERATIONS = %i(count distinct_count estimate_batch_distinct_count sum average).freeze private_constant :IMPLEMENTED_OPERATIONS diff --git a/lib/gitlab/usage/metrics/instrumentations/issues_created_from_alerts_metric.rb b/lib/gitlab/usage/metrics/instrumentations/issues_created_from_alerts_metric.rb new file mode 100644 index 00000000000..e430bc8eb71 --- /dev/null +++ b/lib/gitlab/usage/metrics/instrumentations/issues_created_from_alerts_metric.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +module Gitlab + module Usage + module Metrics + module Instrumentations + class IssuesCreatedFromAlertsMetric < NumbersMetric + ISSUES_FROM_ALERTS_METRICS = [ + IssuesWithAlertManagementAlertsMetric, + IssuesWithPrometheusAlertEvents, + IssuesWithSelfManagedPrometheusAlertEvents + ].freeze + + operation :add + + data do |time_frame| + ISSUES_FROM_ALERTS_METRICS.map { |metric| metric.new(time_frame: time_frame).value } + end + + # overwriting instrumentation to generate the appropriate sql query + def instrumentation + 'SELECT ' + ISSUES_FROM_ALERTS_METRICS.map do |metric| + "(#{metric.new(time_frame: time_frame).instrumentation})" + end.join(' + ') + end + end + end + end + end +end diff --git a/lib/gitlab/usage/metrics/instrumentations/issues_with_alert_management_alerts_metric.rb b/lib/gitlab/usage/metrics/instrumentations/issues_with_alert_management_alerts_metric.rb new file mode 100644 index 00000000000..62b91e50e07 --- /dev/null +++ b/lib/gitlab/usage/metrics/instrumentations/issues_with_alert_management_alerts_metric.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module Gitlab + module Usage + module Metrics + module Instrumentations + class IssuesWithAlertManagementAlertsMetric < DatabaseMetric + # this metric is used in IssuesCreatedFromAlertsMetric + # do not report metric directly in service ping + available? { false } + + operation :count + + start { Issue.minimum(:id) } + finish { Issue.maximum(:id) } + + relation { Issue.with_alert_management_alerts } + + cache_start_and_finish_as :issue + end + end + end + end +end diff --git a/lib/gitlab/usage/metrics/instrumentations/issues_with_prometheus_alert_events.rb b/lib/gitlab/usage/metrics/instrumentations/issues_with_prometheus_alert_events.rb new file mode 100644 index 00000000000..2befec65ac2 --- /dev/null +++ b/lib/gitlab/usage/metrics/instrumentations/issues_with_prometheus_alert_events.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module Gitlab + module Usage + module Metrics + module Instrumentations + class IssuesWithPrometheusAlertEvents < DatabaseMetric + # this metric is used in IssuesCreatedFromAlertsMetric + # do not report metric directly in service ping + available? { false } + + operation :count + + start { Issue.minimum(:id) } + finish { Issue.maximum(:id) } + + relation { Issue.with_prometheus_alert_events } + + cache_start_and_finish_as :issue + end + end + end + end +end diff --git a/lib/gitlab/usage/metrics/instrumentations/issues_with_self_managed_prometheus_alert_events.rb b/lib/gitlab/usage/metrics/instrumentations/issues_with_self_managed_prometheus_alert_events.rb new file mode 100644 index 00000000000..fdbaa65bc68 --- /dev/null +++ b/lib/gitlab/usage/metrics/instrumentations/issues_with_self_managed_prometheus_alert_events.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module Gitlab + module Usage + module Metrics + module Instrumentations + class IssuesWithSelfManagedPrometheusAlertEvents < DatabaseMetric + # this metric is used in IssuesCreatedFromAlertsMetric + # do not report metric directly in service ping + available? { false } + + operation :count + + start { Issue.minimum(:id) } + finish { Issue.maximum(:id) } + + relation { Issue.with_self_managed_prometheus_alert_events } + + cache_start_and_finish_as :issue + end + end + end + end +end diff --git a/lib/gitlab/usage/metrics/instrumentations/jira_imports_total_imported_issues_count_metric.rb b/lib/gitlab/usage/metrics/instrumentations/jira_imports_total_imported_issues_count_metric.rb new file mode 100644 index 00000000000..6ca57864b8a --- /dev/null +++ b/lib/gitlab/usage/metrics/instrumentations/jira_imports_total_imported_issues_count_metric.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Gitlab + module Usage + module Metrics + module Instrumentations + class JiraImportsTotalImportedIssuesCountMetric < DatabaseMetric + operation :sum, column: :imported_issues_count + + relation { JiraImportState.finished } + end + end + end + end +end diff --git a/lib/gitlab/usage/metrics/instrumentations/numbers_metric.rb b/lib/gitlab/usage/metrics/instrumentations/numbers_metric.rb new file mode 100644 index 00000000000..8504ee368fc --- /dev/null +++ b/lib/gitlab/usage/metrics/instrumentations/numbers_metric.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +module Gitlab + module Usage + module Metrics + module Instrumentations + class NumbersMetric < BaseMetric + # Usage Example + # + # class BoardsCountMetric < NumbersMetric + # operation :add + # + # data do |time_frame| + # [ + # CountIssuesMetric.new(time_frame: time_frame).value, + # CountBoardsMetric.new(time_frame: time_frame).value, + # ] + # end + # end + + UnimplementedOperationError = Class.new(StandardError) # rubocop:disable UsageData/InstrumentationSuperclass + + class << self + IMPLEMENTED_OPERATIONS = %i(add).freeze + + private_constant :IMPLEMENTED_OPERATIONS + + def data(&block) + return @metric_data&.call unless block_given? + + @metric_data = block + end + + def operation(symbol) + raise UnimplementedOperationError unless symbol.in?(IMPLEMENTED_OPERATIONS) + + @metric_operation = symbol + end + + attr_reader :metric_operation, :metric_data + end + + def value + method(self.class.metric_operation).call(*data) + end + + def suggested_name + Gitlab::Usage::Metrics::NameSuggestion.for(:alt) + end + + private + + def data + self.class.metric_data.call(time_frame) + end + end + end + end + end +end diff --git a/lib/gitlab/usage/metrics/instrumentations/unique_active_users_metric.rb b/lib/gitlab/usage/metrics/instrumentations/unique_active_users_metric.rb new file mode 100644 index 00000000000..9da30db05dd --- /dev/null +++ b/lib/gitlab/usage/metrics/instrumentations/unique_active_users_metric.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module Gitlab + module Usage + module Metrics + module Instrumentations + class UniqueActiveUsersMetric < DatabaseMetric + operation :count + relation { ::User.active } + + metric_options do + { + batch_size: 10_000 + } + end + + def time_constraints + case time_frame + when '28d' + monthly_time_range_db_params(column: :last_activity_on) + else + super + end + end + end + end + end + end +end diff --git a/lib/gitlab/usage/metrics/name_suggestion.rb b/lib/gitlab/usage/metrics/name_suggestion.rb index 0728af9e2ca..238a7a51a20 100644 --- a/lib/gitlab/usage/metrics/name_suggestion.rb +++ b/lib/gitlab/usage/metrics/name_suggestion.rb @@ -19,6 +19,8 @@ module Gitlab name_suggestion(column: column, relation: relation, prefix: 'estimate_distinct_count') when :sum name_suggestion(column: column, relation: relation, prefix: 'sum') + when :average + name_suggestion(column: column, relation: relation, prefix: 'average') when :redis REDIS_EVENT_METRIC_NAME when :alt diff --git a/lib/gitlab/usage/metrics/query.rb b/lib/gitlab/usage/metrics/query.rb index 851aa7a50e8..e071b422c16 100644 --- a/lib/gitlab/usage/metrics/query.rb +++ b/lib/gitlab/usage/metrics/query.rb @@ -13,6 +13,8 @@ module Gitlab distinct_count(relation, column) when :sum sum(relation, column) + when :average + average(relation, column) when :estimate_batch_distinct_count estimate_batch_distinct_count(relation, column) when :histogram @@ -25,19 +27,23 @@ module Gitlab private def count(relation, column = nil) - raw_sql(relation, column) + raw_count_sql(relation, column) end def distinct_count(relation, column = nil) - raw_sql(relation, column, true) + raw_count_sql(relation, column, true) end def sum(relation, column) - relation.select(relation.all.table[column].sum).to_sql + raw_sum_sql(relation, column) + end + + def average(relation, column) + raw_average_sql(relation, column) end def estimate_batch_distinct_count(relation, column = nil) - raw_sql(relation, column, true) + raw_count_sql(relation, column, true) end # rubocop: disable CodeReuse/ActiveRecord @@ -62,15 +68,31 @@ module Gitlab # rubocop: enable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord - def raw_sql(relation, column, distinct = false) + def raw_count_sql(relation, column, distinct = false) column ||= relation.primary_key - node = node_to_count(relation, column) + node = node_to_operate(relation, column) relation.unscope(:order).select(node.count(distinct)).to_sql end # rubocop: enable CodeReuse/ActiveRecord - def node_to_count(relation, column) + # rubocop: disable CodeReuse/ActiveRecord + def raw_sum_sql(relation, column) + node = node_to_operate(relation, column) + + relation.unscope(:order).select(node.sum).to_sql + end + # rubocop: enable CodeReuse/ActiveRecord + + # rubocop: disable CodeReuse/ActiveRecord + def raw_average_sql(relation, column) + node = node_to_operate(relation, column) + + relation.unscope(:order).select(node.average).to_sql + end + # rubocop: enable CodeReuse/ActiveRecord + + def node_to_operate(relation, column) if join_relation?(relation) && joined_column?(column) table_name, column_name = column.split(".") Arel::Table.new(table_name)[column_name] |