wingo - in flumotion/trunk: . bin conf/rrdmon flumotion/admin flumotion/admin/rrdmon

flumotion-commit at lists.fluendo.com flumotion-commit at lists.fluendo.com
Wed Jun 27 18:59:12 CEST 2007


Author: wingo
Date: Wed Jun 27 18:59:06 2007
New Revision: 5273

Added:
   flumotion/trunk/bin/flumotion-rrdmon.in
   flumotion/trunk/conf/rrdmon/
   flumotion/trunk/conf/rrdmon/default.xml
   flumotion/trunk/flumotion/admin/rrdmon/
   flumotion/trunk/flumotion/admin/rrdmon/Makefile.am
   flumotion/trunk/flumotion/admin/rrdmon/__init__.py
   flumotion/trunk/flumotion/admin/rrdmon/config.py
   flumotion/trunk/flumotion/admin/rrdmon/main.py
   flumotion/trunk/flumotion/admin/rrdmon/rrdmon.py
Modified:
   flumotion/trunk/ChangeLog
   flumotion/trunk/bin/Makefile.am
   flumotion/trunk/configure.ac
   flumotion/trunk/flumotion/admin/Makefile.am
Log:
2007-06-27  Andy Wingo  <wingo at pobox.com>

	* configure.ac: 
	* conf/rrdmon/default.xml: 
	* bin/Makefile.am (bin_SCRIPTS): 
	* bin/flumotion-rrdmon.in: 
	* flumotion/admin/Makefile.am: 
	* flumotion/admin/rrdmon/config.py: 
	* flumotion/admin/rrdmon/main.py: 
	* flumotion/admin/rrdmon/Makefile.am: 
	* flumotion/admin/rrdmon/rrdmon.py: 
	* flumotion/admin/rrdmon/__init__.py: Add scaffolding for a daemon
	that can monitor components' UIState keys, logging them to an RRD
	file.



Modified: flumotion/trunk/ChangeLog
==============================================================================
--- flumotion/trunk/ChangeLog	(original)
+++ flumotion/trunk/ChangeLog	Wed Jun 27 18:59:06 2007
@@ -1,5 +1,18 @@
 2007-06-27  Andy Wingo  <wingo at pobox.com>
 
+	* configure.ac: 
+	* conf/rrdmon/default.xml: 
+	* bin/Makefile.am (bin_SCRIPTS): 
+	* bin/flumotion-rrdmon.in: 
+	* flumotion/admin/Makefile.am: 
+	* flumotion/admin/rrdmon/config.py: 
+	* flumotion/admin/rrdmon/main.py: 
+	* flumotion/admin/rrdmon/Makefile.am: 
+	* flumotion/admin/rrdmon/rrdmon.py: 
+	* flumotion/admin/rrdmon/__init__.py: Add scaffolding for a daemon
+	that can monitor components' UIState keys, logging them to an RRD
+	file.
+
 	* flumotion/admin/multi.py (MultiAdminModel.removeListener): New
 	method.
 	(MultiAdminModel._managerConnected)

Modified: flumotion/trunk/bin/Makefile.am
==============================================================================
--- flumotion/trunk/bin/Makefile.am	(original)
+++ flumotion/trunk/bin/Makefile.am	Wed Jun 27 18:59:06 2007
@@ -6,6 +6,7 @@
 	flumotion-job \
 	flumotion-launch \
 	flumotion-manager \
+	flumotion-rrdmon \
 	flumotion-tester \
 	flumotion-worker
 

