Class: Gitlab::Usage::MetricDefinition

Inherits:
Object
  • Object
show all
Defined in:
lib/gitlab/usage/metric_definition.rb

Constant Summary collapse

METRIC_SCHEMA_PATH =
Rails.root.join('config', 'metrics', 'schema', 'base.json')
AVAILABLE_STATUSES =
%w[active broken].to_set.freeze
VALID_SERVICE_PING_STATUSES =
%w[active broken].to_set.freeze
TIME_FRAME_SUFFIX =
{
  '7d' => '_weekly',
  '28d' => '_monthly',
  'all' => ''
}.freeze
InvalidError =
Class.new(RuntimeError)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path, opts = {}) ⇒ MetricDefinition

Returns a new instance of MetricDefinition.



19
20
21
22
# File 'lib/gitlab/usage/metric_definition.rb', line 19

def initialize(path, opts = {})
  @path = path
  @attributes = opts
end

Instance Attribute Details

#pathObject (readonly)

Returns the value of attribute path.



17
18
19
# File 'lib/gitlab/usage/metric_definition.rb', line 17

def path
  @path
end

Class Method Details

.allObject



163
164
165
# File 'lib/gitlab/usage/metric_definition.rb', line 163

def all
  @all ||= definitions.map { |_key_path, definition| definition }
end

.context_for(key_path) ⇒ Object



177
178
179
# File 'lib/gitlab/usage/metric_definition.rb', line 177

def context_for(key_path)
  definitions[key_path]&.to_context
end

.definition_schemaObject



194
195
196
# File 'lib/gitlab/usage/metric_definition.rb', line 194

def definition_schema
  @definition_schema ||= ::JSONSchemer.schema(METRIC_SCHEMA_PATH)
end

.definitionsObject



159
160
161
# File 'lib/gitlab/usage/metric_definition.rb', line 159

def definitions
  @definitions ||= load_all!
end

.dump_metrics_yaml(include_paths:) ⇒ Object



181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/gitlab/usage/metric_definition.rb', line 181

def dump_metrics_yaml(include_paths:)
  @metrics_yaml ||= {}
  @metrics_yaml[include_paths.to_s] ||= begin
    metrics = definitions.values.map do |definition|
      result = definition.to_h

      result[:file_path] = Pathname.new(definition.path).relative_path_from(Rails.root).to_s if include_paths
      result
    end
    metrics.map(&:deep_stringify_keys).to_yaml
  end
end

.not_removedObject



167
168
169
# File 'lib/gitlab/usage/metric_definition.rb', line 167

def not_removed
  all.select { |definition| definition.status != 'removed' }.index_by(&:key_path)
end

.pathsObject



155
156
157
# File 'lib/gitlab/usage/metric_definition.rb', line 155

def paths
  @paths ||= [Rails.root.join('config', 'metrics', '[^agg]*', '*.yml')]
end

.with_instrumentation_classObject



171
172
173
174
175
# File 'lib/gitlab/usage/metric_definition.rb', line 171

def with_instrumentation_class
  all.select do |definition|
    (definition.internal_events? || definition.instrumentation_class.present?) && definition.available?
  end
end

Instance Method Details

#active?Boolean

Returns:

  • (Boolean)


124
125
126
# File 'lib/gitlab/usage/metric_definition.rb', line 124

def active?
  status == 'active'
end

#available?Boolean

Returns:

  • (Boolean)


132
133
134
# File 'lib/gitlab/usage/metric_definition.rb', line 132

def available?
  AVAILABLE_STATUSES.include?(status)
end

#broken?Boolean

Returns:

  • (Boolean)


128
129
130
# File 'lib/gitlab/usage/metric_definition.rb', line 128

def broken?
  status == 'broken'
end

#data_categoryObject



140
141
142
# File 'lib/gitlab/usage/metric_definition.rb', line 140

def data_category
  @attributes[:data_category]
end

#data_sourceObject



144
145
146
# File 'lib/gitlab/usage/metric_definition.rb', line 144

def data_source
  @attributes[:data_source]
end

#event_selection_rulesObject



32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/gitlab/usage/metric_definition.rb', line 32

def event_selection_rules
  return [] unless @attributes[:events]

  @event_selection_rules ||= @attributes[:events].map do |event|
    EventSelectionRule.new(
      name: event[:name],
      time_framed: time_framed?,
      filter: event[:filter],
      unique_identifier_name: event[:unique]&.split('.')&.first&.to_sym,
      operator: event[:operator]
    )
  end
