Permalink
Browse files

Ganglia Monitor 1.0

git-svn-id: http://zenpacks.zenoss.org/svn/zenpacks@558 db08cffe-75b9-45d1-af1a-46ad9ef135f6
  • Loading branch information...
0 parents commit 4971ebbe9958ba5002c48890b38781629b73636c Matt Ray committed Mar 6, 2010
@@ -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.
@@ -0,0 +1 @@
+graft ZenPacks
@@ -0,0 +1 @@
+__import__('pkg_resources').declare_namespace(__name__)
@@ -0,0 +1,26 @@
+###########################################################################
+#
+# Copyright (C) 2008, Zenoss Inc.
+#
+# 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.
+#
+# For complete information please visit: http://www.zenoss.com/oss/
+#
+###########################################################################
+
+import Globals
+from Products.ZenModel.ZenPack import ZenPackBase
+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())
+
+class ZenPack(ZenPackBase):
+ packZProperties = [
+ ('zGangliaHost', '', 'string'),
+ ('zGangliaPort', 8649, 'int'),
+ ]
@@ -0,0 +1,109 @@
+###########################################################################
+#
+# Copyright (C) 2010, Zenoss Inc.
+#
+# 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.
+#
+# For complete information please visit: http://www.zenoss.com/oss/
+#
+###########################################################################
+
+__doc__='''GangliaMonitorDataSource.py
+
+Defines datasource for GangliaMonitor
+'''
+
+import Products.ZenModel.BasicDataSource as BasicDataSource
+from Products.ZenModel.ZenPackPersistence import ZenPackPersistence
+from AccessControl import ClassSecurityInfo, Permissions
+from Products.ZenUtils.ZenTales import talesCompile, getEngine
+
+import os
+
+class GangliaMonitorDataSource(ZenPackPersistence,
+ BasicDataSource.BasicDataSource):
+ GANGLIA_MONITOR = 'GangliaMonitor'
+ ZENPACKID = 'ZenPacks.jschroeder.GangliaMonitor'
+
+ sourcetypes = (GANGLIA_MONITOR,)
+ sourcetype = GANGLIA_MONITOR
+
+ timeout = 60
+ eventClass = '/Status/Ganglia'
+ host = '${dev/zGangliaHost}'
+ port = '${dev/zGangliaPort}'
+
+ _properties = BasicDataSource.BasicDataSource._properties + (
+ {'id':'timeout', 'type':'int', 'mode':'w'},
+ {'id':'eventClass', 'type':'string', 'mode':'w'},
+ {'id':'host', 'type':'string', 'mode':'w'},
+ {'id':'port', 'type':'string', 'mode':'w'},
+ )
+
+ _relations = BasicDataSource.BasicDataSource._relations + (
+ )
+
+ factory_type_information = (
+ {
+ 'immediate_view': 'editGangliaMonitorDataSource',
+ 'actions':
+ (
+ { 'id': 'edit',
+ 'name': 'Data Source',
+ 'action': 'editGangliaMonitorDataSource',
+ '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.GANGLIA_MONITOR:
+ return self.hostname
+ return BasicDataSource.BasicDataSource.getDescription(self)
+
+
+ def useZenCommand(self):
+ return True
+
+
+ def getCommand(self, context):
+ parts = ['check_ganglia.py', self.host, self.port, '${dev/manageIp}', str(self.cycletime)]
+ 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):
+ for dpname in ('bytes_in', 'bytes_out', 'cpu_idle', 'cpu_nice',
+ 'cpu_system', 'cpu_user', 'cpu_wio', 'disk_free',
+ 'disk_total', 'lastUpdate', 'load_fifteen', 'load_five',
+ 'load_one', 'mem_buffers', 'mem_cached', 'mem_free',
+ 'mem_shared', 'mem_total', 'pkts_in', 'pkts_out',
+ 'proc_run', 'proc_total', 'swap_free', 'swap_total'):
+ dp = self.manage_addRRDDataPoint(dpname)
+ dp.rrdtype = 'GAUGE'
+ dp.rrdmin = 0
+
+ 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
+ return BasicDataSource.BasicDataSource.zmanage_editProperties(self,
+ REQUEST)
+
@@ -0,0 +1,104 @@
+#!/usr/bin/env python
+###########################################################################
+#
+# Copyright (C) 2010, Zenoss Inc.
+#
+# 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.
+#
+# For complete information please visit: http://www.zenoss.com/oss/
+#
+###########################################################################
+
+import os
+import socket
+import sys
+import time
+import xml.dom.minidom
+
+# Get our options
+try:
+ ghost = socket.gethostbyname(sys.argv[1])
+ gport = int(sys.argv[2])
+ devip = sys.argv[3]
+ cache = int(sys.argv[4])
+except:
+ sys.stderr.write("Usage: %s <ganglia_host> <ganglia_port> <cluster_host>\n" % os.path.basename(sys.argv[0]))
+ sys.exit(1)
+
+# Setup some global stuff
+TEMPDIR = "/tmp"
+TEMPDIR = os.path.join(TEMPDIR, "gangliadata")
+CACHEFILE = os.path.join(TEMPDIR, "%s:%d.cache" % (ghost, gport))
+
+# Make sure we have the tempdir
+if not os.path.isdir(TEMPDIR):
+ os.mkdir(TEMPDIR)
+
+# If we have no cache or the cache is stale, repopulate
+curtime = time.time()
+if not os.path.exists(CACHEFILE) or curtime - os.path.getmtime(CACHEFILE) > cache:
+ tmpfile = CACHEFILE + ".%d" % os.getpid()
+
+ # Connect to socket and save data to tempfile
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ try:
+ s.connect((ghost, gport))
+ xmldata = ""
+ while True:
+ chunk = s.recv(1024)
+ if not chunk: break
+ xmldata += chunk
+ s.close()
+ except:
+ s.close()
+ print "Unable to connect to ganglia server!"
+ sys.exit(1)
+
+ try:
+ dom = xml.dom.minidom.parseString(xmldata)
+ except:
+ print "Ganglia server returned malformed XML!"
+ sys.exit(1)
+
+ # Save our cache
+ f = open(tmpfile, "w")
+ for cluster in dom.getElementsByTagName("GANGLIA_XML")[0].getElementsByTagName("CLUSTER"):
+ data = {}
+ for host in cluster.getElementsByTagName("HOST"):
+ data = {}
+ for metric in host.getElementsByTagName("METRIC"):
+ data[metric.getAttribute("NAME")] = metric.getAttribute("VAL")
+ data["lastUpdate"] = str(int(curtime) - int(host.getAttribute("REPORTED")))
+ f.write("%s\t%s\n" % (host.getAttribute("IP"), " ".join(["%s=%s" % (k, v) for k,v in data.items()])))
+ f.close()
+
+ # Try to rename the data into place
+ for i in range(10): # Handle up to 10 errors, then fail
+ if os.path.exists(CACHEFILE):
+ try:
+ os.remove(CACHEFILE)
+ except OSError:
+ pass
+ try:
+ os.rename(tmpfile, CACHEFILE)
+ break
+ except OSError:
+ pass
+ if os.path.exists(tmpfile):
+ os.remove(tmpfile)
+
+# Check to make sure we have cache and it is updated
+if not os.path.exists(CACHEFILE):
+ print "Unable to find ganglia cache!"
+ sys.exit(1)
+if curtime - os.path.getmtime(CACHEFILE) > cache:
+ print "Unable to update stale ganglia cache!"
+ sys.exit(1)
+
+# OK, now we actually try to read the data from the cache
+for line in open(CACHEFILE):
+ if line.startswith(devip + "\t"):
+ print "OK|" + line.split("\t", 1)[1]
+ break
Oops, something went wrong.

0 comments on commit 4971ebb

Please sign in to comment.