Module: TingYun::Support::Coerce

Overview

We really don’t want to send bad values to the collector, and it doesn’t accept types like Rational that have occasionally slipped into our data.

These methods are intended to safely coerce things into the form we want, to provide documentation of expected types on to_collector_array methods, and to log failures if totally invalid data gets into outgoing data

Class Method Summary collapse

Class Method Details

.event_params(value, context = nil) ⇒ Object

Convert a hash into a format acceptable to be included with Transaction event data.

We accept a hash and will return a new hash where all of the keys have been converted to strings. As values we only allow Strings, Floats, Integers. Symbols are also allowed but are converted to strings. Any values of other type (e.g. Hash, Array, any other class) are discarded. Their keys are also removed from the results hash.



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/ting_yun/support/coerce.rb', line 61

def event_params(value, context=nil)
  unless value.is_a? Hash
    raise ArgumentError, "Expected Hash but got #{value.class}"
  end
  value.inject({}) do |memo, (key, val)|
    case val
      when String, Integer, TrueClass, FalseClass
        memo[key.to_s] = val
      when Float
        if val.finite?
          memo[key.to_s] = val
        else
          memo[key.to_s] = nil
        end
      when Symbol
        memo[key.to_s] = val.to_s
    end
    memo
  end
rescue => error
  log_failure(value.class, 'valid event params', context, error)
  {}
end

.float(value, context = nil) ⇒ Object



31
32
33
34
35
36
37
38
# File 'lib/ting_yun/support/coerce.rb', line 31

def float(value, context=nil)
  result = Float(value)
  raise "Value #{result.inspect} is not finite." unless result.finite?
  result
rescue => error
  log_failure(value, Float, context, error)
  0.0
end

.int(value, context = nil) ⇒ Object



16
17
18
19
20
21
# File 'lib/ting_yun/support/coerce.rb', line 16

def int(value, context=nil)
  Integer(value)
rescue => error
  log_failure(value, Integer, context, error)
  0
end

.int_or_nil(value, context = nil) ⇒ Object



23
24
25
26
27
28
29
# File 'lib/ting_yun/support/coerce.rb', line 23

def int_or_nil(value, context=nil)
  return nil if value.nil?
  Integer(value)
rescue => error
  log_failure(value, Integer, context, error)
  nil
end

.log_failure(value, type, context, error) ⇒ Object



85
86
87
88
89
# File 'lib/ting_yun/support/coerce.rb', line 85

def log_failure(value, type, context, error)
  msg = "Unable to convert '#{value}' to #{type}"
  msg += " in context '#{context}'" if context
  TingYun::Agent.logger.warn(msg, error)
end

.string(value, context = nil) ⇒ Object



40
41
42
43
44
45
46
# File 'lib/ting_yun/support/coerce.rb', line 40

def string(value, context=nil)
  return value if value.nil?
  String(value)
rescue => error
  log_failure(value.class, String, context, error)
  ""
end

.url_encode(s) ⇒ Object



48
49
50
51
52
# File 'lib/ting_yun/support/coerce.rb', line 48

def url_encode(s)
  s.to_s.b.gsub(/[^a-zA-Z0-9_\-.]/n) { |m|
    sprintf("%%%02X", m.unpack("C")[0])
  }
end