Added: flumotion/trunk/bin/flumotion-rrdmon.in
==============================================================================
--- (empty file)
+++ flumotion/trunk/bin/flumotion-rrdmon.in	Wed Jun 27 18:59:06 2007
@@ -0,0 +1,45 @@
+#!/usr/bin/python
+# -*- Mode: Python -*-
+# vi:si:et:sw=4:sts=4:ts=4
+#
+# Flumotion - a streaming media server
+# Copyright (C) 2007 Fluendo, S.L. (www.fluendo.com).
+# All rights reserved.
+
+# This file may be distributed and/or modified under the terms of
+# the GNU General Public License version 2 as published by
+# the Free Software Foundation.
+# This file is distributed without any warranty; without even the implied
+# warranty of merchantability or fitness for a particular purpose.
+# See "LICENSE.GPL" in the source distribution for more information.
+
+# Licensees having purchased or holding a valid Flumotion Advanced
+# Streaming Server license may use this file in accordance with the
+# Flumotion Advanced Streaming Server Commercial License Agreement.
+# See "LICENSE.Flumotion" in the source distribution for more information.
+
+# Headers in this file shall remain intact.
+
+
+import os
+import sys
+
+# Variable templates 
+LIBDIR = '@LIBDIR@'
+PROGRAM_PATH = 'flumotion.admin.rrdmon.main.main'
+
+try:
+    # setup the project root
+    dir = os.path.dirname(os.path.abspath(__file__))
+    if os.path.exists(os.path.join(dir, '..', 'flumotion', '.svn')):
+        root = os.path.split(dir)[0]
+    else:
+        root = os.path.join(LIBDIR, 'flumotion', 'python')
+    sys.path.insert(0, root)
+
+    # and boot!
+    from flumotion.common import boot
+    boot.boot(PROGRAM_PATH, gst=False)
+
+except KeyboardInterrupt:
+    print 'Interrupted'

Added: flumotion/trunk/conf/rrdmon/default.xml
==============================================================================
--- (empty file)
+++ flumotion/trunk/conf/rrdmon/default.xml	Wed Jun 27 18:59:06 2007
@@ -0,0 +1,14 @@
+<rrdmon>
+ <source name="http-streamer">
+  <manager>user:test at localhost:7531</manager>
+  <ui-state-key>stream-totalbytes</ui-state-key>
+  <is-gauge>False</is-gauge>
+  <sample-frequency>300</sample-frequency>
+  <archive>
+   <!-- This should be nicer in the future, but the meaning of this is that we
+        sample every 1*stepsize=1*300s=5 minutes, for 1200 samples = 5
+        min*1200=100h.-->
+   <rra-spec>AVERAGE:0.5:1:1200</rra-spec>
+  </archive>
+ </source>
+</rrdmon>

Modified: flumotion/trunk/configure.ac
==============================================================================
--- flumotion/trunk/configure.ac	(original)
+++ flumotion/trunk/configure.ac	Wed Jun 27 18:59:06 2007
@@ -145,6 +145,7 @@
 AC_CONFIG_FILES([bin/flumotion-job], [chmod +x bin/flumotion-job])
 AC_CONFIG_FILES([bin/flumotion-launch], [chmod +x bin/flumotion-launch])
 AC_CONFIG_FILES([bin/flumotion-manager], [chmod +x bin/flumotion-manager])
+AC_CONFIG_FILES([bin/flumotion-rrdmon], [chmod +x bin/flumotion-rrdmon])
 AC_CONFIG_FILES([bin/flumotion-tester], [chmod +x bin/flumotion-tester])
 AC_CONFIG_FILES([bin/flumotion-worker], [chmod +x bin/flumotion-worker])
 AC_CONFIG_FILES([bin/runtest], [chmod +x bin/runtest])
@@ -165,6 +166,7 @@
 flumotion/admin/Makefile
 flumotion/admin/command/Makefile
 flumotion/admin/gtk/Makefile
+flumotion/admin/rrdmon/Makefile
 flumotion/admin/text/Makefile
 flumotion/common/Makefile
 flumotion/component/Makefile

Modified: flumotion/trunk/flumotion/admin/Makefile.am
==============================================================================
--- flumotion/trunk/flumotion/admin/Makefile.am	(original)
+++ flumotion/trunk/flumotion/admin/Makefile.am	Wed Jun 27 18:59:06 2007
@@ -7,7 +7,7 @@
 	connections.py \
 	multi.py
 
-SUBDIRS = command gtk text
+SUBDIRS = command gtk rrdmon text
 
 TAGS_FILES = $(component_PYTHON)
 

Added: flumotion/trunk/flumotion/admin/rrdmon/Makefile.am
==============================================================================
--- (empty file)
+++ flumotion/trunk/flumotion/admin/rrdmon/Makefile.am	Wed Jun 27 18:59:06 2007
@@ -0,0 +1,14 @@
+include $(top_srcdir)/common/python.mk
+
+componentdir = $(libdir)/flumotion/python/flumotion/admin/rrdmon
+component_PYTHON = \
+	__init__.py \
+	config.py \
+	main.py \
+	rrdmon.py
+
+TAGS_FILES = $(component_PYTHON)
+
+clean-local:
+	rm -rf *.pyc *.pyo
+

