[Checkins] SVN: zc.monitorlogstats/branches/dev/ Got the handler working.

Jim Fulton jim at zope.com
Fri Sep 5 18:32:18 EDT 2008


Log message for revision 90909:
  Got the handler working.
  

Changed:
  U   zc.monitorlogstats/branches/dev/buildout.cfg
  U   zc.monitorlogstats/branches/dev/setup.py
  A   zc.monitorlogstats/branches/dev/src/zc/monitorlogstats/
  A   zc.monitorlogstats/branches/dev/src/zc/monitorlogstats/README.txt
  A   zc.monitorlogstats/branches/dev/src/zc/monitorlogstats/__init__.py
  A   zc.monitorlogstats/branches/dev/src/zc/monitorlogstats/component.xml
  A   zc.monitorlogstats/branches/dev/src/zc/monitorlogstats/tests.py
  A   zc.monitorlogstats/branches/dev/src/zc/monitorlogstats/zconfig.py

-=-
Modified: zc.monitorlogstats/branches/dev/buildout.cfg
===================================================================
--- zc.monitorlogstats/branches/dev/buildout.cfg	2008-09-05 21:26:48 UTC (rev 90908)
+++ zc.monitorlogstats/branches/dev/buildout.cfg	2008-09-05 22:32:18 UTC (rev 90909)
@@ -4,7 +4,7 @@
 
 [test]
 recipe = zc.recipe.testrunner
-eggs = 
+eggs = zc.monitorlogstats [test]
 
 [py]
 recipe = zc.recipe.egg

Modified: zc.monitorlogstats/branches/dev/setup.py
===================================================================
--- zc.monitorlogstats/branches/dev/setup.py	2008-09-05 21:26:48 UTC (rev 90908)
+++ zc.monitorlogstats/branches/dev/setup.py	2008-09-05 22:32:18 UTC (rev 90909)
@@ -12,40 +12,37 @@
 #
 ##############################################################################
 
-name, version = '', '0'
+name, version = 'zc.monitorlogstats', '0'
 
-import os
-from setuptools import setup, find_packages
+import os, setuptools
 
-entry_points = """
-"""
-
 def read(rname):
     return open(os.path.join(os.path.dirname(__file__), *rname.split('/')
                              )).read()
 
-long_description = (
-        read('src/zc/?/README.txt')
-        + '\n' +
-        'Download\n'
-        '--------\n'
-        )
+entry_points = """
+"""
 
