diff --git a/doc/administration/monitoring/prometheus/gitlab_metrics.md b/doc/administration/monitoring/prometheus/gitlab_metrics.md index 913a730ee6b4609cf41c6bb8dfb87ff2c8831481..a3805e57f35e2eda44a91ddc07e4fc30c2805655 100644 --- a/doc/administration/monitoring/prometheus/gitlab_metrics.md +++ b/doc/administration/monitoring/prometheus/gitlab_metrics.md @@ -179,6 +179,7 @@ The following metrics are available: | `gitlab_ci_queue_active_runners_total` | Histogram | 16.3 | The amount of active runners that can process queue in a project | | `gitlab_connection_pool_size` | Gauge | 16.7 | Size of connection pool | | `gitlab_connection_pool_available_count` | Gauge | 16.7 | Number of available connections in the pool | +| `gitlab_security_policies_scan_result_process_duration_seconds` | Histogram | 16.7 | The amount of time to process scan result policies | ## Metrics controlled by a feature flag diff --git a/ee/app/workers/security/process_scan_result_policy_worker.rb b/ee/app/workers/security/process_scan_result_policy_worker.rb index e79abcf7bc984a7340531456d147949f914eb60a..8d63461630c80769fb9e32855449ba3af7283148 100644 --- a/ee/app/workers/security/process_scan_result_policy_worker.rb +++ b/ee/app/workers/security/process_scan_result_policy_worker.rb @@ -11,16 +11,20 @@ class ProcessScanResultPolicyWorker sidekiq_options retry: true feature_category :security_policy_management + HISTOGRAM_BUCKETS = [120, 240, 360, 480, 600, 720, 840, 960].freeze + def perform(project_id, configuration_id) - project = Project.find_by_id(project_id) - configuration = Security::OrchestrationPolicyConfiguration.find_by_id(configuration_id) - return unless project && configuration + measure(project_id, configuration_id) do + project = Project.find_by_id(project_id) + configuration = Security::OrchestrationPolicyConfiguration.find_by_id(configuration_id) + break unless project && configuration - sync_policies(project, configuration, applicable_active_policies(configuration, project)) + sync_policies(project, configuration, applicable_active_policies(configuration, project)) - Security::SecurityOrchestrationPolicies::SyncOpenedMergeRequestsService - .new(project: project, policy_configuration: configuration) - .execute + Security::SecurityOrchestrationPolicies::SyncOpenedMergeRequestsService + .new(project: project, policy_configuration: configuration) + .execute + end end private @@ -46,5 +50,21 @@ def sync_policies(project, configuration, active_scan_result_policies) .execute end end + + def measure(project_id, configuration_id) + lo = ::Gitlab::Metrics::System.monotonic_time + yield + hi = ::Gitlab::Metrics::System.monotonic_time + + histogram.observe({ project_id: project_id, configuration_id: configuration_id }, hi - lo) + end + + def histogram + Gitlab::Metrics.histogram( + :gitlab_security_policies_scan_result_process_duration_seconds, + 'The amount of time to process scan result policies', + {}, + HISTOGRAM_BUCKETS) + end end end diff --git a/ee/spec/workers/security/process_scan_result_policy_worker_spec.rb b/ee/spec/workers/security/process_scan_result_policy_worker_spec.rb index 4b147ba8df804ed506f9176e8443b97210709d21..cd8ad366a81d9c580a0c702f99e899b3ec3db585 100644 --- a/ee/spec/workers/security/process_scan_result_policy_worker_spec.rb +++ b/ee/spec/workers/security/process_scan_result_policy_worker_spec.rb @@ -58,6 +58,29 @@ describe '#perform' do subject(:worker) { described_class.new } + describe 'metrics' do + specify do + expect(Gitlab::Metrics).to receive(:histogram).with( + :gitlab_security_policies_scan_result_process_duration_seconds, + 'The amount of time to process scan result policies', + {}, + described_class::HISTOGRAM_BUCKETS + ).and_call_original + + worker.perform(configuration.project_id, configuration.id) + end + + specify do + histogram = instance_double('Prometheus::Client::Histogram') + expect(histogram).to receive(:observe).with( + { project_id: configuration.project_id, + configuration_id: configuration.id }, an_instance_of(Float)) + + allow(worker).to receive(:histogram).and_return(histogram) + worker.perform(configuration.project_id, configuration.id) + end + end + it_behaves_like 'when no policy is applicable due to the policy scope' do it 'does not call ProcessScanResultPolicyService to create approval rules' do expect(Security::SecurityOrchestrationPolicies::ProcessScanResultPolicyService).not_to receive(:new)