Module: RRDNotifier::RubyParser

Defined in:
lib/rrd-grapher/notifier/parsers/ruby_parser.rb

Constant Summary collapse

HOST =

part type

0x0000
TIME =
0x0001
PLUGIN =
0x0002
PLUGIN_INSTANCE =
0x0003
TYPE =
0x0004
TYPE_INSTANCE =
0x0005
VALUES =
0x0006
INTERVAL =
0x0007
MESSAGE =
0x0100
SEVERITY =
0x0101
PART_TYPE_AS_STRING =
{
  HOST            => 'host',
  TIME            => 'time',
  PLUGIN          => 'plugin',
  PLUGIN_INSTANCE => 'plugin_instance',
  TYPE            => 'type',
  TYPE_INSTANCE   => 'type_instance',
  VALUES          => 'values',
  INTERVAL        => 'interval',
  MESSAGE         => 'message',
  SEVERITY        => 'severity'
}.freeze
STR_FIELDS =
[HOST, PLUGIN, PLUGIN_INSTANCE, TYPE, TYPE_INSTANCE, MESSAGE]
INT_FIELDS =
[TIME, INTERVAL, SEVERITY]
COUNTER =
0x00
GAUGE =
0x01
DERIVE =
0x02
ABSOLUTE =
0x03
INT64_MAX =
(1 << 63)
INT64_SIGN_BIT =
(1 << 64)
COPY_FIELDS =
[
  :time,
  :host,
  :plugin,
  :plugin_instance,
  :type,
  :type_instance,
  :interval
].freeze

Class Method Summary collapse

Class Method Details

.parse(buffer) ⇒ Object



116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/rrd-grapher/notifier/parsers/ruby_parser.rb', line 116

def self.parse(buffer)
  packets = []
  last_packet = {}
  
  # 4 = part header size
  while buffer.bytesize >= 4
    packet, buffer = parse_packet(buffer, last_packet)
    packets << packet
    
    last_packet = packet if packet.data?
  end
  
  packets
end

.parse_int64(buffer, signed = false) ⇒ Object

uint to int “val = val - #<< nbits if (val >= #<< (nbits - 1))”



50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/rrd-grapher/notifier/parsers/ruby_parser.rb', line 50

def self.parse_int64(buffer, signed = false)
  # [v>>32, v & 0xffffffff].pack("NN")}.join
  
  hi, lo, buffer = buffer.unpack("NNa*")
  n = (hi << 32 | lo)
  
  if signed && (n >= INT64_MAX)
    n = n - INT64_SIGN_BIT
  end
  
  [n, buffer]
end

.parse_packet(buffer, initial_values = {}) ⇒ Object



105
106
107
108
109
110
111
112
113
114
# File 'lib/rrd-grapher/notifier/parsers/ruby_parser.rb', line 105

def self.parse_packet(buffer, initial_values = {})
  packet = Packet.new(initial_values, COPY_FIELDS)
  
  begin
    type, value, buffer = parse_part(buffer)
    packet.send("#{type}=", value)
  end until packet.message || packet.values
  
  [packet, buffer]
end

.parse_part(buffer) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/rrd-grapher/notifier/parsers/ruby_parser.rb', line 63

def self.parse_part(buffer)
  type, length, buffer = parse_part_header(buffer)
  case
  when INT_FIELDS.include?(type)  then  val, buffer = parse_int64(buffer)        
  when STR_FIELDS.include?(type)  then  val, buffer = buffer.unpack("Z#{length}a*")
  when type == VALUES             then  val, buffer = parse_part_values(length, buffer)
  end
        
  [
    PART_TYPE_AS_STRING[type],
    val,
    buffer
  ]
end

.parse_part_header(buffer) ⇒ Object



40
41
42
43
# File 'lib/rrd-grapher/notifier/parsers/ruby_parser.rb', line 40

def self.parse_part_header(buffer)
  type, length, rest = buffer.unpack('nna*')
  [type, length - 4, rest]
end

.parse_part_values(length, buffer) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/rrd-grapher/notifier/parsers/ruby_parser.rb', line 78

def self.parse_part_values(length, buffer)
  # first we need to read the types of all the values
  values_count, buffer = buffer.unpack("na*")
  *types, buffer = buffer.unpack("C#{values_count}a*")
  values = types.map! do |type|
    case type
    when COUNTER, ABSOLUTE  then  val, buffer = parse_int64(buffer)
    when GAUGE              then  val, buffer = buffer.unpack("Ea*")
    when DERIVE             then  val, buffer = parse_int64(buffer, true)
    end
    
    val
  end
  
  [values, buffer]
end