Added: flumotion/trunk/flumotion/admin/rrdmon/__init__.py
==============================================================================
--- (empty file)
+++ flumotion/trunk/flumotion/admin/rrdmon/__init__.py	Wed Jun 27 18:59:06 2007
@@ -0,0 +1,23 @@
+# -*- Mode: Python -*-
+# vi:si:et:sw=4:sts=4:ts=4
+#
+# Flumotion - a streaming media server
+# Copyright (C) 2007 Fluendo, S.L. (www.fluendo.com).
+# All rights reserved.
+
+# This file may be distributed and/or modified under the terms of
+# the GNU General Public License version 2 as published by
+# the Free Software Foundation.
+# This file is distributed without any warranty; without even the implied
+# warranty of merchantability or fitness for a particular purpose.
+# See "LICENSE.GPL" in the source distribution for more information.
+
+# Licensees having purchased or holding a valid Flumotion Advanced
+# Streaming Server license may use this file in accordance with the
+# Flumotion Advanced Streaming Server Commercial License Agreement.
+# See "LICENSE.Flumotion" in the source distribution for more information.
+
+# Headers in this file shall remain intact.
+
+"""
+"""

Added: flumotion/trunk/flumotion/admin/rrdmon/config.py
==============================================================================
--- (empty file)
+++ flumotion/trunk/flumotion/admin/rrdmon/config.py	Wed Jun 27 18:59:06 2007
@@ -0,0 +1,148 @@
+# -*- Mode: Python -*-
+# vi:si:et:sw=4:sts=4:ts=4
+#
+# Flumotion - a streaming media server
+# Copyright (C) 2004,2005,2006,2007 Fluendo, S.L. (www.fluendo.com).
+# All rights reserved.
+
+# This file may be distributed and/or modified under the terms of
+# the GNU General Public License version 2 as published by
+# the Free Software Foundation.
+# This file is distributed without any warranty; without even the implied
+# warranty of merchantability or fitness for a particular purpose.
+# See "LICENSE.GPL" in the source distribution for more information.
+
+# Licensees having purchased or holding a valid Flumotion Advanced
+# Streaming Server license may use this file in accordance with the
+# Flumotion Advanced Streaming Server Commercial License Agreement.
+# See "LICENSE.Flumotion" in the source distribution for more information.
+
+# Headers in this file shall remain intact.
+
+import os
+
+from xml.dom import Node
+
+from flumotion.configure import configure
+from flumotion.common import common, config, connection
+from flumotion.common.errors import ConfigError
+
+
+class ConfigParser(config.BaseConfigParser):
+    """
+    RRD monitor configuration file parser.
+
+    Create a parser via passing the name of the file to parse to
+    __init__. Parse into a dict of properly-typed options by calling
+    parse() on the parser.
+    """
+    logCategory = 'rrdmon-config'
+
+    def __init__(self, file, rrdBaseDir=None):
+        """
+        @param file: The path to the config file to parse, or a file object
+        @type  file: str or file
+        @param rrdBaseDir: The base directory for resolving filenames, or None to
+                        infer from the path passed
+        @type rrdBaseDir: str or None
+        """
+        if rrdBaseDir is not None:
+            self.rrdBaseDir = rrdBaseDir
+        else:
+            self.rrdBaseDir = os.path.dirname(file)
+        config.BaseConfigParser.__init__(self, file)
+
+    def _parseArchive(self, node):
+        def strparser(parser):
+            def parsestr(node):
+                return self.parseTextNode(node, parser)
+            return parsestr
+        def ressetter(k):
+            def setter(v):
+                res[k] = v
+            return setter
+
+        res = {}
+        table = {}
+        basicOptions = (('rra-spec', True, str, None),)
+        for k, required, parser, default in basicOptions:
+            table[k] = strparser(parser), ressetter(k)
+            if not required:
+                res[k] = default
+
+        self.parseFromTable(node, table)
+
+        for k, required, parser, default in basicOptions:
+            if required and k not in res:
+                raise config.ConfigError('missing required node %s' % k)
+        return res
+
+    def _parseSource(self, node):
+        def strparser(parser):
+            def parsestr(node):
+                return self.parseTextNode(node, parser)
+            return parsestr
+        def ressetter(k):
+            def setter(v):
+                res[k] = v
+            return setter
+
+        name, = self.parseAttributes(node, ('name',))
+
+        res = {'name': name}
+        table = {}
+
+        basicOptions = (('manager', True,
+                         connection.parsePBConnectionInfo, None),
+                        ('ui-state-key', True, str, None),
+                        ('sample-frequency', False, float, 300),
+                        ('is-gauge', False, common.strToBool, True),
+                        ('rrd-ds-spec', False, str, None),
+                        ('rrd-file', False, str, None))
+        for k, required, parser, default in basicOptions:
+            table[k] = strparser(parser), ressetter(k)
+            if not required:
+                res[k] = default
+
+        res['archives'] = []
+        table['archive'] = (self._parseArchive, res['archives'].append)
+
+        self.parseFromTable(node, table)
+
+        for k, required, parser, default in basicOptions:
+            if required and k not in res:
+                raise config.ConfigError('missing required node %s' % k)
+        if not res['archives']:
+            raise config.ConfigError('must specify at least one '
+                                     '<archive> per <source>')
+            
+        return res
+
+    def parse(self):
+        # <rrdmon>
+        #   <propName>propValue</propName>
+        root = self.doc.documentElement
+        if not root.nodeName == 'rrdmon':
+            raise ConfigError("unexpected root node: %s" % root.nodeName)
+        
+        def strparser(parser):
+            def parsestr(node):
+                return self.parseTextNode(node, parser)
+            return parsestr
+        def ressetter(k):
+            def setter(v):
+                res[k] = v
+            return setter
+
+        res = {'debug': None,
+               'sources': []}
+        table = {'debug': (strparser(str), ressetter('debug')),
+                 'source': (self._parseSource, res['sources'].append)}
+
+        self.parseFromTable(root, table)
+
+        if not res['sources']:
+            raise config.ConfigError('must specify at least one '
+                                     '<source>')
+
+        return res

