Class: GitLab::Monitor::Database::CiBuildsCollector

Inherits:
Base
  • Object
show all
Defined in:
lib/gitlab_monitor/database/ci_builds.rb

Overview

A helper class to collect CI builds metrics.

Constant Summary collapse

SET_RANDOM_PAGE_COST =

rubocop:disable Metrics/ClassLength

"SET LOCAL random_page_cost TO 1".freeze
BUILDS_QUERY_EE =
<<~SQL.freeze
  SELECT
    projects.namespace_id,
    ci_builds.status,
    projects.shared_runners_enabled,
    (COALESCE(namespaces.shared_runners_minutes_limit, application_settings.shared_runners_minutes, 0) = 0 OR
       COALESCE(namespace_statistics.shared_runners_seconds, 0) < COALESCE(namespaces.shared_runners_minutes_limit, application_settings.shared_runners_minutes, 0) * 60) as has_minutes,
    COUNT(*) AS count
  FROM ci_builds
  JOIN projects
    ON projects.id = ci_builds.project_id
  JOIN namespaces
    ON namespaces.id = projects.namespace_id
  LEFT JOIN namespace_statistics
    ON namespace_statistics.namespace_id = namespaces.id
  JOIN application_settings
    ON application_settings.id = 1
  WHERE ci_builds.type = 'Ci::Build'
    AND ci_builds.status = '%s'
    AND projects.pending_delete = 'f'
  GROUP BY
    projects.namespace_id,
    ci_builds.status,
    projects.shared_runners_enabled,
    namespaces.shared_runners_minutes_limit,
    namespace_statistics.shared_runners_seconds,
    application_settings.shared_runners_minutes
SQL
BUILDS_QUERY_CE =
<<~SQL.freeze
  SELECT
    projects.namespace_id,
    ci_builds.status,
    projects.shared_runners_enabled,
    COUNT(*) AS count
  FROM ci_builds
  JOIN projects
    ON projects.id = ci_builds.project_id
  WHERE ci_builds.type = 'Ci::Build'
    AND ci_builds.status = '%s'
    AND projects.pending_delete = 'f'
  GROUP BY
    projects.namespace_id,
    ci_builds.status,
    projects.shared_runners_enabled
SQL
STALE_BUILDS_QUERY =
<<~SQL.freeze
  SELECT
    COUNT(*) AS count
  FROM ci_builds
  JOIN projects
    ON projects.id = ci_builds.project_id
  WHERE ci_builds.type = 'Ci::Build'
    AND ci_builds.status = 'running'
    AND ci_builds.updated_at < NOW() - INTERVAL '1 hour'
    AND projects.pending_delete = 'f'
SQL
PER_RUNNER_QUERY_EE =
<<~SQL.freeze
  SELECT
    ci_builds.runner_id,
    ci_runners.is_shared,
    projects.namespace_id,
    projects.mirror,
    projects.mirror_trigger_builds,
    ci_pipelines.pipeline_schedule_id,
    ci_builds.trigger_request_id,
    (COALESCE(namespaces.shared_runners_minutes_limit, application_settings.shared_runners_minutes, 0) = 0 OR
       COALESCE(namespace_statistics.shared_runners_seconds, 0) < COALESCE(namespaces.shared_runners_minutes_limit, application_settings.shared_runners_minutes, 0) * 60) as has_minutes,
    COUNT(*) AS count
  FROM ci_builds
  JOIN ci_runners
    ON ci_runners.id = ci_builds.runner_id
  JOIN projects
    ON projects.id = ci_builds.project_id
  JOIN ci_pipelines
    ON ci_pipelines.id = ci_builds.commit_id
  JOIN namespaces
    ON namespaces.id = projects.namespace_id
  LEFT JOIN namespace_statistics
    ON namespace_statistics.namespace_id = namespaces.id
  JOIN application_settings
    ON application_settings.id = 1
  WHERE ci_builds.type = 'Ci::Build'
    AND ci_builds.status = 'running'
    AND projects.pending_delete = 'f'
  GROUP BY
    ci_builds.runner_id,
    ci_runners.is_shared,
    projects.namespace_id,
    projects.mirror,
    projects.mirror_trigger_builds,
    ci_pipelines.pipeline_schedule_id,
    ci_builds.trigger_request_id,
    namespaces.shared_runners_minutes_limit,
    namespace_statistics.shared_runners_seconds,
    application_settings.shared_runners_minutes
SQL
PER_RUNNER_QUERY_CE =
<<~SQL.freeze
  SELECT
    ci_builds.runner_id,
    ci_runners.is_shared,
    projects.namespace_id,
    ci_pipelines.pipeline_schedule_id,
    ci_builds.trigger_request_id,
    COUNT(*) AS count
  FROM ci_builds
  JOIN ci_runners
    ON ci_runners.id = ci_builds.runner_id
  JOIN projects
    ON projects.id = ci_builds.project_id
  JOIN ci_pipelines
    ON ci_pipelines.id = ci_builds.commit_id
  WHERE ci_builds.type = 'Ci::Build'
    AND ci_builds.status = 'running'
    AND projects.pending_delete = 'f'
  GROUP BY
    ci_builds.runner_id,
    ci_runners.is_shared,
    projects.namespace_id,
    ci_pipelines.pipeline_schedule_id,
    ci_builds.trigger_request_id
