Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add check for kyoto tycoon #426

Merged
merged 5 commits into from
Mar 27, 2013
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions checks.d/kyototycoon.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import re
import urllib2
from collections import defaultdict

from checks import AgentCheck

db_stats = re.compile(r'^db_(\d)+$')
whitespace = re.compile(r'\s')

class KyotoTycoonCheck(AgentCheck):
"""Report statistics about the Kyoto Tycoon DBM-style
database server (http://fallabs.com/kyototycoon/)
"""

GAUGES = {
'serv_conn_count': 'connections',
'serv_thread_count': 'threads',
'cnt_get': 'ops.get.hits',
'cnt_get_misses': 'ops.get.misses',
'cnt_set': 'ops.set.hits',
'cnt_set_misses': 'ops.set.misses',
'cnt_remove': 'ops.del.hits',
'cnt_remove_misses': 'ops.del.misses',
'repl_delay': 'replication.delay',
}
DB_GAUGES = {
'count': 'records',
'size': 'size',
}
TOTALS = {
'cnt_get': 'ops.get.total',
'cnt_get_misses': 'ops.get.total',
'cnt_set': 'ops.set.total',
'cnt_set_misses': 'ops.set.total',
'cnt_remove': 'ops.get.total',
'cnt_remove_misses': 'ops.get.total',
}

def check(self, instance):
url = instance.get('report_url')
if not url:
self.log.exception('Invalid Kyoto Tycoon report url %r', url)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should let these "expected" exceptions bubble up. They'll be caught by the agent and will display in the "datadog-agent info" command (I'll add this to the docs today). Same with the couldn't connect exceptions, etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Meaning I should remove the try/except at lines 53-58, and not check report_url here? huh, good to know.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, You can still check it if you want to raise a more informative message, just raise Exception("invalid url ...") instead of continuing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Neat. Updated.

return

tags = instance.get('tags', {})
name = instance.get('name')

# generate the formatted list of tags
tags = ['%s:%s' % (k, v) for k, v in tags.items()]
if name is not None:
tags.append('instance:%s' % name)

try:
response = urllib2.urlopen(url)
body = response.read()
except:
self.log.exception('Could not connect to Kyoto Tycoon at %r', url)
return

totals = defaultdict(lambda: 0)
for line in body.split('\n'):
if '\t' not in line:
continue

key, value = line.strip().split('\t', 1)
if key in self.GAUGES:
name = self.GAUGES[key]
self.gauge('kyototycoon.%s' % name, float(value), tags=tags)

elif db_stats.match(key):
# Also produce a per-db metrics tagged with the db
# number in addition to the default tags
m = db_stats.match(key)
dbnum = int(m.group(1))
mytags = tags + ['db:%d' % dbnum]
for part in whitespace.split(value):
k, v = part.split('=', 1)
if k in self.DB_GAUGES:
name = self.DB_GAUGES[k]
self.gauge('kyototycoon.%s' % name, float(v), tags=mytags)

if key in self.TOTALS:
totals[self.TOTALS[key]] += float(value)

for key, value in totals.items():
self.gauge('kyototycoon.%s' % key, value, tags=tags)

if __name__ == '__main__':
check, instances = KyotoTycoonCheck.from_yaml('kyototycoon.yaml')
for instance in instances:
check.check(instance)
if check.has_events():
print 'Events: %s' % (check.get_events())
print 'Metrics: %s'
import pprint
pprint.pprint(check.get_metrics())