# Copyright © 2009 Adrian Perez <aperez@igalia.com>
#
# Distributed under terms of the GPLv2 license.
+#
+# Frank Marien (frank@apsu.be) 4 Sep 2012
+# - quick fixes for 5.1 binary protocol
+# - updated for python 3
+# - fixed for larger packet sizes (possible on lo interface)
"""
Collectd network protocol implementation.
import socket
import struct
-
try:
- from cStringIO import StringIO
+ from io import StringIO
except ImportError:
- from StringIO import StringIO
+ from cStringIO import StringIO
from datetime import datetime
from copy import deepcopy
# Message kinds
TYPE_HOST = 0x0000
TYPE_TIME = 0x0001
+TYPE_TIME_HR = 0x0008
TYPE_PLUGIN = 0x0002
TYPE_PLUGIN_INSTANCE = 0x0003
TYPE_TYPE = 0x0004
TYPE_TYPE_INSTANCE = 0x0005
TYPE_VALUES = 0x0006
TYPE_INTERVAL = 0x0007
+TYPE_INTERVAL_HR = 0x0009
# For notifications
TYPE_MESSAGE = 0x0100
# DS kinds
DS_TYPE_COUNTER = 0
DS_TYPE_GAUGE = 1
+DS_TYPE_DERIVE = 2
+DS_TYPE_ABSOLUTE = 3
header = struct.Struct("!2H")
assert double.size == number.size
result = []
- for dstype in map(ord, buf[header.size+short.size:off]):
+ for dstype in buf[header.size+short.size:off]:
if dstype == DS_TYPE_COUNTER:
result.append((dstype, number.unpack_from(buf, off)[0]))
off += valskip
elif dstype == DS_TYPE_GAUGE:
result.append((dstype, double.unpack_from(buf, off)[0]))
off += valskip
+ elif dstype == DS_TYPE_DERIVE:
+ result.append((dstype, number.unpack_from(buf, off)[0]))
+ off += valskip
+ elif dstype == DS_TYPE_ABSOLUTE:
+ result.append((dstype, number.unpack_from(buf, off)[0]))
+ off += valskip
else:
raise ValueError("DS type %i unsupported" % dstype)
_decoders = {
TYPE_VALUES : decode_network_values,
TYPE_TIME : decode_network_number,
+ TYPE_TIME_HR : decode_network_number,
TYPE_INTERVAL : decode_network_number,
+ TYPE_INTERVAL_HR : decode_network_number,
TYPE_HOST : decode_network_string,
TYPE_PLUGIN : decode_network_string,
TYPE_PLUGIN_INSTANCE: decode_network_string,
"""
off = 0
blen = len(buf)
+
while off < blen:
ptype, plen = header.unpack_from(buf, off)
off += plen
-
-
-
class Data(object):
time = 0
host = None
typeinstance = None
def __init__(self, **kw):
- [setattr(self, k, v) for k, v in kw.iteritems()]
+ [setattr(self, k, v) for k, v in kw.items()]
@property
def datetime(self):
def source(self):
buf = StringIO()
if self.host:
- buf.write(self.host)
+ buf.write(str(self.host))
if self.plugin:
buf.write("/")
- buf.write(self.plugin)
+ buf.write(str(self.plugin))
if self.plugininstance:
buf.write("/")
- buf.write(self.plugininstance)
+ buf.write(str(self.plugininstance))
if self.type:
buf.write("/")
- buf.write(self.type)
+ buf.write(str(self.type))
if self.typeinstance:
buf.write("/")
- buf.write(self.typeinstance)
+ buf.write(str(self.typeinstance))
return buf.getvalue()
def __str__(self):
for kind, data in iterable:
if kind == TYPE_TIME:
vl.time = nt.time = data
+ elif kind == TYPE_TIME_HR:
+ vl.time = nt.time = data
elif kind == TYPE_INTERVAL:
vl.interval = data
+ elif kind == TYPE_INTERVAL_HR:
+ vl.interval = data
elif kind == TYPE_HOST:
vl.host = nt.host = data
elif kind == TYPE_PLUGIN:
host = None
port = DEFAULT_PORT
- BUFFER_SIZE = 1024
+ BUFFER_SIZE = 16384
def __init__(self, host=None, port=DEFAULT_PORT, multicast=False):
"""
if iterable is None:
iterable = self.decode()
- if isinstance(iterable, basestring):
+ if isinstance(iterable, str):
iterable = self.decode(iterable)
return interpret_opcodes(iterable)
-
-