SQL
MIRROR_COLUMN_QUERY =
<<~SQL.freeze
  SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='projects' AND column_name='mirror')
SQL
REPEATED_COMMANDS_QUERY_EE =
<<~SQL.freeze
  SELECT
    subquery.namespace_id,
    subquery.shared_runners_enabled,
    subquery.project_id,
    subquery.status,
    subquery.has_minutes,
    MAX(subquery.count) as count
  FROM (
    SELECT
      projects.namespace_id,
      projects.shared_runners_enabled,
      ci_builds.project_id,
      ci_builds.commit_id,
      ci_builds.status,
      (COALESCE(namespaces.shared_runners_minutes_limit, application_settings.shared_runners_minutes, 0) = 0 OR
         COALESCE(namespace_statistics.shared_runners_seconds, 0) < COALESCE(namespaces.shared_runners_minutes_limit, application_settings.shared_runners_minutes, 0) * 60) as has_minutes,
      COUNT(*) AS count
    FROM ci_builds
    JOIN projects
      ON projects.id = ci_builds.project_id
    JOIN namespaces
      ON namespaces.id = projects.namespace_id
    LEFT JOIN namespace_statistics
      ON namespace_statistics.namespace_id = namespaces.id
    JOIN application_settings
      ON application_settings.id = 1
    WHERE ci_builds.type = 'Ci::Build'
      AND ci_builds.status IN ('running', 'pending')
    GROUP BY
      projects.namespace_id,
      projects.shared_runners_enabled,
      ci_builds.project_id,
      ci_builds.commit_id,
      ci_builds.status,
      ci_builds.commands,
      namespaces.shared_runners_minutes_limit,
      namespace_statistics.shared_runners_seconds,
      application_settings.shared_runners_minutes
    HAVING COUNT(*) > %d
  ) AS subquery
  GROUP BY
    subquery.namespace_id,
    subquery.shared_runners_enabled,
    subquery.project_id,
    subquery.commit_id,
    subquery.status,
    subquery.has_minutes
SQL
REPEATED_COMMANDS_QUERY_CE =
<<~SQL.freeze
  SELECT
    subquery.namespace_id,
    subquery.shared_runners_enabled,
    subquery.project_id,
    subquery.status,
    MAX(subquery.count) as count
  FROM (
    SELECT
      projects.namespace_id,
      projects.shared_runners_enabled,
      ci_builds.project_id,
      ci_builds.commit_id,
      ci_builds.status,
      COUNT(*) AS count
    FROM ci_builds
    JOIN projects
      ON projects.id = ci_builds.project_id
    JOIN namespaces
      ON namespaces.id = projects.namespace_id
    WHERE ci_builds.type = 'Ci::Build'
      AND ci_builds.status IN ('running', 'pending')
    GROUP BY
      projects.namespace_id,
      projects.shared_runners_enabled,
      ci_builds.project_id,
      ci_builds.commit_id,
      ci_builds.status,
      ci_builds.commands
    HAVING COUNT(*) > %d
  ) AS subquery
  GROUP BY
    subquery.namespace_id,
    subquery.shared_runners_enabled,
    subquery.project_id,
    subquery.commit_id,
    subquery.status
SQL
UNARCHIVED_TRACES_QUERY =
<<~SQL.freeze
  SELECT
    COUNT(*) as count
  FROM ci_builds
  JOIN ci_build_trace_chunks
    ON ci_build_trace_chunks.build_id = ci_builds.id
  LEFT JOIN ci_job_artifacts
    ON ci_job_artifacts.job_id = ci_builds.id
    AND ci_job_artifacts.file_type = 3
  WHERE ci_builds.type = 'Ci::Build'
    AND ci_builds.status IN ('success', 'failed', 'canceled')
    AND ci_builds.finished_at < '%s'
    AND ci_job_artifacts.job_id IS NULL
SQL
STATUS_CREATED =
"created".freeze
STATUS_PENDING =
"pending".freeze
DEFAULT_UNARCHIVED_TRACES_OFFSET_MINUTES =
1440

Instance Method Summary collapse

Methods inherited from Base

connection_pool, #connection_pool, #with_connection_pool

Constructor Details

#initialize(opts) ⇒ CiBuildsCollector

Returns a new instance of CiBuildsCollector.


256
257
258
259
260
261
262
# File 'lib/gitlab_monitor/database/ci_builds.rb', line 256

def initialize(opts)
  super(opts)

  @allowed_repeated_commands_count = opts[:allowed_repeated_commands_count]
  @created_builds_counting_disabled = opts[:created_builds_counting_disabled]
  @unarchived_traces_offset_minutes = opts[:unarchived_traces_offset_minutes]
end

Instance Method Details

#runObject


264
265
266
267
268
269
270
271
272
273
# File 'lib/gitlab_monitor/database/ci_builds.rb', line 264

def run
  results = {}
  results[:created_builds] = builds(STATUS_CREATED) unless @created_builds_counting_disabled
  results[:pending_builds] = builds(STATUS_PENDING)
  results[:stale_builds] = stale_builds
  results[:per_runner] = per_runner_builds
  results[:repeated_commands] = repeated_commands
  results[:unarchived_traces] = unarchived_traces
  results
end