Welcome to mirror list, hosted at ThFree Co, Russian Federation.

logger.rb « pipeline « ci « gitlab « lib - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 97f7dddd09a08d70484678650fd2e6ff43265d20 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# frozen_string_literal: true

module Gitlab
  module Ci
    module Pipeline
      class Logger
        include ::Gitlab::Utils::StrongMemoize

        def self.current_monotonic_time
          ::Gitlab::Metrics::System.monotonic_time
        end

        def initialize(project:, destination: Gitlab::AppJsonLogger)
          @started_at = current_monotonic_time
          @project = project
          @destination = destination
          @log_conditions = []

          yield(self) if block_given?
        end

        def log_when(&block)
          log_conditions.push(block)
        end

        def instrument(operation)
          return yield unless enabled?

          raise ArgumentError, 'block not given' unless block_given?

          op_started_at = current_monotonic_time

          result = yield

          observe("#{operation}_duration_s", current_monotonic_time - op_started_at)

          result
        end

        def observe(operation, value)
          return unless enabled?

          observations[operation.to_s].push(value)
        end

        def commit(pipeline:, caller:)
          return unless log?

          attributes = {
            class: self.class.name.to_s,
            pipeline_creation_caller: caller,
            project_id: project.id,
            pipeline_id: pipeline.id,
            pipeline_persisted: pipeline.persisted?,
            pipeline_source: pipeline.source,
            pipeline_creation_service_duration_s: age
          }.stringify_keys.merge(observations_hash)

          destination.info(attributes)
        end

        def observations_hash
          observations.transform_values do |values|
            next if values.empty?

            {
              'count' => values.size,
              'min' => values.min,
              'max' => values.max,
              'avg' => values.sum / values.size
            }
          end.compact
        end

        private

        attr_reader :project, :destination, :started_at, :log_conditions
        delegate :current_monotonic_time, to: :class

        def age
          current_monotonic_time - started_at
        end

        def log?
          return false unless enabled?
          return true if log_conditions.empty?

          log_conditions.any? { |cond| cond.call(observations) }
        end

        def enabled?
          strong_memoize(:enabled) do
            ::Feature.enabled?(:ci_pipeline_creation_logger, project, type: :ops, default_enabled: :yaml)
          end
        end

        def observations
          @observations ||= Hash.new { |hash, key| hash[key] = [] }
        end
      end
    end
  end
end