Completed
Push — master ( 5cbcf8...d3d059 )
by Matthias
01:08
created

Encoder.format_measurement_name()   A

Complexity

Conditions 4

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 4
dl 0
loc 9
rs 9.2
c 1
b 0
f 1
1
# PyPy does not have ultrajson
2
# See https://github.com/esnme/ultrajson/issues/98
3
try:
4
    import ujson as json
5
except ImportError:
6
    import json
7
8
import logging
9
10
11
class Encoder(object):
12
    """
13
    An encoder for the Collectd JSON format
14
    See https://collectd.org/wiki/index.php/JSON
15
16
    Sample measurements:
17
18
    [{"values":[0],"dstypes":["derive"],"dsnames":["value"],"time":1436372292.412,"interval":10.000,"host":"26f2fc918f50","plugin":"cpu","plugin_instance":"1","type":"cpu","type_instance":"interrupt"}]
19
20
    [
21
       {
22
         "values":  [1901474177],
23
         "dstypes":  ["counter"],
24
         "dsnames":    ["value"],
25
         "time":      1280959128,
26
         "interval":          10,
27
         "host":            "leeloo.octo.it",
28
         "plugin":          "cpu",
29
         "plugin_instance": "0",
30
         "type":            "cpu",
31
         "type_instance":   "idle"
32
       }
33
    ]
34
    """
35
    def encode(self, msg):
36
        measurements = []
37
38
        for line in msg.decode().split("\n"):
39
            try:
40
                # Set flag for float precision to get the same
41
                # results for Python 2 and 3.
42
                json_object = self.parse_line(line)
43
            except ValueError as e:
44
                logging.debug("Error in encoder: %s", e)
45
                continue
46
            for entry in json_object:
47
                try:
48
                    # to set plugin, plugin_instance as the measurement name, just need pass ['plugin', 'plugin_instance']
49
                    measurement = Encoder.format_measurement_name(entry, ['plugin', 'plugin_instance', 'type'])
50
                    tags = Encoder.format_tags(entry, ['host', 'type_instance'])
51
                    value = Encoder.format_value(entry)
52
                    time = Encoder.format_time(entry)
53
                    measurements.append(Encoder.compose_data(measurement, tags, value, time))
54
                except Exception as e:
55
                    logging.debug("Error in input data: %s. Skipping.", e)
56
                    continue
57
        return measurements
58
59
    @staticmethod
60
    def parse_line(line):
61
        # return json.loads(line, {'precise_float': True})
62
        # for influxdb version > 0.9, timestamp is an integer
63
        return json.loads(line)
64
65
    # following methods are added to support customizing measurement name, tags much more flexible
66
    @staticmethod
67
    def compose_data(measurement, tags, value, time):
68
        data = "%s,%s value=%s %s" % (measurement, tags, value, time)
69
        return data
70
71
    @staticmethod
72
    def format_measurement_name(entry, args):
73
        name = []
74
        for arg in args:
75
            if arg in entry:
76
                # avoid to add extra _ if some entry value is None
77
                if entry[arg] != '':
78
                    name.append(entry[arg])
79
        return '_'.join(name)
80
81
    @staticmethod
82
    def format_tags(entry, args):
83
        tag = []
84
        for arg in args:
85
            if arg in entry:
86
                # to avoid add None as tag value
87
                if entry[arg] != '':
88
                    tag.append("%s=%s" % (arg, entry[arg]))
89
        return ','.join(tag)
90
91
    @staticmethod
92
    def format_time(entry):
93
        return int(float(entry['time']))
94
95
    @staticmethod
96
    def format_value(entry):
97
        values = entry['values']
98
        if len(values) == 1:
99
            return entry['values'][0]
100
        else:
101
            # support to add multiple values
102
            value = ' '.join(str(value) for value in values)
103
            return '"%s"' % value
104
105
106