Added: flumotion/trunk/flumotion/admin/rrdmon/main.py
==============================================================================
--- (empty file)
+++ flumotion/trunk/flumotion/admin/rrdmon/main.py	Wed Jun 27 18:59:06 2007
@@ -0,0 +1,144 @@
+# -*- Mode: Python -*-
+# vi:si:et:sw=4:sts=4:ts=4
+#
+# Flumotion - a streaming media server
+# Copyright (C) 2004,2005,2006,2007 Fluendo, S.L. (www.fluendo.com).
+# All rights reserved.
+
+# This file may be distributed and/or modified under the terms of
+# the GNU General Public License version 2 as published by
+# the Free Software Foundation.
+# This file is distributed without any warranty; without even the implied
+# warranty of merchantability or fitness for a particular purpose.
+# See "LICENSE.GPL" in the source distribution for more information.
+
+# Licensees having purchased or holding a valid Flumotion Advanced
+# Streaming Server license may use this file in accordance with the
+# Flumotion Advanced Streaming Server Commercial License Agreement.
+# See "LICENSE.Flumotion" in the source distribution for more information.
+
+# Headers in this file shall remain intact.
+
+import optparse
+import os
+import sys
+
+from twisted.internet import reactor
+
+from flumotion.configure import configure
+from flumotion.common import log, keycards, common, errors
+from flumotion.common import connection
+from flumotion.admin.rrdmon import rrdmon, config
+from flumotion.twisted import pb
+
+# more standard helper functions necessary...
+def _createParser():
+    parser = optparse.OptionParser()
+    parser.add_option('-d', '--debug',
+                      action="store", type="string", dest="debug",
+                      help="set debug levels")
+    parser.add_option('-v', '--verbose',
+                      action="store_true", dest="verbose",
+                      help="be verbose")
+    parser.add_option('', '--version',
+                      action="store_true", dest="version",
+                      help="show version information")
+
+    group = optparse.OptionGroup(parser, "rrdmon options")
+    group.add_option('-s', '--service-name',
+                     action="store", type="string", dest="serviceName",
+                     help="name to use for log and pid files "
+                          "when run as a daemon")
+    group.add_option('-D', '--daemonize',
+                     action="store_true", dest="daemonize",
+                     help="run in background as a daemon")
+    group.add_option('', '--daemonize-to',
+                     action="store", dest="daemonizeTo",
+                     help="what directory to run from when daemonizing")
+
+    parser.add_option('-L', '--logdir',
+                      action="store", dest="logdir",
+                      help="flumotion log directory (default: %s)" %
+                        configure.logdir)
+    parser.add_option('-R', '--rundir',
+                      action="store", dest="rundir",
+                      help="flumotion run directory (default: %s)" %
+                        configure.rundir)
+    parser.add_option_group(group)
+
+    return parser
+
+def _readConfig(confXml, options):
+    # modifies options dict in-place
+    log.info('rrdmon', 'Reading configuration from %s' % confXml)
+    cfg = config.ConfigParser(confXml).parse()
+    # command-line debug > environment debug > config file debug
+    if not options.debug and cfg['debug'] \
+        and not os.environ.has_key('FLU_DEBUG'):
+        options.debug = cfg['debug']
+    return cfg
+    
+def main(args):
+    parser = _createParser()
+    log.debug('rrdmon', 'Parsing arguments (%r)' % ', '.join(args))
+    options, args = parser.parse_args(args)
+
+    # Force options down configure's throat
+    for d in ['logdir', 'rundir']:
+        o = getattr(options, d, None)
+        if o:
+            log.debug('rrdmon', 'Setting configure.%s to %s' % (d, o))
+            setattr(configure, d, o)
+
+    # handle all options
+    if options.version:
+        print common.version("flumotion-rrdmon")
+        return 0
+
+    if options.verbose:
+        log.setFluDebug("*:3")
+ 
+    # apply the command-line debug level if is given through --verbose or -d
+    if options.debug:
+        log.setFluDebug(options.debug)
+
+    # check if a config file was specified; if so, parse config and copy over
+    if len(args) != 2:
+        raise SystemExit('usage: flumotion-rrdtool [OPTIONS] CONFIG-FILE')
+
+    confXml = args[1]
+    cfg = _readConfig(confXml, options)
+
+    # reset FLU_DEBUG which could be different after parsing XML file
+    if options.debug:
+        log.setFluDebug(options.debug)
+
+    if options.daemonizeTo and not options.daemonize:
+        sys.stderr.write(
+            'ERROR: --daemonize-to can only be used with -D/--daemonize.\n')
+        return 1
+
+    if options.serviceName and not options.daemonize:
+        sys.stderr.write(
+            'ERROR: --service-name can only be used with -D/--daemonize.\n')
+        return 1
+
+    monitor = rrdmon.RRDMonitor(cfg['sources'])
+
+    name = 'rrdmon'
+    if options.daemonize:
+        if options.serviceName:
+            name = options.serviceName
+
+    common.startup("rrdmon", name, options.daemonize, options.daemonizeTo)
+
+    log.debug('rrdmon', 'Running Flumotion version %s' %
+        configure.version)
+    import twisted.copyright
+    log.debug('rrdmon', 'Running against Twisted version %s' %
+        twisted.copyright.version)
+
+    # go into the reactor main loop
+    reactor.run()
+
+    return 0