-setup(
+setuptools.setup(
     name = name,
     version = version,
     author = 'Jim Fulton',
     author_email = 'jim at zope.com',
     description = '',
-    long_description=long_description,
+    long_description = (
+        read('src/zc/%s/README.txt' % name.split('.')[-1])
+        + '\n' +
+        'Download\n'
+        '--------\n'
+        ),
     license = 'ZPL 2.1',
     
     include_package_data = True,
-    packages = find_packages('src'),
+    packages = setuptools.find_packages('src'),
     namespace_packages = ['zc'],
     package_dir = {'': 'src'},
     install_requires = ['setuptools'],
     zip_safe = False,
     entry_points=entry_points,
-    include_package_data = True,
+    extras_require = dict(test=['ZConfig'])
     )

Added: zc.monitorlogstats/branches/dev/src/zc/monitorlogstats/README.txt
===================================================================
--- zc.monitorlogstats/branches/dev/src/zc/monitorlogstats/README.txt	                        (rev 0)
+++ zc.monitorlogstats/branches/dev/src/zc/monitorlogstats/README.txt	2008-09-05 22:32:18 UTC (rev 90909)
@@ -0,0 +1,122 @@
+zc.z3monitor plugin and log handler for getting Log statistics
+==============================================================
+
+zc.monitorlogstats provides a zc.z3monitor plugin and log handler to
+track log statistics.  The idea is that you can conect to it to find
+out how many log entries of various types have been posted. If you
+sample it over time, youcan see how many entries are added.  In
+particular, if you get new warning, error, or critical entries,
+someone might want to look at the logs to find out what's going on.
+
+Counting Log Handler
+--------------------
+
+Let's start by looking at the log handler.  The factory
+zc.monitorlogstats.CountingHandler can be installed like any other
+handler.  It doesn't emit anything. It just counts.
+
+Let's create one to see how it works:
+
+    >>> import logging, zc.monitorlogstats
+    >>> handler = zc.monitorlogstats.CountingHandler()
+    >>> logging.getLogger().addHandler(handler)
+    >>> logging.getLogger().setLevel(logging.INFO)
+
+Now, let's log:
+
+    >>> for i in range(5):
+    ...     logging.getLogger('foo').critical('Yipes')
+
+    >>> for i in range(9):
+    ...     logging.getLogger('bar').error('oops')
+
+    >>> for i in range(12):
+    ...     logging.getLogger('baz').warn('hm')
+
+    >>> for i in range(21):
+    ...     logging.getLogger('foo').info('yawn')
+
+    >>> for i in range(99):
+    ...     logging.getLogger('xxx').log(5, 'yuck yuck')
+
+We can ask the handler for statistics:
+
+    >>> handler.start_time
+    datetime.datetime(2008, 9, 5, 21, 10, 14)
+
+    >>> for level, count, time, message in handler.statistics:
+    ...     print level, count, time
+    ...     print `message`
+    20 21 2008-09-05 21:11:01
+    'yawn'
+    30 12 2008-09-05 21:10:40
+    'hm'
+    40 9 2008-09-05 21:10:28
+    'oops'
+    50 5 2008-09-05 21:10:19
+    'Yipes'
+
+We can also ask it to clear it's statistics:
+
+    >>> handler.clear()
+    >>> for i in range(3):
+    ...     logging.getLogger('foo').critical('Eek')
+
+    >>> handler.start_time
+    datetime.datetime(2008, 9, 5, 21, 11, 2)
+
+    >>> for level, count, time, message in handler.statistics:
+    ...     print level, count, time
+    ...     print `message`
+    50 3 2008-09-05 21:11:05
+    'Eek'
+
+There's ZConfig support for defining counting handlers:
+
+    >>> import ZConfig, StringIO
+    >>> schema = ZConfig.loadSchemaFile(StringIO.StringIO("""
+    ... <schema>
+    ...  <import package="ZConfig.components.logger"/>
+    ...  <multisection type="logger" attribute="loggers" name="*" required="no">
+    ...  </multisection>
+    ... </schema>
+    ... """))
+
+    >>> conf, _ = ZConfig.loadConfigFile(schema, StringIO.StringIO("""
+    ... %import zc.monitorlogstats
+    ... <logger>
+    ...     name test
+    ...     level INFO
+    ...     <counter>
+    ...     </counter>
+    ... </logger>
+    ... """))
+
+    >>> testhandler = conf.loggers[0]().handlers[0]
+
+    >>> for i in range(2):
+    ...     logging.getLogger('test').critical('Waaa')
+
+    >>> for level, count, time, message in handler.statistics:
+    ...     print level, count, time
+    ...     print `message`
+    50 5 2008-09-05 21:11:10
+    'Waaa'
+
+
+    >>> for level, count, time, message in testhandler.statistics:
+    ...     print level, count, time
+    ...     print `message`
+    50 2 2008-09-05 21:11:09
+    'Waaa'
+
+The example above illustrates that you can install as many counting
+handlers as you want to.
+
+.. Cleanup:
+
+    >>> logging.getLogger().removeHandler(handler)
+    >>> logging.getLogger().setLevel(logging.NOTSET)
+   
+    >>> logging.getLogger('test').removeHandler(testhandler)
+    >>> logging.getLogger('test').setLevel(logging.NOTSET)


Property changes on: zc.monitorlogstats/branches/dev/src/zc/monitorlogstats/README.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: zc.monitorlogstats/branches/dev/src/zc/monitorlogstats/__init__.py
===================================================================
--- zc.monitorlogstats/branches/dev/src/zc/monitorlogstats/__init__.py	                        (rev 0)
+++ zc.monitorlogstats/branches/dev/src/zc/monitorlogstats/__init__.py	2008-09-05 22:32:18 UTC (rev 90909)
@@ -0,0 +1,41 @@
+##############################################################################
+#
+# Copyright (c) Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+import logging, datetime
+
+class CountingHandler(logging.Handler):
+
+    def __init__(self, *args, **kw):
+        self.clear()
+        logging.Handler.__init__(self, *args, **kw)
+
+    def emit(self, record):
+        levelno = record.levelno
+        statistics = self._statitistics.get(levelno)
+        if statistics is None:
+            statistics = [levelno, 0, None, None]
+            self._statitistics[levelno] = statistics
+
+        statistics[1] += 1
+        statistics[2] = datetime.datetime.utcnow()
+        statistics[3] = record.getMessage()
+
+    @property
+    def statistics(self):
+        for levelno in sorted(self._statitistics):
+            yield tuple(self._statitistics[levelno])
+
+    def clear(self):
+        self._statitistics = {}
+        self.start_time = datetime.datetime.utcnow()
+    


Property changes on: zc.monitorlogstats/branches/dev/src/zc/monitorlogstats/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zc.monitorlogstats/branches/dev/src/zc/monitorlogstats/component.xml
===================================================================
--- zc.monitorlogstats/branches/dev/src/zc/monitorlogstats/component.xml	                        (rev 0)
+++ zc.monitorlogstats/branches/dev/src/zc/monitorlogstats/component.xml	2008-09-05 22:32:18 UTC (rev 90909)
@@ -0,0 +1,14 @@
+<component>
+  <description>
+     Definition for counting log handler 
+  </description>
+
+  <sectiontype name="counter"
+               datatype="zc.monitorlogstats.zconfig.Counter"
+               implements="ZConfig.logger.handler"
+               extends="ZConfig.logger.base-log-handler">
+    <key name="format"
+         default="%(name)s %(message)s"
+         datatype="ZConfig.components.logger.handlers.log_format"/>
+  </sectiontype>
+</component>


Property changes on: zc.monitorlogstats/branches/dev/src/zc/monitorlogstats/component.xml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: zc.monitorlogstats/branches/dev/src/zc/monitorlogstats/tests.py
===================================================================
--- zc.monitorlogstats/branches/dev/src/zc/monitorlogstats/tests.py	                        (rev 0)
+++ zc.monitorlogstats/branches/dev/src/zc/monitorlogstats/tests.py	2008-09-05 22:32:18 UTC (rev 90909)
@@ -0,0 +1,43 @@
+##############################################################################
+#
+# Copyright (c) Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+import datetime
+import unittest
+from zope.testing import doctest, setupstack
+
+def setUp(test):
+
+    class FauxDateTime:
+
+        now = datetime.datetime(2008, 9, 5, 21, 10, 13)
+
+        @classmethod
+        def utcnow(self):
+            self.now += datetime.timedelta(seconds=1)
+            return self.now
+
+    datetime_orig = datetime.datetime
+    def restore():
+        datetime.datetime = datetime_orig
+
+    setupstack.register(test, restore)
+
+    datetime.datetime = FauxDateTime
+
+def test_suite():
+    return unittest.TestSuite((
+        doctest.DocFileSuite(
+            'README.txt',
+            setUp=setUp, tearDown=setupstack.tearDown),
+        ))
+


Property changes on: zc.monitorlogstats/branches/dev/src/zc/monitorlogstats/tests.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zc.monitorlogstats/branches/dev/src/zc/monitorlogstats/zconfig.py
===================================================================
--- zc.monitorlogstats/branches/dev/src/zc/monitorlogstats/zconfig.py	                        (rev 0)
+++ zc.monitorlogstats/branches/dev/src/zc/monitorlogstats/zconfig.py	2008-09-05 22:32:18 UTC (rev 90909)
@@ -0,0 +1,21 @@
+##############################################################################
+#
+# Copyright (c) Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import ZConfig.components.logger.handlers
+import zc.monitorlogstats
+
+class Counter(ZConfig.components.logger.handlers.HandlerFactory):
+
+    def create_loghandler(self):
+        return zc.monitorlogstats.CountingHandler()


Property changes on: zc.monitorlogstats/branches/dev/src/zc/monitorlogstats/zconfig.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native



More information about the Checkins mailing list