UNPKG

2.33 kBMarkdownView Raw
1# Pickling for Graphite
2
3The graphite statsd backend can optionally be configured to use pickle
4for its over-the-wire protocol.
5
6```javascript
7 { graphiteHost: "your.graphite.host",
8 graphiteProtocol: "pickle" }
9```
10
11The default is to use the graphite text protocol, which can require
12more CPU processing by the graphite endpoint.
13
14The message format expected by the graphite pickle endpoint consists
15of a header and payload.
16
17## The Payload
18
19The message payload is a list of tuples. Each tuple contains the measurement
20for a single metric name. The measurement is encoded as a second,
21nested tuple containing timestamp and measured value.
22
23This ends up looking like:
24
25```python
26[ ( "path.to.metric.name", ( timestamp, "value" ) ),
27 ( "path.to.another.name", ( timestamp, "value" ) ) ]
28```
29
30The graphite receiver `carbon.protocols.MetricPickleReceiver` coerces
31both the timestamp and measured value into `float`.
32
33The timestamp must be seconds since epoch encoded as a number.
34
35The measured value is encoded as a string. This may change in the
36future.
37
38We have chosen to not implement pickle's object memoization. This
39simplifies what is sent across the wire. It is not likely any
40optimization would result within a single poll cycle.
41
42Here is some Python code showing how a given set of metrics can be
43serialized in a more simple way.
44
45```python
46import pickle
47
48metrics = [ ( "a.b.c", ( 1234L, "5678" ) ), ( "d.e.f.g", ( 1234L, "9012" ) ) ]
49pickle.dumps(metrics)
50# "(lp0\n(S'a.b.c'\np1\n(L1234L\nS'5678'\np2\ntp3\ntp4\na(S'd.e.f.g'\np5\n(L1234L\nS'9012'\np6\ntp7\ntp8\na."
51
52payload = "(l(S'a.b.c'\n(L1234L\nS'5678'\ntta(S'd.e.f.g'\n(L1234L\nS'9012'\ntta."
53pickle.loads(payload)
54# [('a.b.c', (1234L, '5678')), ('d.e.f.g', (1234L, '9012'))]
55```
56
57The trailing `L` for long fields is unnecessary, but we are adding the
58character to match Python pickle output. It's a side-effect of
59`repr(long(1234))`.
60
61## The Header
62
63The message header is a 32-bit integer sent over the wire as
64four-bytes. This integer must describe the length of the pickled
65payload.
66
67Here is some sample code showing how to construct the message header
68containing the payload length.
69
70```python
71import struct
72
73payload_length = 81
74header = struct.pack("!L", payload_length)
75# '\x00\x00\x00Q'
76```
77
78The `Q` character is equivalent to `\x81` (ASCII encoding).