Skip to content

Instantly share code, notes, and snippets.

@werkshy
Last active August 3, 2021 21:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save werkshy/fd5c68d8f428ab9067c2 to your computer and use it in GitHub Desktop.
Save werkshy/fd5c68d8f428ab9067c2 to your computer and use it in GitHub Desktop.
Python class for interacting with the statsd admin interface. List stats, counters, timers, and gauges. Delete counters, timers, and gauges.
import socket
import simplejson as json
# Copyright (c) EnergyHub, Inc 2013
# Released under MIT license.
class StatsdAdminClient(object):
"""
A client for statsd admin interface.
Example commands: stats, counters, timers, gauges, delcounters, deltimers, delgauges, quit
Usage:
statsd_admin = StatsdAdminClient('mystatshost')
gauges = statsd_admin.list('gauges')
for gauge, value in gauges.items():
print "%s = %r" % (gauge, value)
statsd_admin.del_gauges(['foo.bar.baz', 'foo.bar.qux'])
"""
def __init__(self, host='localhost', port=8126):
"""Create a new client."""
self.rbufsize = -1
self._addr = (socket.gethostbyname(host), port)
def list(self, stat_type='stats'):
"""
Returns a dictionary of stat:value pairs for all stats that statsd
is tracking.
stat_type could be one of: stats, counters, timers, gauges
"""
sock = socket.socket(socket.AF_INET)
sock.connect(self._addr)
sock.send(stat_type + "\n")
# Open a file-like object for this socket and read it to 'txt'
rfile = sock.makefile('r', self.rbufsize)
txt = ""
for line in rfile:
if line == "END\n":
break
if line:
txt += line.replace("'", "\"")
sock.close()
if txt[0] == '{':
data = json.loads(txt)
else:
data = {}
for line in txt.split("\n"):
if ":" in line:
key, val = line.split(":")
key = key.strip()
val = val.strip()
data[key] = val # Not converting to numbers
return data
def del_gauges(self, gauges):
"""
Delete the given gauges from statsd.
gauges is a list of gauge keys.
If statsd receives more data for a deleted gauge, it will be recreated.
"""
sock = socket.socket(socket.AF_INET)
sock.connect(self._addr)
msg = "delgauges " + " ".join(gauges)
sock.send(msg + "\n")
sock.close()
def del_timers(self, timers):
"""
Delete the given timers from statsd.
If statsd receives more data for a deleted timer, it will be recreated.
"""
sock = socket.socket(socket.AF_INET)
sock.connect(self._addr)
msg = "deltimers " + " ".join(timers)
sock.send(msg + "\n")
sock.close()
def del_counters(self, counters):
"""
Delete the given counters from statsd.
If statsd receives more data for a deleted counter, it will be recreated.
"""
sock = socket.socket(socket.AF_INET)
sock.connect(self._addr)
msg = "delcounters " + " ".join(counters)
sock.send(msg + "\n")
sock.close()
@rarawls
Copy link

rarawls commented Aug 3, 2021

I have a need to programmatically interact with Graphite/Statsd with python. I have a lot working, but I am unable to delete stats. After using this as a starting point, I found that I could delete everything I wanted in Statsd, but when viewing Graphite they are still there! Thinking there is something else in the back-end that needs to happen. I'd really appreciate if you have any ideas. Thanks!

@werkshy
Copy link
Author

werkshy commented Aug 3, 2021

I think that makes sense, graphite has its own storage layer, each statsd metric becomes a whisper file on disk. I haven't used statsd or graphite in a very long time, but a) I recall having to delete whisper files and b) this SO answer suggests that statsd could be writing 'idle' stats and you can turn that off? Best of luck!

@rarawls
Copy link

rarawls commented Aug 3, 2021

Bummer. That's what I found in my research too. I was hoping you may have some additional insight since you've developed against it. Thanks for the help and reply!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment