Module: FFWD::Plugin::Collectd::Parser
- Includes:
- Logging
- Defined in:
- lib/ffwd/plugin/collectd/parser.rb
Overview
An parser implementation of collectd.org/wiki/index.php/Binary_protocol
Constant Summary collapse
- HOST =
0x0000
- TIME =
0x0001
- TIME_HR =
0x0008
- PLUGIN =
0x0002
- PLUGIN_INSTANCE =
0x0003
- TYPE =
0x0004
- TYPE_INSTANCE =
0x0005
- VALUES =
0x0006
- INTERVAL =
0x0007
- INTERVAL_HR =
0x0009
- MESSAGE =
0x0100
- SEVERITY =
0x0101
- COUNTER =
0
- GAUGE =
1
- DERIVE =
2
- ABSOLUTE =
3
- SB64 =
0x8000000000000000
- B64 =
0x10000000000000000
- FACTOR_HR =
2**30
Class Method Summary collapse
- .interval_high_res(frame, i, size) ⇒ Object
- .numeric(frame, i, size) ⇒ Object
-
.parse(frame) ⇒ Object
Maintain a current frame, and yield a copy of it to the subscribing block.
- .signed_integer(data) ⇒ Object
- .string(frame, i, size) ⇒ Object
- .time_high_res(frame, i, size) ⇒ Object
- .unsigned_integer(data) ⇒ Object
- .values(frame, i, size) ⇒ Object
Class Method Details
.interval_high_res(frame, i, size) ⇒ Object
104 105 106 |
# File 'lib/ffwd/plugin/collectd/parser.rb', line 104 def self.interval_high_res frame, i, size numeric(frame, i, size).to_f / FACTOR_HR end |
.numeric(frame, i, size) ⇒ Object
96 97 98 |
# File 'lib/ffwd/plugin/collectd/parser.rb', line 96 def self.numeric frame, i, size unsigned_integer frame[4 + i, 8] end |
.parse(frame) ⇒ Object
Maintain a current frame, and yield a copy of it to the subscribing block.
Reading a ‘values’ part is the indicator that a block is ‘ready’.
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/ffwd/plugin/collectd/parser.rb', line 112 def self.parse frame raise "invalid frame" if frame.size < 4 current = {} i = 0 loop do break if i >= frame.size type, size = frame[i,4].unpack("nn") case type when HOST current[:host] = self.string(frame, i, size) when TIME current[:time] = Time.at(self.numeric(frame, i, size)) when TIME_HR current[:time] = self.time_high_res(frame, i, size) when PLUGIN current[:plugin] = self.string(frame, i, size) when PLUGIN_INSTANCE current[:plugin_instance] = self.string(frame, i, size) when TYPE current[:type] = self.string(frame, i, size) when TYPE_INSTANCE current[:type_instance] = self.string(frame, i, size) when VALUES values = self.values(frame, i, size) current[:values] = values yield current when INTERVAL current[:interval] = self.numeric(frame, i, size).to_f when INTERVAL_HR current[:interval] = self.interval_high_res(frame, i, size) when MESSAGE current[:message] = self.string(frame, i, size) when SEVERITY current[:severity] = self.numeric(frame, i, size) else log.warning("cannot understand type: #{type}") end i += size end end |
.signed_integer(data) ⇒ Object
52 53 54 55 56 57 58 59 60 |
# File 'lib/ffwd/plugin/collectd/parser.rb', line 52 def self.signed_integer data us = unsigned_integer(data) if (us & SB64) == SB64 us - B64 else us end end |
.string(frame, i, size) ⇒ Object
92 93 94 |
# File 'lib/ffwd/plugin/collectd/parser.rb', line 92 def self.string frame, i, size frame[4 + i, (size - 5)] end |
.time_high_res(frame, i, size) ⇒ Object
100 101 102 |
# File 'lib/ffwd/plugin/collectd/parser.rb', line 100 def self.time_high_res frame, i, size Time.at(numeric(frame, i, size).to_f / FACTOR_HR) end |
.unsigned_integer(data) ⇒ Object
47 48 49 50 |
# File 'lib/ffwd/plugin/collectd/parser.rb', line 47 def self.unsigned_integer data high, low = data.unpack("NN") ((high << 32) | low) end |
.values(frame, i, size) ⇒ Object
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 |
# File 'lib/ffwd/plugin/collectd/parser.rb', line 62 def self.values frame, i, size n = frame[i + 4, 2].unpack("n")[0] result = [] types = frame[i + 6, n].unpack("C" * n) types.each_with_index do |type, j| o = 6 + n + (j * 8) data = frame[i + o, 8] case type when COUNTER result << [:counter, self.unsigned_integer(data)] when GAUGE result << [:gauge, data.unpack("E")[0]] when DERIVE result << [:derive, self.signed_integer(data)] when ABSOLUTE result << [:absolute, self.unsigned_integer(data)] else raise "unkonwn value type: #{type}" end j += 1 end result end |