end

#eventsObject



28
29
30
# File 'lib/gitlab/usage/metric_definition.rb', line 28

def events
  events_from_new_structure || events_from_old_structure || {}
end

#has_json_schema?Boolean

Returns:

  • (Boolean)


95
96
97
# File 'lib/gitlab/usage/metric_definition.rb', line 95

def has_json_schema?
  @attributes[:value_type] == 'object' && @attributes[:value_json_schema].present?
end

#instrumentation_classObject



46
47
48
49
50
51
52
53
# File 'lib/gitlab/usage/metric_definition.rb', line 46

def instrumentation_class
  return @attributes[:instrumentation_class] if @attributes[:instrumentation_class]
  return unless internal_events?
  return "TotalSumMetric" if event_selection_rules.first&.sum?
  return "UniqueTotalsMetric" if event_selection_rules.first&.unique_total?

  events.each_value.first.nil? ? "TotalCountMetric" : "UniqueCountMetric"
end

#internal_events?Boolean

Returns:

  • (Boolean)


148
149
150
# File 'lib/gitlab/usage/metric_definition.rb', line 148

def internal_events?
  data_source == 'internal_events'
end

#json_schemaObject



83
84
85
86
87
# File 'lib/gitlab/usage/metric_definition.rb', line 83

def json_schema
  return unless has_json_schema?

  @json_schema ||= Gitlab::Json.parse(File.read(json_schema_path))
end

#json_schema_pathObject



89
90
91
92
93
# File 'lib/gitlab/usage/metric_definition.rb', line 89

def json_schema_path
  return '' unless has_json_schema?

  Rails.root.join(@attributes[:value_json_schema])
end

#keyObject Also known as: key_path



24
25
26
# File 'lib/gitlab/usage/metric_definition.rb', line 24

def key
  @attributes[:key_path]
end

#product_groupObject



112
113
114
# File 'lib/gitlab/usage/metric_definition.rb', line 112

def product_group
  @attributes[:product_group]
end

#raw_attributesObject

This method can be removed when the refactoring is complete. It is only here to limit access to @attributes in a gradual manner.



57
58
59
# File 'lib/gitlab/usage/metric_definition.rb', line 57

def raw_attributes
  @attributes
end

#statusObject



61
62
63
# File 'lib/gitlab/usage/metric_definition.rb', line 61

def status
  @attributes[:status]
end

#time_frameObject



116
117
118
# File 'lib/gitlab/usage/metric_definition.rb', line 116

def time_frame
  @attributes[:time_frame]
end

#time_framed?Boolean

Returns:

  • (Boolean)


120
121
122
# File 'lib/gitlab/usage/metric_definition.rb', line 120

def time_framed?
  %w[7d 28d].include?(time_frame)
end

#to_contextObject



73
74
75
76
77
# File 'lib/gitlab/usage/metric_definition.rb', line 73

def to_context
  return unless %w[redis redis_hll].include?(data_source)

  Gitlab::Tracking::ServicePingContext.new(data_source: data_source, event: events.each_key.first)
end

#to_hObject Also known as: to_dictionary



79
80
81
# File 'lib/gitlab/usage/metric_definition.rb', line 79

def to_h
  @attributes
end

#valid_service_ping_status?Boolean

Returns:

  • (Boolean)


136
137
138
# File 'lib/gitlab/usage/metric_definition.rb', line 136

def valid_service_ping_status?
  VALID_SERVICE_PING_STATUSES.include?(status)
end

#validation_errorsObject



99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/gitlab/usage/metric_definition.rb', line 99

def validation_errors
  self.class.definition_schema.validate(@attributes.deep_stringify_keys).map do |error|
    <<~ERROR_MSG
      --------------- VALIDATION ERROR ---------------
      Metric file: #{path}
      Error type: #{error['type']}
      Data: #{error['data']}
      Path: #{error['data_pointer']}
      Details: #{error['details'] || error['error']}
    ERROR_MSG
  end
end

#value_json_schemaObject



65
66
67
# File 'lib/gitlab/usage/metric_definition.rb', line 65

def value_json_schema
  @attributes[:value_json_schema]
end

#value_typeObject



69
70
71
# File 'lib/gitlab/usage/metric_definition.rb', line 69

def value_type
  @attributes[:value_type]
end