Class: Maze::Schemas::TraceValidator

Inherits:
Object
  • Object
show all
Defined in:
lib/maze/schemas/trace_validator.rb

Overview

Contains a set of pre-defined validations for ensuring traces are correct

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(body) ⇒ TraceValidator

Creates the validator

@param body [Hash] The body of the trace to validate


19
20
21
22
23
# File 'lib/maze/schemas/trace_validator.rb', line 19

def initialize(body)
  @body = body
  @success = nil
  @errors = []
end

Instance Attribute Details

#errorsObject (readonly)

Returns the value of attribute errors.



14
15
16
# File 'lib/maze/schemas/trace_validator.rb', line 14

def errors
  @errors
end

#successObject (readonly)

Whether the trace passed the validation, one of true, false, or nil (not run)

@returns [Boolean|nil] Whether the validation was successful


13
14
15
# File 'lib/maze/schemas/trace_validator.rb', line 13

def success
  @success
end

Instance Method Details

#element_a_greater_or_equal_element_b(path_a, path_b) ⇒ Object



88
89
90
91
92
93
94
95
# File 'lib/maze/schemas/trace_validator.rb', line 88

def element_a_greater_or_equal_element_b(path_a, path_b)
  element_a = Maze::Helper.read_key_path(@body, path_a)
  element_b = Maze::Helper.read_key_path(@body, path_b)
  unless element_a && element_b && element_a >= element_b
    @success = false
    @errors << "Element '#{path_a}':'#{element_a}' was expected to be greater than or equal to '#{path_b}':'#{element_b}'"
  end
end

#element_contains(path, key_value, value_type = nil, possible_values = nil) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/maze/schemas/trace_validator.rb', line 67

def element_contains(path, key_value, value_type=nil, possible_values=nil)
  container = Maze::Helper.read_key_path(@body, path)
  if container.nil? || !container.kind_of?(Array)
    @success = false
    @errors << "Element '#{path}' was expected to be an array, was '#{container}'"
    return
  end
  element = container.find { |value| value['key'].eql?(key_value) }
  unless element
    @success = false
    @errors << "Element '#{path}' did not contain a value with the key '#{key_value}'"
    return
  end
  if value_type && possible_values
    unless element['value'] && element['value'][value_type] && possible_values.include?(element['value'][value_type])
      @success = false
      @errors << "Element '#{path}':'#{element}' did not contain a value of '#{value_type}' from '#{possible_values}'"
    end
  end
end

#element_int_in_range(path, range) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/maze/schemas/trace_validator.rb', line 54

def element_int_in_range(path, range)
  element_value = Maze::Helper.read_key_path(@body, path)
  if element_value.nil? || !element_value.kind_of?(Integer)
    @success = false
    @errors << "Element '#{path}' was expected to be an integer, was '#{element_value}'"
    return
  end
  unless range.include?(element_value)
    @success = false
    @errors << "Element '#{path}':'#{element_value}' was expected to be in the range '#{range}'"
  end
end

#regex_comparison(path, regex) ⇒ Object



45
46
47
48
49
50
51
52
# File 'lib/maze/schemas/trace_validator.rb', line 45

def regex_comparison(path, regex)
  element_value = Maze::Helper.read_key_path(@body, path)
  expected = Regexp.new(regex)
  unless expected.match(element_value)
    @success = false
    @errors << "Element '#{path}' was expected to match the regex '#{regex}', but was '#{element_value}'"
  end
end

#validateObject

Runs the validation against the trace given



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/maze/schemas/trace_validator.rb', line 26

def validate
  @success = true
  # Shortcut the validation if the body is empty for initial P gathering reasons
  return if @body.keys.eql?(['resourceSpans']) && @body['resourceSpans'].empty?

  regex_comparison('resourceSpans.0.scopeSpans.0.spans.0.spanId', '^[A-Fa-f0-9]{16}$')
  regex_comparison('resourceSpans.0.scopeSpans.0.spans.0.traceId', '^[A-Fa-f0-9]{32}$')
  element_int_in_range('resourceSpans.0.scopeSpans.0.spans.0.kind', 0..5)
  regex_comparison('resourceSpans.0.scopeSpans.0.spans.0.startTimeUnixNano', '^[0-9]+$')
  regex_comparison('resourceSpans.0.scopeSpans.0.spans.0.endTimeUnixNano', '^[0-9]+$')
  element_contains('resourceSpans.0.resource.attributes', 'deployment.environment')
  element_contains('resourceSpans.0.resource.attributes', 'telemetry.sdk.name')
  element_contains('resourceSpans.0.resource.attributes', 'telemetry.sdk.version')
  element_a_greater_or_equal_element_b(
    'resourceSpans.0.scopeSpans.0.spans.0.endTimeUnixNano',
    'resourceSpans.0.scopeSpans.0.spans.0.startTimeUnixNano'
  )
end