Added: flumotion/trunk/flumotion/admin/rrdmon/rrdmon.py
==============================================================================
--- (empty file)
+++ flumotion/trunk/flumotion/admin/rrdmon/rrdmon.py	Wed Jun 27 18:59:06 2007
@@ -0,0 +1,33 @@
+# -*- Mode: Python -*-
+# vi:si:et:sw=4:sts=4:ts=4
+#
+# Flumotion - a streaming media server
+# Copyright (C) 2004,2005,2006,2007 Fluendo, S.L. (www.fluendo.com).
+# All rights reserved.
+
+# This file may be distributed and/or modified under the terms of
+# the GNU General Public License version 2 as published by
+# the Free Software Foundation.
+# This file is distributed without any warranty; without even the implied
+# warranty of merchantability or fitness for a particular purpose.
+# See "LICENSE.GPL" in the source distribution for more information.
+
+# Licensees having purchased or holding a valid Flumotion Advanced
+# Streaming Server license may use this file in accordance with the
+# Flumotion Advanced Streaming Server Commercial License Agreement.
+# See "LICENSE.Flumotion" in the source distribution for more information.
+
+# Headers in this file shall remain intact.
+
+
+from flumotion.common import log
+
+
+class RRDMonitor(log.Loggable):
+    logName = 'rrdmon'
+
+    def __init__(self, sources):
+        self.debug('started rrd monitor')
+        self.sources = sources
+        # There is a bit of a TODO here :)
+        


More information about the flumotion-commit mailing list