Skip to content

Commit

Permalink
Tokyo Tyrant Data Source 1.0
Browse files Browse the repository at this point in the history
git-svn-id: http://zenpacks.zenoss.org/svn/zenpacks@877 db08cffe-75b9-45d1-af1a-46ad9ef135f6
  • Loading branch information
Matt Ray committed Aug 4, 2010
0 parents commit d1aad5c
Show file tree
Hide file tree
Showing 18 changed files with 568 additions and 0 deletions.
16 changes: 16 additions & 0 deletions COPYRIGHT.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
All files in this directory and below are:

Copyright (c) 2010 Zenoss, Inc. All rights reserved.

This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 as published
by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
graft ZenPacks
1 change: 1 addition & 0 deletions ZenPacks/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__import__('pkg_resources').declare_namespace(__name__)
8 changes: 8 additions & 0 deletions ZenPacks/community/TokyoTyrant/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

import Globals
import os.path

skinsDir = os.path.join(os.path.dirname(__file__), 'skins')
from Products.CMFCore.DirectoryView import registerDirectory
if os.path.isdir(skinsDir):
registerDirectory(skinsDir, globals())
111 changes: 111 additions & 0 deletions ZenPacks/community/TokyoTyrant/datasources/TTyrantDataSource.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
__doc__='''
TTyrantDatasource.py
This datasource is part of the Zenpacks.community.TokyoTyrant Zenpack
by B Maqueira / http://codelab.ferrarihaines.com
It defines the datasource TokyoTyrantStats
'''
from Globals import InitializeClass
import Products.ZenModel.BasicDataSource as BasicDataSource
from Products.ZenModel.ZenPackPersistence import ZenPackPersistence
from AccessControl import ClassSecurityInfo, Permissions
from Products.ZenUtils.ZenTales import talesCompile, getEngine
from Products.ZenUtils.Utils import binPath

class TTyrantDataSource(ZenPackPersistence, BasicDataSource.BasicDataSource):

ZENPACKID = 'ZenPacks.community.TokyoTyrant'
TOKYO_TYRANT_STATS = 'TokyoTyrantStats'

sourcetypes = (TOKYO_TYRANT_STATS,)
sourcetype = TOKYO_TYRANT_STATS

timeout = 3
eventClass = '/Status/TokyoTyrant'
component = 'TokyoTyrant'
hostname = '${dev/id}'
ipAddress = '${dev/manageIp}'
port = 1978

_properties = BasicDataSource.BasicDataSource._properties + (
{'id':'hostname', 'type':'string', 'mode':'w'},
{'id':'ipAddress', 'type':'string', 'mode':'w'},
{'id':'port', 'type':'int', 'mode':'w'},
{'id':'timeout', 'type':'int', 'mode':'w'},
)

_relations = BasicDataSource.BasicDataSource._relations + ()


factory_type_information = (
{
'immediate_view' : 'editTTDataSource',
'actions' :
(
{ 'id' : 'edit',
'name' : 'Data Source',
'action' : 'editTTDataSource',
'permissions' : ( Permissions.view, ),
},
)
},
)

security = ClassSecurityInfo()

def __init__(self, id, title=None, buildRelations=True):
BasicDataSource.BasicDataSource.__init__(self, id, title, buildRelations)


def getDescription(self):
if self.sourcetype == self.TOKYO_TYRANT_STATS:
return self.hostname
return BasicDataSource.BasicDataSource.getDescription(self)


def useZenCommand(self):
return True

def getCommand(self, context):
parts = ['check_ttserver.py']
if self.hostname:
parts.append('-H %s' % self.hostname)
if self.port:
parts.append('-p %s' % self.port)
if self.timeout:
parts.append("-t %s" % self.timeout)
cmd = ' '.join(parts)
cmd = BasicDataSource.BasicDataSource.getCommand(self, context, cmd)
return cmd

def checkCommandPrefix(self, context, cmd):
zp = self.getZenPack(context)
return zp.path('libexec', cmd)

def addDataPoints(self):
# create gauges
for stat in [ 'hit_percent', 'get_set_ratio', 'missed_percent',
'pointer_size', 'rusage_user',
'rusage_system', 'cmd_set', 'cmd_set_hits',
'cmd_set_misses', 'cmd_delete', 'cmd_delete_hits',
'cmd_delete_misses', 'cmd_get', 'cmd_get_hits',
'cmd_get_misses', 'cmd_flush', 'curr_items',
'total_items', 'bytes', 'threads']:
if not self.datapoints._getOb(stat, None):
self.manage_addRRDDataPoint(stat)

def zmanage_editProperties(self, REQUEST=None):
'''validation, etc'''
if REQUEST:
self.addDataPoints()
if not REQUEST.form.get('eventClass', None):
REQUEST.form['eventClass'] = self.__class__.eventClass

if not REQUEST.form.get('component', None):
REQUEST.form['component'] = self.__class__.component

return BasicDataSource.BasicDataSource.zmanage_editProperties(self,
REQUEST)

InitializeClass(TTyrantDataSource)
2 changes: 2 additions & 0 deletions ZenPacks/community/TokyoTyrant/datasources/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# __init__.py

