Commit be509ff2 authored by Peter Leitzen's avatar Peter Leitzen

Usage ping: Histogram for enabled integrations per project

Add metrics config with value type of `histogram`.
Add a changelog.

Fix attributes in metrics config

Move histogram to usage_activity_by_stage.monitor
parent 2940e3fd
---
title: 'Usage ping: Histogram for enabled integrations per project'
merge_request: 55782
author:
type: added
---
key_path: usage_activity_by_stage.monitor.projects_with_enabled_alert_integrations_histogram
description: Histogram (buckets 1 to 100) of projects with at least 1 enabled integration.
product_section: ops
product_stage: monitor
product_group: group::monitor
product_category: incident_management
value_type: object
status: data_available
milestone: "13.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55782
time_frame: all
data_source: database
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
}, },
"value_type": { "value_type": {
"type": "string", "type": "string",
"enum": ["string", "number", "boolean"] "enum": ["string", "number", "boolean", "object"]
}, },
"status": { "status": {
"type": ["string"], "type": ["string"],
......
...@@ -14840,6 +14840,18 @@ Status: `data_available` ...@@ -14840,6 +14840,18 @@ Status: `data_available`
Tiers: `free` Tiers: `free`
### `usage_activity_by_stage.monitor.projects_with_enabled_alert_integrations_histogram`
Histogram (buckets 1 to 100) of projects with at least 1 enabled integration.
[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_all/20210309165717_projects_with_enabled_alert_integrations_histogram.yml)
Group: `group::monitor`
Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
### `usage_activity_by_stage.monitor.projects_with_error_tracking_enabled` ### `usage_activity_by_stage.monitor.projects_with_error_tracking_enabled`
Projects where error tracking is enabled Projects where error tracking is enabled
......
...@@ -32,7 +32,7 @@ Each metric is defined in a separate YAML file consisting of a number of fields: ...@@ -32,7 +32,7 @@ Each metric is defined in a separate YAML file consisting of a number of fields:
| `product_stage` | no | The [stage](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/stages.yml) for the metric. | | `product_stage` | no | The [stage](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/stages.yml) for the metric. |
| `product_group` | yes | The [group](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/stages.yml) that owns the metric. | | `product_group` | yes | The [group](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/stages.yml) that owns the metric. |
| `product_category` | no | The [product category](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/categories.yml) for the metric. | | `product_category` | no | The [product category](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/categories.yml) for the metric. |
| `value_type` | yes | `string`; one of `string`, `number`, `boolean`. | | `value_type` | yes | `string`; one of `string`, `number`, `boolean`, `object`. |
| `status` | yes | `string`; status of the metric, may be set to `data_available`, `planned`, `in_progress`, `implemented`, `not_used`, `deprecated` | | `status` | yes | `string`; status of the metric, may be set to `data_available`, `planned`, `in_progress`, `implemented`, `not_used`, `deprecated` |
| `time_frame` | yes | `string`; may be set to a value like `7d`, `28d`, `all`, `none`. | | `time_frame` | yes | `string`; may be set to a value like `7d`, `28d`, `all`, `none`. |
| `data_source` | yes | `string`; may be set to a value like `database`, `redis`, `redis_hll`, `prometheus`, `ruby`. | | `data_source` | yes | `string`; may be set to a value like `database`, `redis`, `redis_hll`, `prometheus`, `ruby`. |
......
...@@ -134,14 +134,6 @@ RSpec.describe Gitlab::UsageData do ...@@ -134,14 +134,6 @@ RSpec.describe Gitlab::UsageData do
expect(count_data[:epic_issues]).to eq(2) expect(count_data[:epic_issues]).to eq(2)
end end
it 'has integer value for epic relationship level' do
expect(count_data[:epics_deepest_relationship_level]).to be_a_kind_of(Integer)
end
it 'has integer values for all counts' do
expect(count_data.values).to all(be_a_kind_of(Integer))
end
it 'gathers security products usage data' do it 'gathers security products usage data' do
expect(count_data[:container_scanning_jobs]).to eq(1) expect(count_data[:container_scanning_jobs]).to eq(1)
expect(count_data[:dast_jobs]).to eq(1) expect(count_data[:dast_jobs]).to eq(1)
......
...@@ -629,6 +629,9 @@ module Gitlab ...@@ -629,6 +629,9 @@ module Gitlab
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def usage_activity_by_stage_monitor(time_period) def usage_activity_by_stage_monitor(time_period)
# Calculate histogram only for overall as other time periods aren't available/useful here.
integrations_histogram = time_period.empty? ? histogram(::AlertManagement::HttpIntegration.active, :project_id, buckets: 1..100) : nil
{ {
clusters: distinct_count(::Clusters::Cluster.where(time_period), :user_id), clusters: distinct_count(::Clusters::Cluster.where(time_period), :user_id),
clusters_applications_prometheus: cluster_applications_user_distinct_count(::Clusters::Applications::Prometheus, time_period), clusters_applications_prometheus: cluster_applications_user_distinct_count(::Clusters::Applications::Prometheus, time_period),
...@@ -638,8 +641,9 @@ module Gitlab ...@@ -638,8 +641,9 @@ module Gitlab
projects_with_tracing_enabled: distinct_count(::Project.with_tracing_enabled.where(time_period), :creator_id), projects_with_tracing_enabled: distinct_count(::Project.with_tracing_enabled.where(time_period), :creator_id),
projects_with_error_tracking_enabled: distinct_count(::Project.with_enabled_error_tracking.where(time_period), :creator_id), projects_with_error_tracking_enabled: distinct_count(::Project.with_enabled_error_tracking.where(time_period), :creator_id),
projects_with_incidents: distinct_count(::Issue.incident.where(time_period), :project_id), projects_with_incidents: distinct_count(::Issue.incident.where(time_period), :project_id),
projects_with_alert_incidents: distinct_count(::Issue.incident.with_alert_management_alerts.where(time_period), :project_id) projects_with_alert_incidents: distinct_count(::Issue.incident.with_alert_management_alerts.where(time_period), :project_id),
} projects_with_enabled_alert_integrations_histogram: integrations_histogram
}.compact
end end
# rubocop: enable CodeReuse/ActiveRecord # rubocop: enable CodeReuse/ActiveRecord
......
...@@ -34,6 +34,7 @@ UsageData/LargeTable: ...@@ -34,6 +34,7 @@ UsageData/LargeTable:
CountMethods: CountMethods:
- :count - :count
- :distinct_count - :distinct_count
- :histogram
AllowedMethods: AllowedMethods:
- :arel_table - :arel_table
- :minimum - :minimum
......
...@@ -384,12 +384,13 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do ...@@ -384,12 +384,13 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
for_defined_days_back do for_defined_days_back do
user = create(:user, dashboard: 'operations') user = create(:user, dashboard: 'operations')
cluster = create(:cluster, user: user) cluster = create(:cluster, user: user)
create(:project, creator: user) project = create(:project, creator: user)
create(:clusters_applications_prometheus, :installed, cluster: cluster) create(:clusters_applications_prometheus, :installed, cluster: cluster)
create(:project_tracing_setting) create(:project_tracing_setting)
create(:project_error_tracking_setting) create(:project_error_tracking_setting)
create(:incident) create(:incident)
create(:incident, alert_management_alert: create(:alert_management_alert)) create(:incident, alert_management_alert: create(:alert_management_alert))
create(:alert_management_http_integration, :active, project: project)
end end
expect(described_class.usage_activity_by_stage_monitor({})).to include( expect(described_class.usage_activity_by_stage_monitor({})).to include(
...@@ -399,10 +400,12 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do ...@@ -399,10 +400,12 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
projects_with_tracing_enabled: 2, projects_with_tracing_enabled: 2,
projects_with_error_tracking_enabled: 2, projects_with_error_tracking_enabled: 2,
projects_with_incidents: 4, projects_with_incidents: 4,
projects_with_alert_incidents: 2 projects_with_alert_incidents: 2,
projects_with_enabled_alert_integrations_histogram: { '1' => 2 }
) )
expect(described_class.usage_activity_by_stage_monitor(described_class.last_28_days_time_period)).to include( data_28_days = described_class.usage_activity_by_stage_monitor(described_class.last_28_days_time_period)
expect(data_28_days).to include(
clusters: 1, clusters: 1,
clusters_applications_prometheus: 1, clusters_applications_prometheus: 1,
operations_dashboard_default_dashboard: 1, operations_dashboard_default_dashboard: 1,
...@@ -411,6 +414,8 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do ...@@ -411,6 +414,8 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
projects_with_incidents: 2, projects_with_incidents: 2,
projects_with_alert_incidents: 1 projects_with_alert_incidents: 1
) )
expect(data_28_days).not_to include(:projects_with_enabled_alert_integrations_histogram)
end end
end end
...@@ -528,14 +533,14 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do ...@@ -528,14 +533,14 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
expect(subject.keys).to include(*UsageDataHelpers::USAGE_DATA_KEYS) expect(subject.keys).to include(*UsageDataHelpers::USAGE_DATA_KEYS)
end end
it 'gathers usage counts' do it 'gathers usage counts', :aggregate_failures do
count_data = subject[:counts] count_data = subject[:counts]
expect(count_data[:boards]).to eq(1) expect(count_data[:boards]).to eq(1)
expect(count_data[:projects]).to eq(4) expect(count_data[:projects]).to eq(4)
expect(count_data.values_at(*UsageDataHelpers::SMAU_KEYS)).to all(be_an(Integer))
expect(count_data.keys).to include(*UsageDataHelpers::COUNTS_KEYS) expect(count_data.keys).to include(*UsageDataHelpers::COUNTS_KEYS)
expect(UsageDataHelpers::COUNTS_KEYS - count_data.keys).to be_empty expect(UsageDataHelpers::COUNTS_KEYS - count_data.keys).to be_empty
expect(count_data.values).to all(be_a_kind_of(Integer))
end end
it 'gathers usage counts correctly' do it 'gathers usage counts correctly' do
......
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