Mini Shell
"""Functions for posting data to carbon"""
import socket
import time
import random
from typing import Optional, List
RELAY_PORTS = [2003, 2005, 2007, 2009]
def carbon_post(
data: List[str],
server: str = 'graphite.imhadmin.net',
port: Optional[int] = None,
chunk_size: int = 500,
chunk_sleep: float = 0.2,
max_tries: int = 3,
) -> bool:
"""Post all items in a list of strings to Carbon
Args:
data: lines to post, each formatted ``"bucket.name value timestamp"``
server: graphite server FQDN to post to
port: TCP port to post to; if unspecified, a random port
from ``mtrlib.carbon.RELAY_PORTS`` will be used
chunk_size: how many metrics to post in each HTTP POST request
chunk_sleep: how long in seconds to pause between HTTP POSTs
max_tries: how many times to retry on socket.error
Returns:
a bool of whether the posts succeeded
"""
if port is None:
port = random.choice(RELAY_PORTS)
if not isinstance(data, list):
raise ValueError('carbon_post data must be a list')
to_carbon = data[:] # create a new copy in memory
success = True
while to_carbon and success:
chunk = []
for _ in range(chunk_size):
try:
chunk.append(to_carbon.pop(0))
except IndexError:
continue
for attempt in range(max_tries): # attempt to post it 3 times
try:
sock = socket.socket()
sock.connect((server, port))
payload = '{0}\n'.format('\n'.join(chunk))
sock.sendall(bytes(payload, 'ascii', 'ignore'))
sock.close()
success = True
break # stop trying
except IOError:
success = False
if attempt < max_tries - 1:
time.sleep(chunk_sleep)
if to_carbon:
time.sleep(chunk_sleep)
return success
Zerion Mini Shell 1.0