91 changes: 91 additions & 0 deletions ZenPacks/community/TokyoTyrant/lib/TTServer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
"""
TTServer.py
This library is part of the Zenpacks.community.TokyoTyrant zenpack by
B Maqueira. It provides "ttyrant" & "ttyrantStats" classes to access
ttyrant statistics. It also provides utility classes to handle
custom error exceptions.
"""
import sys
import telnetlib

class Error(Exception):
""" Base Class for my exceptions """
def __init__(self, value):
self.msg = value

def __str__(self):
return repr(self.msg)

pass

class ConnectionError(Error):
def __init__(self, msg):
self.msg = msg

class ttyrant(object):
""" Class to connect to ttyrant """
def __init__(self, host='localhost', port=1978, timeout=3):
self.host = host
self.port = port
self.timeout = float(timeout)
self.tn = telnetlib.Telnet()
self.getStats()

def getStats(self):
try:
self.tn.open(self.host, self.port)
self.tn.read_until('Escape character is \'^]\'.', self.timeout)
self.tn.write("stats\n")

stats = self.tn.read_until('END', self.timeout)
self.tn.write('quit')
self.tn.close()
except Exception, e:
raise ConnectionError( "Operation failed during connection to %s: %s" % (self.host, e) )
return
self.stats = self.parseStats(stats)
self.tn.close()

def parseStats(self, stats):
return ttyrantStats(stats)

def get(self, statsKey):
if not statsKey == None:
return self.stats.get(statsKey)
else:
return None

class ttyrantStats(object):
""" build some ttyrant stats """
def __init__(self, statsStack):
self.stats = {'hit_percent':0, 'get_set_ratio':0, 'missed_percent':0}
for statline in statsStack.split("\n"):
st = statline.split(' ')
if len(st) > 1:
try:
self.stats[st[1]] = float(st[2])
except:
self.stats[st[1]] = st[2]

if self.stats.has_key('cmd_get_hits')\
and self.stats.has_key('cmd_get')\
and self.stats['cmd_get'] > 0:
self.stats['hit_percent'] = 100 * self.stats['cmd_get_hits'] / self.stats['cmd_get']

if self.stats.has_key('cmd_set')\
and self.stats.has_key('cmd_get')\
and self.stats['cmd_set'] > 0:
self.stats['get_set_ratio'] = self.stats['cmd_get'] / self.stats['cmd_set']

if self.stats.has_key('cmd_get_misses')\
and self.stats.has_key('cmd_get')\
and self.stats['cmd_get'] > 0:
self.stats['missed_percent'] = 100 * self.stats['cmd_get_misses'] / self.stats['cmd_get']

def get(self, statKey):
if self.stats.has_key(statKey):
return self.stats[statKey]
else:
return None

1 change: 1 addition & 0 deletions ZenPacks/community/TokyoTyrant/lib/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# __init__.py
50 changes: 50 additions & 0 deletions ZenPacks/community/TokyoTyrant/libexec/check_ttserver.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/usr/bin/env python
"""
check_ttserver.py
This script connects to ttserver instances and retrieves and parses
the stats output
"""
import sys
from optparse import OptionParser
import Globals
from ZenPacks.community.TokyoTyrant.lib.TTServer import ttyrant

#import os
#sys.path.append( os.path.dirname(os.path.realpath(__file__)) + '/../lib')
#from TTServer import ttyrant

if __name__ == "__main__":
parser = OptionParser()
parser.add_option('-H', '--host', dest='host', default='localhost',
help='Hostname of ttserver server')
parser.add_option('-p', '--port', dest='port', default=1978,
help='Port of ttserver server')
parser.add_option('-t', '--timeout', dest='timeout', default=3,
help="connection time out")
options, args = parser.parse_args()

if not options.host:
print "You must specify the host parameter."
sys.exit(1)

try:
ttStats = ttyrant(options.host, options.port, options.timeout)
except Exception, e:
print "CMD FAIL| %s" % e
sys.exit(1)

cmdOutPut = "CMD OK|"
for stat in [ 'get_set_ratio', 'hit_percent', 'missed_percent', 'pid', 'uptime',
'time', 'version', 'pointer_size', 'rusage_user',
'rusage_system', 'cmd_set', 'cmd_set_hits',
'cmd_set_misses', 'cmd_delete', 'cmd_delete_hits',
'cmd_delete_misses', 'cmd_get', 'cmd_get_hits',
'cmd_get_misses', 'cmd_flush', 'curr_items',
'total_items', 'bytes', 'threads'
]:
cmdOutPut += "%s=%s " % (stat, ttStats.get(stat))

print cmdOutPut
1 change: 1 addition & 0 deletions ZenPacks/community/TokyoTyrant/migrate/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# __init__.py
Empty file.
Empty file.
6 changes: 6 additions & 0 deletions ZenPacks/community/TokyoTyrant/objects/objects.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0"?>
<objects>
<!-- ('', 'zport', 'dmd', 'Events', 'Status', 'TokyoTyrant') -->
<object id='/zport/dmd/Events/Status/TokyoTyrant' module='Products.ZenEvents.EventClass' class='EventClass'>
</object>
</objects>
Loading

0 comments on commit d1aad5c

Please sign in to comment.