diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-11-27 18:09:20 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-11-27 18:09:20 +0300 |
commit | 362c8e8462d38d529d2357649cbb2836cad2452c (patch) | |
tree | b304d6531095f2cbc6c43cf8db1800c338b0e11b | |
parent | 55abfc8a0c81b95b532b243bd701033aa0aa2b07 (diff) |
Add latest changes from gitlab-org/gitlab@master
-rw-r--r-- | doc/administration/monitoring/prometheus/gitlab_metrics.md | 2 | ||||
-rw-r--r-- | lib/gitlab/ci/pipeline/chain/command.rb | 6 | ||||
-rw-r--r-- | lib/gitlab/ci/pipeline/metrics.rb | 3 | ||||
-rw-r--r-- | lib/gitlab/tracking/service_ping_context.rb | 43 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/pipeline/chain/command_spec.rb | 57 | ||||
-rw-r--r-- | spec/lib/gitlab/tracking/service_ping_context_spec.rb | 49 |
6 files changed, 129 insertions, 31 deletions
diff --git a/doc/administration/monitoring/prometheus/gitlab_metrics.md b/doc/administration/monitoring/prometheus/gitlab_metrics.md index 7c2d341b779..53ee028bc32 100644 --- a/doc/administration/monitoring/prometheus/gitlab_metrics.md +++ b/doc/administration/monitoring/prometheus/gitlab_metrics.md @@ -41,7 +41,7 @@ The following metrics are available: | `gitlab_cache_operations_total` | Counter | 12.2 | Cache operations by controller or action | `controller`, `action`, `operation` | | `gitlab_cache_read_multikey_count` | Histogram | 15.7 | Count of keys in multi-key cache read operations | `controller`, `action` | | `gitlab_ci_pipeline_builder_scoped_variables_duration` | Histogram | 14.5 | Time in seconds it takes to create the scoped variables for a CI/CD job -| `gitlab_ci_pipeline_creation_duration_seconds` | Histogram | 13.0 | Time in seconds it takes to create a CI/CD pipeline | | +| `gitlab_ci_pipeline_creation_duration_seconds` | Histogram | 13.0 | Time in seconds it takes to create a CI/CD pipeline | `gitlab` | | `gitlab_ci_pipeline_size_builds` | Histogram | 13.1 | Total number of builds within a pipeline grouped by a pipeline source | `source` | | `gitlab_ci_runner_authentication_success_total` | Counter | 15.2 | Total number of times that runner authentication has succeeded | `type` | | `gitlab_ci_runner_authentication_failure_total` | Counter | 15.2 | Total number of times that runner authentication has failed diff --git a/lib/gitlab/ci/pipeline/chain/command.rb b/lib/gitlab/ci/pipeline/chain/command.rb index 837c09e8045..31b130b5ab7 100644 --- a/lib/gitlab/ci/pipeline/chain/command.rb +++ b/lib/gitlab/ci/pipeline/chain/command.rb @@ -110,7 +110,7 @@ module Gitlab logger.observe(:pipeline_creation_duration_s, duration, once: true) metrics.pipeline_creation_duration_histogram - .observe({}, duration.seconds) + .observe({ gitlab: gitlab_org_project?.to_s }, duration.seconds) end def observe_pipeline_size(pipeline) @@ -157,6 +157,10 @@ module Gitlab def full_git_ref_name_unavailable? ref == origin_ref end + + def gitlab_org_project? + project.full_path == 'gitlab-org/gitlab' + end end end end diff --git a/lib/gitlab/ci/pipeline/metrics.rb b/lib/gitlab/ci/pipeline/metrics.rb index c3e0f043b44..04565beeecc 100644 --- a/lib/gitlab/ci/pipeline/metrics.rb +++ b/lib/gitlab/ci/pipeline/metrics.rb @@ -9,7 +9,8 @@ module Gitlab def self.pipeline_creation_duration_histogram name = :gitlab_ci_pipeline_creation_duration_seconds comment = 'Pipeline creation duration' - labels = {} + # @gitlab: boolean value - if project is gitlab-org/gitlab + labels = { gitlab: false } buckets = [0.01, 0.05, 0.1, 0.5, 1.0, 2.0, 5.0, 20.0, 50.0, 240.0] ::Gitlab::Metrics.histogram(name, comment, labels, buckets) diff --git a/lib/gitlab/tracking/service_ping_context.rb b/lib/gitlab/tracking/service_ping_context.rb index 3177dca4ef7..d31ca69a10c 100644 --- a/lib/gitlab/tracking/service_ping_context.rb +++ b/lib/gitlab/tracking/service_ping_context.rb @@ -4,21 +4,22 @@ module Gitlab module Tracking class ServicePingContext SCHEMA_URL = 'iglu:com.gitlab/gitlab_service_ping/jsonschema/1-0-0' - ALLOWED_SOURCES = %i[redis_hll].freeze + REDISHLL_SOURCE = :redis_hll + REDIS_SOURCE = :redis - def initialize(data_source:, event:) - unless ALLOWED_SOURCES.include?(data_source) - raise ArgumentError, "#{data_source} is not acceptable data source for ServicePingContext" - end + ALLOWED_SOURCES = [REDISHLL_SOURCE, REDIS_SOURCE].freeze - @payload = { - data_source: data_source, - event_name: event - } + def initialize(data_source:, event: nil, key_path: nil) + check_configuration(data_source, event, key_path) + + @payload = { data_source: data_source } + + payload[:event_name] = event if data_source.eql? REDISHLL_SOURCE + payload[:key_path] = key_path if data_source.eql? REDIS_SOURCE end def to_context - SnowplowTracker::SelfDescribingJson.new(SCHEMA_URL, @payload) + SnowplowTracker::SelfDescribingJson.new(SCHEMA_URL, payload) end def to_h @@ -27,6 +28,28 @@ module Gitlab data: @payload } end + + private + + attr_reader :payload + + def check_configuration(data_source, event, key_path) + unless ALLOWED_SOURCES.include?(data_source) + configuration_error("#{data_source} is not acceptable data source for ServicePingContext") + end + + if REDISHLL_SOURCE.eql?(data_source) && event.nil? + configuration_error("event attribute can not be missing for #{REDISHLL_SOURCE} data source") + end + + return unless REDIS_SOURCE.eql?(data_source) && key_path.nil? + + configuration_error("key_path attribute can not be missing for #{REDIS_SOURCE} data source") + end + + def configuration_error(message) + Gitlab::ErrorTracking.track_and_raise_for_dev_exception(ArgumentError.new(message)) + end end end end diff --git a/spec/lib/gitlab/ci/pipeline/chain/command_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/command_spec.rb index 9126c6dab21..68158503628 100644 --- a/spec/lib/gitlab/ci/pipeline/chain/command_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/chain/command_spec.rb @@ -374,21 +374,57 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Command do end end + describe '#observe_creation_duration' do + let(:histogram) { instance_double(Prometheus::Client::Histogram) } + let(:duration) { 1.hour } + let(:command) { described_class.new(project: project) } + + subject(:observe_creation_duration) do + command.observe_creation_duration(duration) + end + + it 'records the duration as histogram' do + expect(::Gitlab::Ci::Pipeline::Metrics).to receive(:pipeline_creation_duration_histogram) + .and_return(histogram) + expect(histogram).to receive(:observe) + .with({ gitlab: 'false' }, duration.seconds) + + observe_creation_duration + end + + context 'when project is gitlab-org/gitlab' do + before do + allow(project).to receive(:full_path).and_return('gitlab-org/gitlab') + end + + it 'tracks the duration with the expected label' do + expect(::Gitlab::Ci::Pipeline::Metrics).to receive(:pipeline_creation_duration_histogram) + .and_return(histogram) + expect(histogram).to receive(:observe) + .with({ gitlab: 'true' }, duration.seconds) + + observe_creation_duration + end + end + end + describe '#observe_step_duration' do + let(:histogram) { instance_double(Prometheus::Client::Histogram) } + let(:duration) { 1.hour } + let(:command) { described_class.new } + + subject(:observe_step_duration) do + command.observe_step_duration(Gitlab::Ci::Pipeline::Chain::Build, duration) + end + context 'when ci_pipeline_creation_step_duration_tracking is enabled' do it 'adds the duration to the step duration histogram' do - histogram = instance_double(Prometheus::Client::Histogram) - duration = 1.hour - expect(::Gitlab::Ci::Pipeline::Metrics).to receive(:pipeline_creation_step_duration_histogram) .and_return(histogram) expect(histogram).to receive(:observe) .with({ step: 'Gitlab::Ci::Pipeline::Chain::Build' }, duration.seconds) - described_class.new.observe_step_duration( - Gitlab::Ci::Pipeline::Chain::Build, - duration - ) + observe_step_duration end end @@ -398,14 +434,9 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Command do end it 'does nothing' do - duration = 1.hour - expect(::Gitlab::Ci::Pipeline::Metrics).not_to receive(:pipeline_creation_step_duration_histogram) - described_class.new.observe_step_duration( - Gitlab::Ci::Pipeline::Chain::Build, - duration - ) + observe_step_duration end end end diff --git a/spec/lib/gitlab/tracking/service_ping_context_spec.rb b/spec/lib/gitlab/tracking/service_ping_context_spec.rb index d70dfaa4e0b..7530650b902 100644 --- a/spec/lib/gitlab/tracking/service_ping_context_spec.rb +++ b/spec/lib/gitlab/tracking/service_ping_context_spec.rb @@ -4,16 +4,55 @@ require 'spec_helper' RSpec.describe Gitlab::Tracking::ServicePingContext do describe '#init' do - it 'does not accept unsupported data sources' do - expect { described_class.new(data_source: :random, event: 'event a') }.to raise_error(ArgumentError) + using RSpec::Parameterized::TableSyntax + + context 'with valid configuration' do + where(:data_source, :event, :key_path) do + :redis | nil | 'counts.some_metric' + :redis_hll | 'some_event' | nil + end + + with_them do + it 'does not raise errors' do + expect { described_class.new(data_source: data_source, event: event, key_path: key_path) }.not_to raise_error + end + end + end + + context 'with invalid configuration' do + where(:data_source, :event, :key_path) do + :redis | nil | nil + :redis | 'some_event' | nil + :redis_hll | nil | nil + :redis_hll | nil | 'some key_path' + :random | 'some_event' | nil + end + + with_them do + subject(:new_instance) { described_class.new(data_source: data_source, event: event, key_path: key_path) } + + it 'does not raise errors' do + expect { new_instance }.to raise_error(ArgumentError) + end + end end end describe '#to_context' do - let(:subject) { described_class.new(data_source: :redis_hll, event: 'sample_event') } + context 'for redis_hll data source' do + let(:context_instance) { described_class.new(data_source: :redis_hll, event: 'sample_event') } + + it 'contains event_name' do + expect(context_instance.to_context.to_json.dig(:data, :event_name)).to eq('sample_event') + end + end + + context 'for redis data source' do + let(:context_instance) { described_class.new(data_source: :redis, key_path: 'counts.sample_metric') } - it 'contains event_name' do - expect(subject.to_context.to_json.dig(:data, :event_name)).to eq('sample_event') + it 'contains event_name' do + expect(context_instance.to_context.to_json.dig(:data, :key_path)).to eq('counts.sample_metric') + end end end end |